summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c72
-rw-r--r--drivers/block/mg_disk.c4
-rw-r--r--drivers/block/systemace.c2
-rw-r--r--drivers/fpga/ACEX1K.c14
-rw-r--r--drivers/fpga/altera.c6
-rw-r--r--drivers/fpga/cyclon2.c22
-rw-r--r--drivers/fpga/fpga.c8
-rw-r--r--drivers/fpga/spartan2.c24
-rw-r--r--drivers/fpga/spartan3.c24
-rw-r--r--drivers/fpga/virtex2.c20
-rw-r--r--drivers/fpga/xilinx.c4
-rw-r--r--drivers/i2c/omap24xx_i2c.c2
-rw-r--r--drivers/mmc/Makefile4
-rw-r--r--drivers/mmc/atmel_mci.h9
-rw-r--r--drivers/mmc/gen_atmel_mci.c4
-rw-r--r--drivers/mmc/mmc.c123
-rw-r--r--drivers/mmc/mv_sdhci.c21
-rw-r--r--drivers/mmc/s5p_mmc.c2
-rw-r--r--drivers/mmc/sdhci.c433
-rw-r--r--drivers/mmc/sh_mmcif.c608
-rw-r--r--drivers/mmc/sh_mmcif.h238
-rw-r--r--drivers/mmc/tegra2_mmc.c510
-rw-r--r--drivers/mmc/tegra2_mmc.h81
-rw-r--r--drivers/mtd/cfi_flash.c4
-rw-r--r--drivers/mtd/spi/eeprom_m95xxx.c5
-rw-r--r--drivers/mtd/spi/eon.c102
-rw-r--r--drivers/mtd/spi/macronix.c98
-rw-r--r--drivers/mtd/spi/ramtron.c2
-rw-r--r--drivers/mtd/spi/spansion.c98
-rw-r--r--drivers/mtd/spi/spi_flash.c59
-rw-r--r--drivers/mtd/spi/spi_flash_internal.h25
-rw-r--r--drivers/mtd/spi/sst.c26
-rw-r--r--drivers/mtd/spi/stmicro.c124
-rw-r--r--drivers/mtd/spi/winbond.c104
-rw-r--r--drivers/net/4xx_enet.c2
-rw-r--r--drivers/net/designware.c6
-rw-r--r--drivers/net/fec_mxc.c6
-rw-r--r--drivers/net/greth.c2
-rw-r--r--drivers/net/natsemi.c2
-rw-r--r--drivers/net/netarm_eth.c12
-rw-r--r--drivers/net/ns8382x.c2
-rw-r--r--drivers/net/phy/generic_10g.c8
-rw-r--r--drivers/net/smc911x.h2
-rw-r--r--drivers/pci/fsl_pci_init.c2
-rw-r--r--drivers/rtc/mpc5xxx.c2
-rw-r--r--drivers/serial/Makefile3
-rw-r--r--drivers/serial/serial.c28
-rw-r--r--drivers/serial/serial_pxa.c3
-rw-r--r--drivers/serial/serial_s3c24x0.c23
-rw-r--r--drivers/serial/serial_s5p.c27
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/andes_spi.c302
-rw-r--r--drivers/spi/andes_spi.h128
-rw-r--r--drivers/spi/mxc_spi.c2
-rw-r--r--drivers/usb/host/ehci-mxc.c33
-rw-r--r--drivers/video/cfb_console.c1104
56 files changed, 3508 insertions, 1074 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index a3ca2dc..64f52bb 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -78,13 +78,15 @@ static int waiting_for_cmd_completed(volatile u8 *offset,
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
+#ifndef CONFIG_SCSI_AHCI_PLAT
pci_dev_t pdev = probe_ent->dev;
+ u16 tmp16;
+ unsigned short vendor;
+#endif
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
u32 tmp, cap_save;
- u16 tmp16;
int i, j;
volatile u8 *port_mmio;
- unsigned short vendor;
cap_save = readl(mmio + HOST_CAP);
cap_save &= ((1 << 28) | (1 << 17));
@@ -110,6 +112,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
writel(cap_save, mmio + HOST_CAP);
writel_with_flush(0xf, mmio + HOST_PORTS_IMPL);
+#ifndef CONFIG_SCSI_AHCI_PLAT
pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor);
if (vendor == PCI_VENDOR_ID_INTEL) {
@@ -118,7 +121,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
tmp16 |= 0xf;
pci_write_config_word(pdev, 0x92, tmp16);
}
-
+#endif
probe_ent->cap = readl(mmio + HOST_CAP);
probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
@@ -183,22 +186,24 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
tmp = readl(mmio + HOST_CTL);
debug("HOST_CTL 0x%x\n", tmp);
-
+#ifndef CONFIG_SCSI_AHCI_PLAT
pci_read_config_word(pdev, PCI_COMMAND, &tmp16);
tmp |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, tmp16);
-
+#endif
return 0;
}
static void ahci_print_info(struct ahci_probe_ent *probe_ent)
{
+#ifndef CONFIG_SCSI_AHCI_PLAT
pci_dev_t pdev = probe_ent->dev;
+ u16 cc;
+#endif
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
u32 vers, cap, impl, speed;
const char *speed_s;
- u16 cc;
const char *scc_s;
vers = readl(mmio + HOST_VERSION);
@@ -213,6 +218,9 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
else
speed_s = "?";
+#ifdef CONFIG_SCSI_AHCI_PLAT
+ scc_s = "SATA";
+#else
pci_read_config_word(pdev, 0x0a, &cc);
if (cc == 0x0101)
scc_s = "IDE";
@@ -222,7 +230,7 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
scc_s = "RAID";
else
scc_s = "unknown";
-
+#endif
printf("AHCI %02x%02x.%02x%02x "
"%u slots %u ports %s Gbps 0x%x impl %s mode\n",
(vers >> 24) & 0xff,
@@ -249,6 +257,7 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
cap & (1 << 13) ? "part " : "");
}
+#ifndef CONFIG_SCSI_AHCI_PLAT
static int ahci_init_one(pci_dev_t pdev)
{
u16 vendor;
@@ -291,7 +300,7 @@ static int ahci_init_one(pci_dev_t pdev)
err_out:
return rc;
}
-
+#endif
#define MAX_DATA_BYTE_COUNT (4*1024*1024)
@@ -468,7 +477,7 @@ static char *ata_id_strcpy(u16 *target, u16 *src, int len)
{
int i;
for (i = 0; i < len / 2; i++)
- target[i] = le16_to_cpu(src[i]);
+ target[i] = swab16(src[i]);
return (char *)target;
}
@@ -667,7 +676,9 @@ void scsi_low_level_init(int busdevfunc)
int i;
u32 linkmap;
+#ifndef CONFIG_SCSI_AHCI_PLAT
ahci_init_one(busdevfunc);
+#endif
linkmap = probe_ent->link_port_map;
@@ -682,6 +693,49 @@ void scsi_low_level_init(int busdevfunc)
}
}
+#ifdef CONFIG_SCSI_AHCI_PLAT
+int ahci_init(u32 base)
+{
+ int i, rc = 0;
+ u32 linkmap;
+
+ memset(ataid, 0, sizeof(ataid));
+
+ probe_ent = malloc(sizeof(struct ahci_probe_ent));
+ memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
+
+ probe_ent->host_flags = ATA_FLAG_SATA
+ | ATA_FLAG_NO_LEGACY
+ | ATA_FLAG_MMIO
+ | ATA_FLAG_PIO_DMA
+ | ATA_FLAG_NO_ATAPI;
+ probe_ent->pio_mask = 0x1f;
+ probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
+
+ probe_ent->mmio_base = base;
+
+ /* initialize adapter */
+ rc = ahci_host_init(probe_ent);
+ if (rc)
+ goto err_out;
+
+ ahci_print_info(probe_ent);
+
+ linkmap = probe_ent->link_port_map;
+
+ for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
+ if (((linkmap >> i) & 0x01)) {
+ if (ahci_port_start((u8) i)) {
+ printf("Can not start port %d\n", i);
+ continue;
+ }
+ ahci_set_feature((u8) i);
+ }
+ }
+err_out:
+ return rc;
+}
+#endif
void scsi_bus_reset(void)
{
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index b74307a..4407006 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -91,7 +91,9 @@ static unsigned int mg_wait (u32 expect, u32 msec)
u32 from, cur, err;
err = MG_ERR_NONE;
+#ifdef CONFIG_SYS_LOW_RES_TIMER
reset_timer();
+#endif
from = get_timer(0);
status = readb(mg_base() + MG_REG_STATUS);
@@ -522,10 +524,12 @@ mg_write_exit:
return err;
}
+#ifdef CONFIG_PARTITIONS
block_dev_desc_t *mg_disk_get_dev(int dev)
{
return ((block_dev_desc_t *) & mg_disk_dev);
}
+#endif
/* must override this function */
struct mg_drv_data * __attribute__((weak)) mg_get_drv_data (void)
diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c
index e8dff0a..58402b9 100644
--- a/drivers/block/systemace.c
+++ b/drivers/block/systemace.c
@@ -104,6 +104,7 @@ static void release_cf_lock(void)
ace_writew((val & 0xffff), 0x18);
}
+#ifdef CONFIG_PARTITIONS
block_dev_desc_t *systemace_get_dev(int dev)
{
/* The first time through this, the systemace_dev object is
@@ -128,6 +129,7 @@ block_dev_desc_t *systemace_get_dev(int dev)
return &systemace_dev;
}
+#endif
/*
* This function is called (by dereferencing the block_read pointer in
diff --git a/drivers/fpga/ACEX1K.c b/drivers/fpga/ACEX1K.c
index 06b4247..4703fc1 100644
--- a/drivers/fpga/ACEX1K.c
+++ b/drivers/fpga/ACEX1K.c
@@ -48,13 +48,13 @@
#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */
#endif
-static int ACEX1K_ps_load( Altera_desc *desc, void *buf, size_t bsize );
-static int ACEX1K_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
-/* static int ACEX1K_ps_info( Altera_desc *desc ); */
+static int ACEX1K_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
+static int ACEX1K_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
+/* static int ACEX1K_ps_info(Altera_desc *desc); */
/* ------------------------------------------------------------------------- */
/* ACEX1K Generic Implementation */
-int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize)
+int ACEX1K_load(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -74,7 +74,7 @@ int ACEX1K_load (Altera_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int ACEX1K_dump (Altera_desc * desc, void *buf, size_t bsize)
+int ACEX1K_dump(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -103,7 +103,7 @@ int ACEX1K_info( Altera_desc *desc )
/* ------------------------------------------------------------------------- */
/* ACEX1K Passive Serial Generic Implementation */
-static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize)
+static int ACEX1K_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns;
@@ -256,7 +256,7 @@ static int ACEX1K_ps_load (Altera_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int ACEX1K_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
+static int ACEX1K_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
{
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index 650f2ec..f087d01 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -45,7 +45,7 @@
static int altera_validate (Altera_desc * desc, const char *fn);
/* ------------------------------------------------------------------------- */
-int altera_load( Altera_desc *desc, void *buf, size_t bsize )
+int altera_load(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume a failure */
@@ -60,7 +60,7 @@ int altera_load( Altera_desc *desc, void *buf, size_t bsize )
__FUNCTION__);
ret_val = ACEX1K_load (desc, buf, bsize);
#elif defined(CONFIG_FPGA_CYCLON2)
- PRINTF ("%s: Launching the CYCLON II Loader...\n",
+ PRINTF ("%s: Launching the CYCLONE II Loader...\n",
__FUNCTION__);
ret_val = CYC2_load (desc, buf, bsize);
#else
@@ -85,7 +85,7 @@ int altera_load( Altera_desc *desc, void *buf, size_t bsize )
return ret_val;
}
-int altera_dump( Altera_desc *desc, void *buf, size_t bsize )
+int altera_dump(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume a failure */
diff --git a/drivers/fpga/cyclon2.c b/drivers/fpga/cyclon2.c
index 4622b4e..26494a3 100644
--- a/drivers/fpga/cyclon2.c
+++ b/drivers/fpga/cyclon2.c
@@ -47,13 +47,13 @@
#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */
#endif
-static int CYC2_ps_load( Altera_desc *desc, void *buf, size_t bsize );
-static int CYC2_ps_dump( Altera_desc *desc, void *buf, size_t bsize );
+static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
+static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
/* static int CYC2_ps_info( Altera_desc *desc ); */
/* ------------------------------------------------------------------------- */
/* CYCLON2 Generic Implementation */
-int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
+int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -63,6 +63,16 @@ int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
ret_val = CYC2_ps_load (desc, buf, bsize);
break;
+ case fast_passive_parallel:
+ /* Fast Passive Parallel (FPP) and PS only differ in what is
+ * done in the write() callback. Use the existing PS load
+ * function for FPP, too.
+ */
+ PRINTF ("%s: Launching Fast Passive Parallel Loader\n",
+ __FUNCTION__);
+ ret_val = CYC2_ps_load(desc, buf, bsize);
+ break;
+
/* Add new interface types here */
default:
@@ -73,7 +83,7 @@ int CYC2_load (Altera_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int CYC2_dump (Altera_desc * desc, void *buf, size_t bsize)
+int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -100,7 +110,7 @@ int CYC2_info( Altera_desc *desc )
/* ------------------------------------------------------------------------- */
/* CYCLON2 Passive Serial Generic Implementation */
-static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
+static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
@@ -200,7 +210,7 @@ static int CYC2_ps_load (Altera_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int CYC2_ps_dump (Altera_desc * desc, void *buf, size_t bsize)
+static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
{
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index a669039..26d2443 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -52,7 +52,7 @@ static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
/* Local static functions */
static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum );
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf,
+static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate(int devnum, const void *buf,
size_t bsize, char *fn );
static int fpga_dev_info( int devnum );
@@ -94,7 +94,7 @@ static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_ge
/* fpga_validate
* generic parameter checking code
*/
-static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf,
+static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate(int devnum, const void *buf,
size_t bsize, char *fn )
{
fpga_desc * desc = fpga_get_desc( devnum );
@@ -212,7 +212,7 @@ int fpga_add( fpga_type devtype, void *desc )
/*
* Generic multiplexing code
*/
-int fpga_load( int devnum, void *buf, size_t bsize )
+int fpga_load(int devnum, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume failure */
fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
@@ -252,7 +252,7 @@ int fpga_load( int devnum, void *buf, size_t bsize )
/* fpga_dump
* generic multiplexing code
*/
-int fpga_dump( int devnum, void *buf, size_t bsize )
+int fpga_dump(int devnum, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume failure */
fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c
index cd16a9c..4bc7070 100644
--- a/drivers/fpga/spartan2.c
+++ b/drivers/fpga/spartan2.c
@@ -48,17 +48,17 @@
#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
#endif
-static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize );
-static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize );
-/* static int Spartan2_sp_info( Xilinx_desc *desc ); */
+static int Spartan2_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Spartan2_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+/* static int Spartan2_sp_info(Xilinx_desc *desc ); */
-static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize );
-static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize );
-/* static int Spartan2_ss_info( Xilinx_desc *desc ); */
+static int Spartan2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Spartan2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+/* static int Spartan2_ss_info(Xilinx_desc *desc ); */
/* ------------------------------------------------------------------------- */
/* Spartan-II Generic Implementation */
-int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize)
+int Spartan2_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -81,7 +81,7 @@ int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+int Spartan2_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -113,7 +113,7 @@ int Spartan2_info( Xilinx_desc *desc )
/* ------------------------------------------------------------------------- */
/* Spartan-II Slave Parallel Generic Implementation */
-static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan2_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
@@ -265,7 +265,7 @@ static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan2_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns;
@@ -313,7 +313,7 @@ static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
/* ------------------------------------------------------------------------- */
-static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan2_Slave_Serial_fns *fn = desc->iface_fns;
@@ -456,7 +456,7 @@ static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c
index 1dd6f26..9207391 100644
--- a/drivers/fpga/spartan3.c
+++ b/drivers/fpga/spartan3.c
@@ -53,17 +53,17 @@
#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
#endif
-static int Spartan3_sp_load( Xilinx_desc *desc, void *buf, size_t bsize );
-static int Spartan3_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize );
-/* static int Spartan3_sp_info( Xilinx_desc *desc ); */
+static int Spartan3_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Spartan3_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+/* static int Spartan3_sp_info(Xilinx_desc *desc ); */
-static int Spartan3_ss_load( Xilinx_desc *desc, void *buf, size_t bsize );
-static int Spartan3_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize );
-/* static int Spartan3_ss_info( Xilinx_desc *desc ); */
+static int Spartan3_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Spartan3_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+/* static int Spartan3_ss_info(Xilinx_desc *desc); */
/* ------------------------------------------------------------------------- */
/* Spartan-II Generic Implementation */
-int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize)
+int Spartan3_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -86,7 +86,7 @@ int Spartan3_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int Spartan3_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+int Spartan3_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -118,7 +118,7 @@ int Spartan3_info( Xilinx_desc *desc )
/* ------------------------------------------------------------------------- */
/* Spartan-II Slave Parallel Generic Implementation */
-static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan3_sp_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
@@ -272,7 +272,7 @@ static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan3_sp_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan3_Slave_Parallel_fns *fn = desc->iface_fns;
@@ -320,7 +320,7 @@ static int Spartan3_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize)
/* ------------------------------------------------------------------------- */
-static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan3_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume the worst */
Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns;
@@ -475,7 +475,7 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int Spartan3_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Spartan3_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
/* Readback is only available through the Slave Parallel and */
/* boundary-scan interfaces. */
diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c
index d1b4d15..b26d231 100644
--- a/drivers/fpga/virtex2.c
+++ b/drivers/fpga/virtex2.c
@@ -101,13 +101,13 @@
#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */
#endif
-static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize);
-static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ssm_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Virtex2_ssm_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
-static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize);
-static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize);
+static int Virtex2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize);
+static int Virtex2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
-int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
+int Virtex2_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -129,7 +129,7 @@ int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+int Virtex2_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
@@ -170,7 +170,7 @@ int Virtex2_info (Xilinx_desc * desc)
* INIT_B and DONE lines. If both are high, configuration has
* succeeded. Congratulations!
*/
-static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Virtex2_ssm_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
@@ -369,7 +369,7 @@ static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize)
/*
* Read the FPGA configuration data
*/
-static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Virtex2_ssm_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL;
Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns;
@@ -421,13 +421,13 @@ static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Virtex2_ss_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__);
return FPGA_FAIL;
}
-static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+static int Virtex2_ss_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__);
return FPGA_FAIL;
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 08dfdec..4072cb4 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -48,7 +48,7 @@ static int xilinx_validate (Xilinx_desc * desc, char *fn);
/* ------------------------------------------------------------------------- */
-int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize)
+int xilinx_load(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume a failure */
@@ -95,7 +95,7 @@ int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize)
return ret_val;
}
-int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize)
+int xilinx_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
{
int ret_val = FPGA_FAIL; /* assume a failure */
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 71251d8..966ffc4 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -399,7 +399,7 @@ static void wait_for_bb (void)
int timeout = I2C_TIMEOUT;
u16 stat;
- writew(0xFFFF, &i2c_base->stat); /* clear current interruts...*/
+ writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/
while ((stat = readw (&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
writew (stat, &i2c_base->stat);
udelay(1000);
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a8fe17a..3968c14 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -33,11 +33,15 @@ COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
COBJS-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
+COBJS-$(CONFIG_MV_SDHCI) += mv_sdhci.o
COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
+COBJS-$(CONFIG_SDHCI) += sdhci.o
+COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
+COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/atmel_mci.h b/drivers/mmc/atmel_mci.h
index 90ab6a8..3095d22 100644
--- a/drivers/mmc/atmel_mci.h
+++ b/drivers/mmc/atmel_mci.h
@@ -36,7 +36,7 @@ typedef struct atmel_mci {
u32 sdcr; /* 0x0c */
u32 argr; /* 0x10 */
u32 cmdr; /* 0x14 */
- u32 _18; /* 0x18 */
+ u32 blkr; /* 0x18 */
u32 _1c; /* 0x1c */
u32 rspr; /* 0x20 */
u32 rspr1; /* 0x24 */
@@ -67,6 +67,7 @@ typedef struct atmel_mci {
#define MMCI_SDCR 0x000c
#define MMCI_ARGR 0x0010
#define MMCI_CMDR 0x0014
+#define MMCI_BLKR 0x0018
#define MMCI_RSPR 0x0020
#define MMCI_RSPR1 0x0024
#define MMCI_RSPR2 0x0028
@@ -140,6 +141,12 @@ typedef struct atmel_mci {
#define MMCI_TRTYP_OFFSET 19
#define MMCI_TRTYP_SIZE 2
+/* Bitfields in BLKR */
+#define MMCI_BCNT_OFFSET 0
+#define MMCI_BCNT_SIZE 16
+#define MMCI_BLKLEN_OFFSET 16
+#define MMCI_BLKLEN_SIZE 16
+
/* Bitfields in RSPRx */
#define MMCI_RSP_OFFSET 0
#define MMCI_RSP_SIZE 32
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index f346b24..d217574 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -183,6 +183,10 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Figure out the transfer arguments */
cmdr = mci_encode_cmd(cmd, data, &error_flags);
+ if (data)
+ writel(MMCI_BF(BCNT, data->blocks) |
+ MMCI_BF(BLKLEN, mmc->read_bl_len), &mci->blkr);
+
/* Send the command */
writel(cmd->cmdarg, &mci->argr);
writel(cmdr, &mci->cmdr);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 21aedba..7e703c0 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -174,6 +174,88 @@ struct mmc *find_mmc_device(int dev_num)
return NULL;
}
+static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
+{
+ struct mmc_cmd cmd;
+ ulong end;
+ int err, start_cmd, end_cmd;
+
+ if (mmc->high_capacity)
+ end = start + blkcnt - 1;
+ else {
+ end = (start + blkcnt - 1) * mmc->write_bl_len;
+ start *= mmc->write_bl_len;
+ }
+
+ if (IS_SD(mmc)) {
+ start_cmd = SD_CMD_ERASE_WR_BLK_START;
+ end_cmd = SD_CMD_ERASE_WR_BLK_END;
+ } else {
+ start_cmd = MMC_CMD_ERASE_GROUP_START;
+ end_cmd = MMC_CMD_ERASE_GROUP_END;
+ }
+
+ cmd.cmdidx = start_cmd;
+ cmd.cmdarg = start;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.flags = 0;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err)
+ goto err_out;
+
+ cmd.cmdidx = end_cmd;
+ cmd.cmdarg = end;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err)
+ goto err_out;
+
+ cmd.cmdidx = MMC_CMD_ERASE;
+ cmd.cmdarg = SECURE_ERASE;
+ cmd.resp_type = MMC_RSP_R1b;
+
+ err = mmc_send_cmd(mmc, &cmd, NULL);
+ if (err)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ puts("mmc erase failed\n");
+ return err;
+}
+
+static unsigned long
+mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
+{
+ int err = 0;
+ struct mmc *mmc = find_mmc_device(dev_num);
+ lbaint_t blk = 0, blk_r = 0;
+
+ if (!mmc)
+ return -1;
+
+ if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
+ printf("\n\nCaution! Your devices Erase group is 0x%x\n"
+ "The erase range would be change to 0x%lx~0x%lx\n\n",
+ mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
+ ((start + blkcnt + mmc->erase_grp_size)
+ & ~(mmc->erase_grp_size - 1)) - 1);
+
+ while (blk < blkcnt) {
+ blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ?
+ mmc->erase_grp_size : (blkcnt - blk);
+ err = mmc_erase_t(mmc, start + blk, blk_r);
+ if (err)
+ break;
+
+ blk += blk_r;
+ }
+
+ return blk;
+}
+
static ulong
mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
{
@@ -449,6 +531,10 @@ int mmc_send_op_cond(struct mmc *mmc)
(mmc->voltages &
(cmd.response[0] & OCR_VOLTAGE_MASK)) |
(cmd.response[0] & OCR_ACCESS_MODE));
+
+ if (mmc->host_caps & MMC_MODE_HC)
+ cmd.cmdarg |= OCR_HCS;
+
cmd.flags = 0;
err = mmc_send_cmd(mmc, &cmd, NULL);
@@ -771,7 +857,7 @@ int mmc_startup(struct mmc *mmc)
{
int err;
uint mult, freq;
- u64 cmult, csize;
+ u64 cmult, csize, capacity;
struct mmc_cmd cmd;
char ext_csd[512];
int timeout = 1000;
@@ -911,14 +997,40 @@ int mmc_startup(struct mmc *mmc)
return err;
}
+ /*
+ * For SD, its erase group is always one sector
+ */
+ mmc->erase_grp_size = 1;
mmc->part_config = MMCPART_NOAVAILABLE;
if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
/* check ext_csd version and capacity */
err = mmc_send_ext_csd(mmc, ext_csd);
if (!err & (ext_csd[192] >= 2)) {
- mmc->capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
- ext_csd[214] << 16 | ext_csd[215] << 24;
- mmc->capacity *= 512;
+ /*
+ * According to the JEDEC Standard, the value of
+ * ext_csd's capacity is valid if the value is more
+ * than 2GB
+ */
+ capacity = ext_csd[212] << 0 | ext_csd[213] << 8 |
+ ext_csd[214] << 16 | ext_csd[215] << 24;
+ capacity *= 512;
+ if ((capacity >> 20) > 2 * 1024)
+ mmc->capacity = capacity;
+ }
+
+ /*
+ * Check whether GROUP_DEF is set, if yes, read out
+ * group size from ext_csd directly, or calculate
+ * the group size from the csd value.
+ */
+ if (ext_csd[175])
+ mmc->erase_grp_size = ext_csd[224] * 512 * 1024;
+ else {
+ int erase_gsz, erase_gmul;
+ erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
+ erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
+ mmc->erase_grp_size = (erase_gsz + 1)
+ * (erase_gmul + 1);
}
/* store the partition info of emmc */
@@ -1044,6 +1156,7 @@ int mmc_register(struct mmc *mmc)
mmc->block_dev.removable = 1;
mmc->block_dev.block_read = mmc_bread;
mmc->block_dev.block_write = mmc_bwrite;
+ mmc->block_dev.block_erase = mmc_berase;
if (!mmc->b_max)
mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
@@ -1054,12 +1167,14 @@ int mmc_register(struct mmc *mmc)
return 0;
}
+#ifdef CONFIG_PARTITIONS
block_dev_desc_t *mmc_get_dev(int dev)
{
struct mmc *mmc = find_mmc_device(dev);
return mmc ? &mmc->block_dev : NULL;
}
+#endif
int mmc_init(struct mmc *mmc)
{
diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c
new file mode 100644
index 0000000..9e59951
--- /dev/null
+++ b/drivers/mmc/mv_sdhci.c
@@ -0,0 +1,21 @@
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+static char *MVSDH_NAME = "mv_sdh";
+int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
+{
+ struct sdhci_host *host = NULL;
+ host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
+ if (!host) {
+ printf("sdh_host malloc fail!\n");
+ return 1;
+ }
+
+ host->name = MVSDH_NAME;
+ host->ioaddr = (void *)regbase;
+ host->quirks = quirks;
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
+ add_sdhci(host, max_clk, min_clk);
+ return 0;
+}
diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c
index 280738f..f136813 100644
--- a/drivers/mmc/s5p_mmc.c
+++ b/drivers/mmc/s5p_mmc.c
@@ -462,7 +462,7 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
mmc->host_caps = MMC_MODE_8BIT;
else
mmc->host_caps = MMC_MODE_4BIT;
- mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
mmc->f_min = 400000;
mmc->f_max = 52000000;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
new file mode 100644
index 0000000..9ebd33d
--- /dev/null
+++ b/drivers/mmc/sdhci.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2011, Marvell Semiconductor Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <sdhci.h>
+
+void *aligned_buffer;
+
+static void sdhci_reset(struct sdhci_host *host, u8 mask)
+{
+ unsigned long timeout;
+
+ /* Wait max 100 ms */
+ timeout = 100;
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
+ if (timeout == 0) {
+ printf("Reset 0x%x never completed.\n", (int)mask);
+ return;
+ }
+ timeout--;
+ udelay(1000);
+ }
+}
+
+static void sdhci_cmd_done(struct sdhci_host *host, struct mmc_cmd *cmd)
+{
+ int i;
+ if (cmd->resp_type & MMC_RSP_136) {
+ /* CRC is stripped so we need to do some shifting. */
+ for (i = 0; i < 4; i++) {
+ cmd->response[i] = sdhci_readl(host,
+ SDHCI_RESPONSE + (3-i)*4) << 8;
+ if (i != 3)
+ cmd->response[i] |= sdhci_readb(host,
+ SDHCI_RESPONSE + (3-i)*4-1);
+ }
+ } else {
+ cmd->response[0] = sdhci_readl(host, SDHCI_RESPONSE);
+ }
+}
+
+static void sdhci_transfer_pio(struct sdhci_host *host, struct mmc_data *data)
+{
+ int i;
+ char *offs;
+ for (i = 0; i < data->blocksize; i += 4) {
+ offs = data->dest + i;
+ if (data->flags == MMC_DATA_READ)
+ *(u32 *)offs = sdhci_readl(host, SDHCI_BUFFER);
+ else
+ sdhci_writel(host, *(u32 *)offs, SDHCI_BUFFER);
+ }
+}
+
+static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
+ unsigned int start_addr)
+{
+ unsigned int stat, rdy, mask, block = 0;
+
+ rdy = SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL;
+ mask = SDHCI_DATA_AVAILABLE | SDHCI_SPACE_AVAILABLE;
+ do {
+ stat = sdhci_readl(host, SDHCI_INT_STATUS);
+ if (stat & SDHCI_INT_ERROR) {
+ printf("Error detected in status(0x%X)!\n", stat);
+ return -1;
+ }
+ if (stat & rdy) {
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask))
+ continue;
+ sdhci_writel(host, rdy, SDHCI_INT_STATUS);
+ sdhci_transfer_pio(host, data);
+ data->dest += data->blocksize;
+ if (++block >= data->blocks)
+ break;
+ }
+#ifdef CONFIG_MMC_SDMA
+ if (stat & SDHCI_INT_DMA_END) {
+ sdhci_writel(host, SDHCI_INT_DMA_END, SDHCI_INT_STATUS);
+ start_addr &= SDHCI_DEFAULT_BOUNDARY_SIZE - 1;
+ start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
+ sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
+ }
+#endif
+ } while (!(stat & SDHCI_INT_DATA_END));
+ return 0;
+}
+
+int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+ unsigned int stat = 0;
+ int ret = 0;
+ int trans_bytes = 0, is_aligned = 1;
+ u32 mask, flags, mode;
+ unsigned int timeout, start_addr = 0;
+
+ /* Wait max 10 ms */
+ timeout = 10;
+
+ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
+ mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
+
+ /* We shouldn't wait for data inihibit for stop commands, even
+ though they might use busy signaling */
+ if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+ mask &= ~SDHCI_DATA_INHIBIT;
+
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+ if (timeout == 0) {
+ printf("Controller never released inhibit bit(s).\n");
+ return COMM_ERR;
+ }
+ timeout--;
+ udelay(1000);
+ }
+
+ mask = SDHCI_INT_RESPONSE;
+ if (!(cmd->resp_type & MMC_RSP_PRESENT))
+ flags = SDHCI_CMD_RESP_NONE;
+ else if (cmd->resp_type & MMC_RSP_136)
+ flags = SDHCI_CMD_RESP_LONG;
+ else if (cmd->resp_type & MMC_RSP_BUSY) {
+ flags = SDHCI_CMD_RESP_SHORT_BUSY;
+ mask |= SDHCI_INT_DATA_END;
+ } else
+ flags = SDHCI_CMD_RESP_SHORT;
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ flags |= SDHCI_CMD_CRC;
+ if (cmd->resp_type & MMC_RSP_OPCODE)
+ flags |= SDHCI_CMD_INDEX;
+ if (data)
+ flags |= SDHCI_CMD_DATA;
+
+ /*Set Transfer mode regarding to data flag*/
+ if (data != 0) {
+ sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
+ mode = SDHCI_TRNS_BLK_CNT_EN;
+ trans_bytes = data->blocks * data->blocksize;
+ if (data->blocks > 1)
+ mode |= SDHCI_TRNS_MULTI;
+
+ if (data->flags == MMC_DATA_READ)
+ mode |= SDHCI_TRNS_READ;
+
+#ifdef CONFIG_MMC_SDMA
+ if (data->flags == MMC_DATA_READ)
+ start_addr = (unsigned int)data->dest;
+ else
+ start_addr = (unsigned int)data->src;
+ if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
+ (start_addr & 0x7) != 0x0) {
+ is_aligned = 0;
+ start_addr = (unsigned int)aligned_buffer;
+ if (data->flags != MMC_DATA_READ)
+ memcpy(aligned_buffer, data->src, trans_bytes);
+ }
+
+ sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
+ mode |= SDHCI_TRNS_DMA;
+#endif
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+ data->blocksize),
+ SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+ }
+
+ sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
+#ifdef CONFIG_MMC_SDMA
+ flush_cache(0, ~0);
+#endif
+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
+ do {
+ stat = sdhci_readl(host, SDHCI_INT_STATUS);
+ if (stat & SDHCI_INT_ERROR)
+ break;
+ } while ((stat & mask) != mask);
+
+ if ((stat & (SDHCI_INT_ERROR | mask)) == mask) {
+ sdhci_cmd_done(host, cmd);
+ sdhci_writel(host, mask, SDHCI_INT_STATUS);
+ } else
+ ret = -1;
+
+ if (!ret && data)
+ ret = sdhci_transfer_data(host, data, start_addr);
+
+ stat = sdhci_readl(host, SDHCI_INT_STATUS);
+ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
+ if (!ret) {
+ if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
+ !is_aligned && (data->flags == MMC_DATA_READ))
+ memcpy(data->dest, aligned_buffer, trans_bytes);
+ return 0;
+ }
+
+ sdhci_reset(host, SDHCI_RESET_CMD);
+ sdhci_reset(host, SDHCI_RESET_DATA);
+ if (stat & SDHCI_INT_TIMEOUT)
+ return TIMEOUT;
+ else
+ return COMM_ERR;
+}
+
+static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
+{
+ struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+ unsigned int div, clk, timeout;
+
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+ if (clock == 0)
+ return 0;
+
+ if (host->version >= SDHCI_SPEC_300) {
+ /* Version 3.00 divisors must be a multiple of 2. */
+ if (mmc->f_max <= clock)
+ div = 1;
+ else {
+ for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
+ if ((mmc->f_max / div) <= clock)
+ break;
+ }
+ }
+ } else {
+ /* Version 2.00 divisors must be a power of 2. */
+ for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
+ if ((mmc->f_max / div) <= clock)
+ break;
+ }
+ }
+ div >>= 1;
+
+ clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
+ clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
+ << SDHCI_DIVIDER_HI_SHIFT;
+ clk |= SDHCI_CLOCK_INT_EN;
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+ /* Wait max 20 ms */
+ timeout = 20;
+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+ & SDHCI_CLOCK_INT_STABLE)) {
+ if (timeout == 0) {
+ printf("Internal clock never stabilised.\n");
+ return -1;
+ }
+ timeout--;
+ udelay(1000);
+ }
+
+ clk |= SDHCI_CLOCK_CARD_EN;
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+ return 0;
+}
+
+static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
+{
+ u8 pwr = 0;
+
+ if (power != (unsigned short)-1) {
+ switch (1 << power) {
+ case MMC_VDD_165_195:
+ pwr = SDHCI_POWER_180;
+ break;
+ case MMC_VDD_29_30:
+ case MMC_VDD_30_31:
+ pwr = SDHCI_POWER_300;
+ break;
+ case MMC_VDD_32_33:
+ case MMC_VDD_33_34:
+ pwr = SDHCI_POWER_330;
+ break;
+ }
+ }
+
+ if (pwr == 0) {
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+ return;
+ }
+
+ pwr |= SDHCI_POWER_ON;
+
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+}
+
+void sdhci_set_ios(struct mmc *mmc)
+{
+ u32 ctrl;
+ struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+
+ if (mmc->clock != host->clock)
+ sdhci_set_clock(mmc, mmc->clock);
+
+ /* Set bus width */
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+ if (mmc->bus_width == 8) {
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl |= SDHCI_CTRL_8BITBUS;
+ } else {
+ if (host->version >= SDHCI_SPEC_300)
+ ctrl &= ~SDHCI_CTRL_8BITBUS;
+ if (mmc->bus_width == 4)
+ ctrl |= SDHCI_CTRL_4BITBUS;
+ else
+ ctrl &= ~SDHCI_CTRL_4BITBUS;
+ }
+
+ if (mmc->clock > 26000000)
+ ctrl |= SDHCI_CTRL_HISPD;
+ else
+ ctrl &= ~SDHCI_CTRL_HISPD;
+
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+}
+
+int sdhci_init(struct mmc *mmc)
+{
+ struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+
+ if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {
+ aligned_buffer = memalign(8, 512*1024);
+ if (!aligned_buffer) {
+ printf("Aligned buffer alloc failed!!!");
+ return -1;
+ }
+ }
+
+ /* Eable all state */
+ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE);
+
+ sdhci_set_power(host, fls(mmc->voltages) - 1);
+
+ return 0;
+}
+
+int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
+{
+ struct mmc *mmc;
+ unsigned int caps;
+
+ mmc = malloc(sizeof(struct mmc));
+ if (!mmc) {
+ printf("mmc malloc fail!\n");
+ return -1;
+ }
+
+ mmc->priv = host;
+
+ sprintf(mmc->name, "%s", host->name);
+ mmc->send_cmd = sdhci_send_command;
+ mmc->set_ios = sdhci_set_ios;
+ mmc->init = sdhci_init;
+
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+#ifdef CONFIG_MMC_SDMA
+ if (!(caps & SDHCI_CAN_DO_SDMA)) {
+ printf("Your controller don't support sdma!!\n");
+ return -1;
+ }
+#endif
+
+ if (max_clk)
+ mmc->f_max = max_clk;
+ else {
+ if (host->version >= SDHCI_SPEC_300)
+ mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
+ >> SDHCI_CLOCK_BASE_SHIFT;
+ else
+ mmc->f_max = (caps & SDHCI_CLOCK_BASE_MASK)
+ >> SDHCI_CLOCK_BASE_SHIFT;
+ mmc->f_max *= 1000000;
+ }
+ if (mmc->f_max == 0) {
+ printf("Hardware doesn't specify base clock frequency\n");
+ return -1;
+ }
+ if (min_clk)
+ mmc->f_min = min_clk;
+ else {
+ if (host->version >= SDHCI_SPEC_300)
+ mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300;
+ else
+ mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200;
+ }
+
+ mmc->voltages = 0;
+ if (caps & SDHCI_CAN_VDD_330)
+ mmc->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+ if (caps & SDHCI_CAN_VDD_300)
+ mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+ if (caps & SDHCI_CAN_VDD_180)
+ mmc->voltages |= MMC_VDD_165_195;
+ mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+ if (caps & SDHCI_CAN_DO_8BIT)
+ mmc->host_caps |= MMC_MODE_8BIT;
+
+ sdhci_reset(host, SDHCI_RESET_ALL);
+ mmc_register(mmc);
+
+ return 0;
+}
diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c
new file mode 100644
index 0000000..567e2cb
--- /dev/null
+++ b/drivers/mmc/sh_mmcif.c
@@ -0,0 +1,608 @@
+/*
+ * MMCIF driver.
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <mmc.h>
+#include <malloc.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include "sh_mmcif.h"
+
+#define DRIVER_NAME "sh_mmcif"
+
+static void *mmc_priv(struct mmc *mmc)
+{
+ return (void *)mmc->priv;
+}
+
+static int sh_mmcif_intr(void *dev_id)
+{
+ struct sh_mmcif_host *host = dev_id;
+ u32 state = 0;
+
+ state = sh_mmcif_read(&host->regs->ce_int);
+ state &= sh_mmcif_read(&host->regs->ce_int_mask);
+
+ if (state & INT_RBSYE) {
+ sh_mmcif_write(~(INT_RBSYE | INT_CRSPE), &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MRBSYE, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_CRSPE) {
+ sh_mmcif_write(~INT_CRSPE, &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MCRSPE, &host->regs->ce_int_mask);
+ /* one more interrupt (INT_RBSYE) */
+ if (sh_mmcif_read(&host->regs->ce_cmd_set) & CMD_SET_RBSY)
+ return -EAGAIN;
+ goto end;
+ } else if (state & INT_BUFREN) {
+ sh_mmcif_write(~INT_BUFREN, &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MBUFREN, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_BUFWEN) {
+ sh_mmcif_write(~INT_BUFWEN, &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MBUFWEN, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_CMD12DRE) {
+ sh_mmcif_write(~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE |
+ INT_BUFRE), &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MCMD12DRE, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_BUFRE) {
+ sh_mmcif_write(~INT_BUFRE, &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MBUFRE, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_DTRANE) {
+ sh_mmcif_write(~INT_DTRANE, &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MDTRANE, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_CMD12RBE) {
+ sh_mmcif_write(~(INT_CMD12RBE | INT_CMD12CRE),
+ &host->regs->ce_int);
+ sh_mmcif_bitclr(MASK_MCMD12RBE, &host->regs->ce_int_mask);
+ goto end;
+ } else if (state & INT_ERR_STS) {
+ /* err interrupts */
+ sh_mmcif_write(~state, &host->regs->ce_int);
+ sh_mmcif_bitclr(state, &host->regs->ce_int_mask);
+ goto err;
+ } else
+ return -EAGAIN;
+
+err:
+ host->sd_error = 1;
+ debug("%s: int err state = %08x\n", DRIVER_NAME, state);
+end:
+ host->wait_int = 1;
+ return 0;
+}
+
+static int mmcif_wait_interrupt_flag(struct sh_mmcif_host *host)
+{
+ int timeout = 10000000;
+
+ while (1) {
+ timeout--;
+ if (timeout < 0) {
+ printf("timeout\n");
+ return 0;
+ }
+
+ if (!sh_mmcif_intr(host))
+ break;
+
+ udelay(1); /* 1 usec */
+ }
+
+ return 1; /* Return value: NOT 0 = complete waiting */
+}
+
+static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
+{
+ int i;
+
+ sh_mmcif_bitclr(CLK_ENABLE, &host->regs->ce_clk_ctrl);
+ sh_mmcif_bitclr(CLK_CLEAR, &host->regs->ce_clk_ctrl);
+
+ if (!clk)
+ return;
+ if (clk == CLKDEV_EMMC_DATA) {
+ sh_mmcif_bitset(CLK_PCLK, &host->regs->ce_clk_ctrl);
+ } else {
+ for (i = 1; (unsigned int)host->clk / (1 << i) >= clk; i++)
+ ;
+ sh_mmcif_bitset((i - 1) << 16, &host->regs->ce_clk_ctrl);
+ }
+ sh_mmcif_bitset(CLK_ENABLE, &host->regs->ce_clk_ctrl);
+}
+
+static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
+{
+ u32 tmp;
+
+ tmp = sh_mmcif_read(&host->regs->ce_clk_ctrl) & (CLK_ENABLE |
+ CLK_CLEAR);
+
+ sh_mmcif_write(SOFT_RST_ON, &host->regs->ce_version);
+ sh_mmcif_write(SOFT_RST_OFF, &host->regs->ce_version);
+ sh_mmcif_bitset(tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29,
+ &host->regs->ce_clk_ctrl);
+ /* byte swap on */
+ sh_mmcif_bitset(BUF_ACC_ATYP, &host->regs->ce_buf_acc);
+}
+
+static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
+{
+ u32 state1, state2;
+ int ret, timeout = 10000000;
+
+ host->sd_error = 0;
+ host->wait_int = 0;
+
+ state1 = sh_mmcif_read(&host->regs->ce_host_sts1);
+ state2 = sh_mmcif_read(&host->regs->ce_host_sts2);
+ debug("%s: ERR HOST_STS1 = %08x\n", \
+ DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts1));
+ debug("%s: ERR HOST_STS2 = %08x\n", \
+ DRIVER_NAME, sh_mmcif_read(&host->regs->ce_host_sts2));
+
+ if (state1 & STS1_CMDSEQ) {
+ debug("%s: Forced end of command sequence\n", DRIVER_NAME);
+ sh_mmcif_bitset(CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
+ sh_mmcif_bitset(~CMD_CTRL_BREAK, &host->regs->ce_cmd_ctrl);
+ while (1) {
+ timeout--;
+ if (timeout < 0) {
+ printf(DRIVER_NAME": Forceed end of " \
+ "command sequence timeout err\n");
+ return -EILSEQ;
+ }
+ if (!(sh_mmcif_read(&host->regs->ce_host_sts1)
+ & STS1_CMDSEQ))
+ break;
+ }
+ sh_mmcif_sync_reset(host);
+ return -EILSEQ;
+ }
+
+ if (state2 & STS2_CRC_ERR)
+ ret = -EILSEQ;
+ else if (state2 & STS2_TIMEOUT_ERR)
+ ret = TIMEOUT;
+ else
+ ret = -EILSEQ;
+ return ret;
+}
+
+static int sh_mmcif_single_read(struct sh_mmcif_host *host,
+ struct mmc_data *data)
+{
+ long time;
+ u32 blocksize, i;
+ unsigned long *p = (unsigned long *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ printf("%s: The data pointer is unaligned.", __func__);
+ return -EIO;
+ }
+
+ host->wait_int = 0;
+
+ /* buf read enable */
+ sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = (BLOCK_SIZE_MASK &
+ sh_mmcif_read(&host->regs->ce_block_set)) + 3;
+ for (i = 0; i < blocksize / 4; i++)
+ *p++ = sh_mmcif_read(&host->regs->ce_data);
+
+ /* buffer read end */
+ sh_mmcif_bitset(MASK_MBUFRE, &host->regs->ce_int_mask);
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ return 0;
+}
+
+static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
+ struct mmc_data *data)
+{
+ long time;
+ u32 blocksize, i, j;
+ unsigned long *p = (unsigned long *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ printf("%s: The data pointer is unaligned.", __func__);
+ return -EIO;
+ }
+
+ host->wait_int = 0;
+ blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
+ for (j = 0; j < data->blocks; j++) {
+ sh_mmcif_bitset(MASK_MBUFREN, &host->regs->ce_int_mask);
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ for (i = 0; i < blocksize / 4; i++)
+ *p++ = sh_mmcif_read(&host->regs->ce_data);
+
+ WATCHDOG_RESET();
+ }
+ return 0;
+}
+
+static int sh_mmcif_single_write(struct sh_mmcif_host *host,
+ struct mmc_data *data)
+{
+ long time;
+ u32 blocksize, i;
+ const unsigned long *p = (unsigned long *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ printf("%s: The data pointer is unaligned.", __func__);
+ return -EIO;
+ }
+
+ host->wait_int = 0;
+ sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);
+
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ blocksize = (BLOCK_SIZE_MASK &
+ sh_mmcif_read(&host->regs->ce_block_set)) + 3;
+ for (i = 0; i < blocksize / 4; i++)
+ sh_mmcif_write(*p++, &host->regs->ce_data);
+
+ /* buffer write end */
+ sh_mmcif_bitset(MASK_MDTRANE, &host->regs->ce_int_mask);
+
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ return 0;
+}
+
+static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
+ struct mmc_data *data)
+{
+ long time;
+ u32 i, j, blocksize;
+ const unsigned long *p = (unsigned long *)data->dest;
+
+ if ((unsigned long)p & 0x00000001) {
+ printf("%s: The data pointer is unaligned.", __func__);
+ return -EIO;
+ }
+
+ host->wait_int = 0;
+ blocksize = BLOCK_SIZE_MASK & sh_mmcif_read(&host->regs->ce_block_set);
+ for (j = 0; j < data->blocks; j++) {
+ sh_mmcif_bitset(MASK_MBUFWEN, &host->regs->ce_int_mask);
+
+ time = mmcif_wait_interrupt_flag(host);
+
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ host->wait_int = 0;
+ for (i = 0; i < blocksize / 4; i++)
+ sh_mmcif_write(*p++, &host->regs->ce_data);
+
+ WATCHDOG_RESET();
+ }
+ return 0;
+}
+
+static void sh_mmcif_get_response(struct sh_mmcif_host *host,
+ struct mmc_cmd *cmd)
+{
+ if (cmd->resp_type & MMC_RSP_136) {
+ cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp3);
+ cmd->response[1] = sh_mmcif_read(&host->regs->ce_resp2);
+ cmd->response[2] = sh_mmcif_read(&host->regs->ce_resp1);
+ cmd->response[3] = sh_mmcif_read(&host->regs->ce_resp0);
+ debug(" RESP %08x, %08x, %08x, %08x\n", cmd->response[0],
+ cmd->response[1], cmd->response[2], cmd->response[3]);
+ } else {
+ cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp0);
+ }
+}
+
+static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
+ struct mmc_cmd *cmd)
+{
+ cmd->response[0] = sh_mmcif_read(&host->regs->ce_resp_cmd12);
+}
+
+static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ struct mmc_data *data, struct mmc_cmd *cmd)
+{
+ u32 tmp = 0;
+ u32 opc = cmd->cmdidx;
+
+ /* Response Type check */
+ switch (cmd->resp_type) {
+ case MMC_RSP_NONE:
+ tmp |= CMD_SET_RTYP_NO;
+ break;
+ case MMC_RSP_R1:
+ case MMC_RSP_R1b:
+ case MMC_RSP_R3:
+ tmp |= CMD_SET_RTYP_6B;
+ break;
+ case MMC_RSP_R2:
+ tmp |= CMD_SET_RTYP_17B;
+ break;
+ default:
+ printf(DRIVER_NAME": Not support type response.\n");
+ break;
+ }
+
+ /* RBSY */
+ if (opc == MMC_CMD_SWITCH)
+ tmp |= CMD_SET_RBSY;
+
+ /* WDAT / DATW */
+ if (host->data) {
+ tmp |= CMD_SET_WDAT;
+ switch (host->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ tmp |= CMD_SET_DATW_1;
+ break;
+ case MMC_BUS_WIDTH_4:
+ tmp |= CMD_SET_DATW_4;
+ break;
+ case MMC_BUS_WIDTH_8:
+ tmp |= CMD_SET_DATW_8;
+ break;
+ default:
+ printf(DRIVER_NAME": Not support bus width.\n");
+ break;
+ }
+ }
+ /* DWEN */
+ if (opc == MMC_CMD_WRITE_SINGLE_BLOCK ||
+ opc == MMC_CMD_WRITE_MULTIPLE_BLOCK)
+ tmp |= CMD_SET_DWEN;
+ /* CMLTE/CMD12EN */
+ if (opc == MMC_CMD_READ_MULTIPLE_BLOCK ||
+ opc == MMC_CMD_WRITE_MULTIPLE_BLOCK) {
+ tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
+ sh_mmcif_bitset(data->blocks << 16, &host->regs->ce_block_set);
+ }
+ /* RIDXC[1:0] check bits */
+ if (opc == MMC_CMD_SEND_OP_COND || opc == MMC_CMD_ALL_SEND_CID ||
+ opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
+ tmp |= CMD_SET_RIDXC_BITS;
+ /* RCRC7C[1:0] check bits */
+ if (opc == MMC_CMD_SEND_OP_COND)
+ tmp |= CMD_SET_CRC7C_BITS;
+ /* RCRC7C[1:0] internal CRC7 */
+ if (opc == MMC_CMD_ALL_SEND_CID ||
+ opc == MMC_CMD_SEND_CSD || opc == MMC_CMD_SEND_CID)
+ tmp |= CMD_SET_CRC7C_INTERNAL;
+
+ return opc = ((opc << 24) | tmp);
+}
+
+static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host,
+ struct mmc_data *data, u16 opc)
+{
+ u32 ret;
+
+ switch (opc) {
+ case MMC_CMD_READ_MULTIPLE_BLOCK:
+ ret = sh_mmcif_multi_read(host, data);
+ break;
+ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+ ret = sh_mmcif_multi_write(host, data);
+ break;
+ case MMC_CMD_WRITE_SINGLE_BLOCK:
+ ret = sh_mmcif_single_write(host, data);
+ break;
+ case MMC_CMD_READ_SINGLE_BLOCK:
+ case MMC_CMD_SEND_EXT_CSD:
+ ret = sh_mmcif_single_read(host, data);
+ break;
+ default:
+ printf(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ struct mmc_data *data, struct mmc_cmd *cmd)
+{
+ long time;
+ int ret = 0, mask = 0;
+ u32 opc = cmd->cmdidx;
+
+ if (opc == MMC_CMD_STOP_TRANSMISSION) {
+ /* MMCIF sends the STOP command automatically */
+ if (host->last_cmd == MMC_CMD_READ_MULTIPLE_BLOCK)
+ sh_mmcif_bitset(MASK_MCMD12DRE,
+ &host->regs->ce_int_mask);
+ else
+ sh_mmcif_bitset(MASK_MCMD12RBE,
+ &host->regs->ce_int_mask);
+
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0 || host->sd_error != 0)
+ return sh_mmcif_error_manage(host);
+
+ sh_mmcif_get_cmd12response(host, cmd);
+ return 0;
+ }
+ if (opc == MMC_CMD_SWITCH)
+ mask = MASK_MRBSYE;
+ else
+ mask = MASK_MCRSPE;
+
+ mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
+ MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
+ MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
+ MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
+
+ if (host->data) {
+ sh_mmcif_write(0, &host->regs->ce_block_set);
+ sh_mmcif_write(data->blocksize, &host->regs->ce_block_set);
+ }
+ opc = sh_mmcif_set_cmd(host, data, cmd);
+
+ sh_mmcif_write(INT_START_MAGIC, &host->regs->ce_int);
+ sh_mmcif_write(mask, &host->regs->ce_int_mask);
+
+ debug("CMD%d ARG:%08x\n", cmd->cmdidx, cmd->cmdarg);
+ /* set arg */
+ sh_mmcif_write(cmd->cmdarg, &host->regs->ce_arg);
+ host->wait_int = 0;
+ /* set cmd */
+ sh_mmcif_write(opc, &host->regs->ce_cmd_set);
+
+ time = mmcif_wait_interrupt_flag(host);
+ if (time == 0)
+ return sh_mmcif_error_manage(host);
+
+ if (host->sd_error) {
+ switch (cmd->cmdidx) {
+ case MMC_CMD_ALL_SEND_CID:
+ case MMC_CMD_SELECT_CARD:
+ case MMC_CMD_APP_CMD:
+ ret = TIMEOUT;
+ break;
+ default:
+ printf(DRIVER_NAME": Cmd(d'%d) err\n", cmd->cmdidx);
+ ret = sh_mmcif_error_manage(host);
+ break;
+ }
+ host->sd_error = 0;
+ host->wait_int = 0;
+ return ret;
+ }
+
+ /* if no response */
+ if (!(opc & 0x00C00000))
+ return 0;
+
+ if (host->wait_int == 1) {
+ sh_mmcif_get_response(host, cmd);
+ host->wait_int = 0;
+ }
+ if (host->data)
+ ret = sh_mmcif_data_trans(host, data, cmd->cmdidx);
+ host->last_cmd = cmd->cmdidx;
+
+ return ret;
+}
+
+static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+ int ret;
+
+ WATCHDOG_RESET();
+
+ switch (cmd->cmdidx) {
+ case MMC_CMD_APP_CMD:
+ return TIMEOUT;
+ case MMC_CMD_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
+ if (data)
+ /* ext_csd */
+ break;
+ else
+ /* send_if_cond cmd (not support) */
+ return TIMEOUT;
+ default:
+ break;
+ }
+ host->sd_error = 0;
+ host->data = data;
+ ret = sh_mmcif_start_cmd(host, data, cmd);
+ host->data = NULL;
+
+ return ret;
+}
+
+static void sh_mmcif_set_ios(struct mmc *mmc)
+{
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+
+ if (mmc->clock)
+ sh_mmcif_clock_control(host, mmc->clock);
+
+ if (mmc->bus_width == 8)
+ host->bus_width = MMC_BUS_WIDTH_8;
+ else if (mmc->bus_width == 4)
+ host->bus_width = MMC_BUS_WIDTH_4;
+ else
+ host->bus_width = MMC_BUS_WIDTH_1;
+
+ debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width);
+}
+
+static int sh_mmcif_init(struct mmc *mmc)
+{
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+
+ sh_mmcif_sync_reset(host);
+ sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask);
+ return 0;
+}
+
+int mmcif_mmc_init(void)
+{
+ int ret = 0;
+ struct mmc *mmc;
+ struct sh_mmcif_host *host = NULL;
+
+ mmc = malloc(sizeof(struct mmc));
+ if (!mmc)
+ ret = -ENOMEM;
+ memset(mmc, 0, sizeof(*mmc));
+ host = malloc(sizeof(struct sh_mmcif_host));
+ if (!host)
+ ret = -ENOMEM;
+ memset(host, 0, sizeof(*host));
+
+ mmc->f_min = CLKDEV_MMC_INIT;
+ mmc->f_max = CLKDEV_EMMC_DATA;
+ mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
+ MMC_MODE_8BIT;
+ memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME));
+ mmc->send_cmd = sh_mmcif_request;
+ mmc->set_ios = sh_mmcif_set_ios;
+ mmc->init = sh_mmcif_init;
+ host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
+ host->clk = CONFIG_SH_MMCIF_CLK;
+ mmc->priv = host;
+
+ mmc_register(mmc);
+
+ return ret;
+}
diff --git a/drivers/mmc/sh_mmcif.h b/drivers/mmc/sh_mmcif.h
new file mode 100644
index 0000000..bd6fbf7
--- /dev/null
+++ b/drivers/mmc/sh_mmcif.h
@@ -0,0 +1,238 @@
+/*
+ * MMCIF driver.
+ *
+ * Copyright (C) 2011 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ */
+
+#ifndef _SH_MMCIF_H_
+#define _SH_MMCIF_H_
+
+struct sh_mmcif_regs {
+ unsigned long ce_cmd_set;
+ unsigned long reserved;
+ unsigned long ce_arg;
+ unsigned long ce_arg_cmd12;
+ unsigned long ce_cmd_ctrl;
+ unsigned long ce_block_set;
+ unsigned long ce_clk_ctrl;
+ unsigned long ce_buf_acc;
+ unsigned long ce_resp3;
+ unsigned long ce_resp2;
+ unsigned long ce_resp1;
+ unsigned long ce_resp0;
+ unsigned long ce_resp_cmd12;
+ unsigned long ce_data;
+ unsigned long reserved2[2];
+ unsigned long ce_int;
+ unsigned long ce_int_mask;
+ unsigned long ce_host_sts1;
+ unsigned long ce_host_sts2;
+ unsigned long reserved3[11];
+ unsigned long ce_version;
+};
+
+/* CE_CMD_SET */
+#define CMD_MASK 0x3f000000
+#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22))
+/* R1/R1b/R3/R4/R5 */
+#define CMD_SET_RTYP_6B ((0 << 23) | (1 << 22))
+/* R2 */
+#define CMD_SET_RTYP_17B ((1 << 23) | (0 << 22))
+/* R1b */
+#define CMD_SET_RBSY (1 << 21)
+#define CMD_SET_CCSEN (1 << 20)
+/* 1: on data, 0: no data */
+#define CMD_SET_WDAT (1 << 19)
+/* 1: write to card, 0: read from card */
+#define CMD_SET_DWEN (1 << 18)
+/* 1: multi block trans, 0: single */
+#define CMD_SET_CMLTE (1 << 17)
+/* 1: CMD12 auto issue */
+#define CMD_SET_CMD12EN (1 << 16)
+/* index check */
+#define CMD_SET_RIDXC_INDEX ((0 << 15) | (0 << 14))
+/* check bits check */
+#define CMD_SET_RIDXC_BITS ((0 << 15) | (1 << 14))
+/* no check */
+#define CMD_SET_RIDXC_NO ((1 << 15) | (0 << 14))
+/* 1: CRC7 check*/
+#define CMD_SET_CRC7C ((0 << 13) | (0 << 12))
+/* 1: check bits check*/
+#define CMD_SET_CRC7C_BITS ((0 << 13) | (1 << 12))
+/* 1: internal CRC7 check*/
+#define CMD_SET_CRC7C_INTERNAL ((1 << 13) | (0 << 12))
+/* 1: CRC16 check*/
+#define CMD_SET_CRC16C (1 << 10)
+/* 1: not receive CRC status */
+#define CMD_SET_CRCSTE (1 << 8)
+/* 1: tran mission bit "Low" */
+#define CMD_SET_TBIT (1 << 7)
+/* 1: open/drain */
+#define CMD_SET_OPDM (1 << 6)
+#define CMD_SET_CCSH (1 << 5)
+/* 1bit */
+#define CMD_SET_DATW_1 ((0 << 1) | (0 << 0))
+/* 4bit */
+#define CMD_SET_DATW_4 ((0 << 1) | (1 << 0))
+/* 8bit */
+#define CMD_SET_DATW_8 ((1 << 1) | (0 << 0))
+
+/* CE_CMD_CTRL */
+#define CMD_CTRL_BREAK (1 << 0)
+
+/* CE_BLOCK_SET */
+#define BLOCK_SIZE_MASK 0x0000ffff
+
+/* CE_CLK_CTRL */
+#define CLK_ENABLE (1 << 24)
+#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+#define CLK_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+/* respons timeout */
+#define SRSPTO_256 ((1 << 13) | (0 << 12))
+/* respons busy timeout */
+#define SRBSYTO_29 ((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8))
+/* read/write timeout */
+#define SRWDTO_29 ((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4))
+/* ccs timeout */
+#define SCCSTO_29 ((1 << 3) | (1 << 2) | (1 << 1) | (1 << 0))
+
+/* CE_BUF_ACC */
+#define BUF_ACC_DMAWEN (1 << 25)
+#define BUF_ACC_DMAREN (1 << 24)
+#define BUF_ACC_BUSW_32 (0 << 17)
+#define BUF_ACC_BUSW_16 (1 << 17)
+#define BUF_ACC_ATYP (1 << 16)
+
+/* CE_INT */
+#define INT_CCSDE (1 << 29)
+#define INT_CMD12DRE (1 << 26)
+#define INT_CMD12RBE (1 << 25)
+#define INT_CMD12CRE (1 << 24)
+#define INT_DTRANE (1 << 23)
+#define INT_BUFRE (1 << 22)
+#define INT_BUFWEN (1 << 21)
+#define INT_BUFREN (1 << 20)
+#define INT_CCSRCV (1 << 19)
+#define INT_RBSYE (1 << 17)
+#define INT_CRSPE (1 << 16)
+#define INT_CMDVIO (1 << 15)
+#define INT_BUFVIO (1 << 14)
+#define INT_WDATERR (1 << 11)
+#define INT_RDATERR (1 << 10)
+#define INT_RIDXERR (1 << 9)
+#define INT_RSPERR (1 << 8)
+#define INT_CCSTO (1 << 5)
+#define INT_CRCSTO (1 << 4)
+#define INT_WDATTO (1 << 3)
+#define INT_RDATTO (1 << 2)
+#define INT_RBSYTO (1 << 1)
+#define INT_RSPTO (1 << 0)
+#define INT_ERR_STS (INT_CMDVIO | INT_BUFVIO | INT_WDATERR | \
+ INT_RDATERR | INT_RIDXERR | INT_RSPERR | \
+ INT_CCSTO | INT_CRCSTO | INT_WDATTO | \
+ INT_RDATTO | INT_RBSYTO | INT_RSPTO)
+#define INT_START_MAGIC 0xD80430C0
+
+/* CE_INT_MASK */
+#define MASK_ALL 0x00000000
+#define MASK_MCCSDE (1 << 29)
+#define MASK_MCMD12DRE (1 << 26)
+#define MASK_MCMD12RBE (1 << 25)
+#define MASK_MCMD12CRE (1 << 24)
+#define MASK_MDTRANE (1 << 23)
+#define MASK_MBUFRE (1 << 22)
+#define MASK_MBUFWEN (1 << 21)
+#define MASK_MBUFREN (1 << 20)
+#define MASK_MCCSRCV (1 << 19)
+#define MASK_MRBSYE (1 << 17)
+#define MASK_MCRSPE (1 << 16)
+#define MASK_MCMDVIO (1 << 15)
+#define MASK_MBUFVIO (1 << 14)
+#define MASK_MWDATERR (1 << 11)
+#define MASK_MRDATERR (1 << 10)
+#define MASK_MRIDXERR (1 << 9)
+#define MASK_MRSPERR (1 << 8)
+#define MASK_MCCSTO (1 << 5)
+#define MASK_MCRCSTO (1 << 4)
+#define MASK_MWDATTO (1 << 3)
+#define MASK_MRDATTO (1 << 2)
+#define MASK_MRBSYTO (1 << 1)
+#define MASK_MRSPTO (1 << 0)
+
+/* CE_HOST_STS1 */
+#define STS1_CMDSEQ (1 << 31)
+
+/* CE_HOST_STS2 */
+#define STS2_CRCSTE (1 << 31)
+#define STS2_CRC16E (1 << 30)
+#define STS2_AC12CRCE (1 << 29)
+#define STS2_RSPCRC7E (1 << 28)
+#define STS2_CRCSTEBE (1 << 27)
+#define STS2_RDATEBE (1 << 26)
+#define STS2_AC12REBE (1 << 25)
+#define STS2_RSPEBE (1 << 24)
+#define STS2_AC12IDXE (1 << 23)
+#define STS2_RSPIDXE (1 << 22)
+#define STS2_CCSTO (1 << 15)
+#define STS2_RDATTO (1 << 14)
+#define STS2_DATBSYTO (1 << 13)
+#define STS2_CRCSTTO (1 << 12)
+#define STS2_AC12BSYTO (1 << 11)
+#define STS2_RSPBSYTO (1 << 10)
+#define STS2_AC12RSPTO (1 << 9)
+#define STS2_RSPTO (1 << 8)
+
+#define STS2_CRC_ERR (STS2_CRCSTE | STS2_CRC16E | \
+ STS2_AC12CRCE | STS2_RSPCRC7E | STS2_CRCSTEBE)
+#define STS2_TIMEOUT_ERR (STS2_CCSTO | STS2_RDATTO | \
+ STS2_DATBSYTO | STS2_CRCSTTO | \
+ STS2_AC12BSYTO | STS2_RSPBSYTO | \
+ STS2_AC12RSPTO | STS2_RSPTO)
+
+/* CE_VERSION */
+#define SOFT_RST_ON (1 << 31)
+#define SOFT_RST_OFF (0 << 31)
+
+#define CLKDEV_EMMC_DATA 52000000 /* 52MHz */
+#define CLKDEV_MMC_INIT 400000 /* 100 - 400 KHz */
+
+#define MMC_BUS_WIDTH_1 0
+#define MMC_BUS_WIDTH_4 2
+#define MMC_BUS_WIDTH_8 3
+
+struct sh_mmcif_host {
+ struct mmc_data *data;
+ struct sh_mmcif_regs *regs;
+ unsigned int clk;
+ int bus_width;
+ u16 wait_int;
+ u16 sd_error;
+ u8 last_cmd;
+};
+
+static inline u32 sh_mmcif_read(unsigned long *reg)
+{
+ return readl(reg);
+}
+
+static inline void sh_mmcif_write(u32 val, unsigned long *reg)
+{
+ writel(val, reg);
+}
+
+static inline void sh_mmcif_bitset(u32 val, unsigned long *reg)
+{
+ sh_mmcif_write(val | sh_mmcif_read(reg), reg);
+}
+
+static inline void sh_mmcif_bitclr(u32 val, unsigned long *reg)
+{
+ sh_mmcif_write(~val & sh_mmcif_read(reg), reg);
+}
+
+#endif /* _SH_MMCIF_H_ */
diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
new file mode 100644
index 0000000..8b6f829
--- /dev/null
+++ b/drivers/mmc/tegra2_mmc.c
@@ -0,0 +1,510 @@
+/*
+ * (C) Copyright 2009 SAMSUNG Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Jaehoon Chung <jh80.chung@samsung.com>
+ * Portions Copyright 2011 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <asm/io.h>
+#include <asm/arch/clk_rst.h>
+#include "tegra2_mmc.h"
+
+/* support 4 mmc hosts */
+struct mmc mmc_dev[4];
+struct mmc_host mmc_host[4];
+
+static inline struct tegra2_mmc *tegra2_get_base_mmc(int dev_index)
+{
+ unsigned long offset;
+ debug("tegra2_get_base_mmc: dev_index = %d\n", dev_index);
+
+ switch (dev_index) {
+ case 0:
+ offset = TEGRA2_SDMMC4_BASE;
+ break;
+ case 1:
+ offset = TEGRA2_SDMMC3_BASE;
+ break;
+ case 2:
+ offset = TEGRA2_SDMMC2_BASE;
+ break;
+ case 3:
+ offset = TEGRA2_SDMMC1_BASE;
+ break;
+ default:
+ offset = TEGRA2_SDMMC4_BASE;
+ break;
+ }
+
+ return (struct tegra2_mmc *)(offset);
+}
+
+static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data)
+{
+ unsigned char ctrl;
+
+ debug("data->dest: %08X, data->blocks: %u, data->blocksize: %u\n",
+ (u32)data->dest, data->blocks, data->blocksize);
+
+ writel((u32)data->dest, &host->reg->sysad);
+ /*
+ * DMASEL[4:3]
+ * 00 = Selects SDMA
+ * 01 = Reserved
+ * 10 = Selects 32-bit Address ADMA2
+ * 11 = Selects 64-bit Address ADMA2
+ */
+ ctrl = readb(&host->reg->hostctl);
+ ctrl &= ~(3 << 3); /* SDMA */
+ writeb(ctrl, &host->reg->hostctl);
+
+ /* We do not handle DMA boundaries, so set it to max (512 KiB) */
+ writew((7 << 12) | (data->blocksize & 0xFFF), &host->reg->blksize);
+ writew(data->blocks, &host->reg->blkcnt);
+}
+
+static void mmc_set_transfer_mode(struct mmc_host *host, struct mmc_data *data)
+{
+ unsigned short mode;
+ debug(" mmc_set_transfer_mode called\n");
+ /*
+ * TRNMOD
+ * MUL1SIN0[5] : Multi/Single Block Select
+ * RD1WT0[4] : Data Transfer Direction Select
+ * 1 = read
+ * 0 = write
+ * ENACMD12[2] : Auto CMD12 Enable
+ * ENBLKCNT[1] : Block Count Enable
+ * ENDMA[0] : DMA Enable
+ */
+ mode = (1 << 1) | (1 << 0);
+ if (data->blocks > 1)
+ mode |= (1 << 5);
+ if (data->flags & MMC_DATA_READ)
+ mode |= (1 << 4);
+
+ writew(mode, &host->reg->trnmod);
+}
+
+static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct mmc_host *host = (struct mmc_host *)mmc->priv;
+ int flags, i;
+ unsigned int timeout;
+ unsigned int mask;
+ unsigned int retry = 0x100000;
+ debug(" mmc_send_cmd called\n");
+
+ /* Wait max 10 ms */
+ timeout = 10;
+
+ /*
+ * PRNSTS
+ * CMDINHDAT[1] : Command Inhibit (DAT)
+ * CMDINHCMD[0] : Command Inhibit (CMD)
+ */
+ mask = (1 << 0);
+ if ((data != NULL) || (cmd->resp_type & MMC_RSP_BUSY))
+ mask |= (1 << 1);
+
+ /*
+ * We shouldn't wait for data inhibit for stop commands, even
+ * though they might use busy signaling
+ */
+ if (data)
+ mask &= ~(1 << 1);
+
+ while (readl(&host->reg->prnsts) & mask) {
+ if (timeout == 0) {
+ printf("%s: timeout error\n", __func__);
+ return -1;
+ }
+ timeout--;
+ udelay(1000);
+ }
+
+ if (data)
+ mmc_prepare_data(host, data);
+
+ debug("cmd->arg: %08x\n", cmd->cmdarg);
+ writel(cmd->cmdarg, &host->reg->argument);
+
+ if (data)
+ mmc_set_transfer_mode(host, data);
+
+ if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
+ return -1;
+
+ /*
+ * CMDREG
+ * CMDIDX[13:8] : Command index
+ * DATAPRNT[5] : Data Present Select
+ * ENCMDIDX[4] : Command Index Check Enable
+ * ENCMDCRC[3] : Command CRC Check Enable
+ * RSPTYP[1:0]
+ * 00 = No Response
+ * 01 = Length 136
+ * 10 = Length 48
+ * 11 = Length 48 Check busy after response
+ */
+ if (!(cmd->resp_type & MMC_RSP_PRESENT))
+ flags = 0;
+ else if (cmd->resp_type & MMC_RSP_136)
+ flags = (1 << 0);
+ else if (cmd->resp_type & MMC_RSP_BUSY)
+ flags = (3 << 0);
+ else
+ flags = (2 << 0);
+
+ if (cmd->resp_type & MMC_RSP_CRC)
+ flags |= (1 << 3);
+ if (cmd->resp_type & MMC_RSP_OPCODE)
+ flags |= (1 << 4);
+ if (data)
+ flags |= (1 << 5);
+
+ debug("cmd: %d\n", cmd->cmdidx);
+
+ writew((cmd->cmdidx << 8) | flags, &host->reg->cmdreg);
+
+ for (i = 0; i < retry; i++) {
+ mask = readl(&host->reg->norintsts);
+ /* Command Complete */
+ if (mask & (1 << 0)) {
+ if (!data)
+ writel(mask, &host->reg->norintsts);
+ break;
+ }
+ }
+
+ if (i == retry) {
+ printf("%s: waiting for status update\n", __func__);
+ return TIMEOUT;
+ }
+
+ if (mask & (1 << 16)) {
+ /* Timeout Error */
+ debug("timeout: %08x cmd %d\n", mask, cmd->cmdidx);
+ return TIMEOUT;
+ } else if (mask & (1 << 15)) {
+ /* Error Interrupt */
+ debug("error: %08x cmd %d\n", mask, cmd->cmdidx);
+ return -1;
+ }
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ if (cmd->resp_type & MMC_RSP_136) {
+ /* CRC is stripped so we need to do some shifting. */
+ for (i = 0; i < 4; i++) {
+ unsigned int offset =
+ (unsigned int)(&host->reg->rspreg3 - i);
+ cmd->response[i] = readl(offset) << 8;
+
+ if (i != 3) {
+ cmd->response[i] |=
+ readb(offset - 1);
+ }
+ debug("cmd->resp[%d]: %08x\n",
+ i, cmd->response[i]);
+ }
+ } else if (cmd->resp_type & MMC_RSP_BUSY) {
+ for (i = 0; i < retry; i++) {
+ /* PRNTDATA[23:20] : DAT[3:0] Line Signal */
+ if (readl(&host->reg->prnsts)
+ & (1 << 20)) /* DAT[0] */
+ break;
+ }
+
+ if (i == retry) {
+ printf("%s: card is still busy\n", __func__);
+ return TIMEOUT;
+ }
+
+ cmd->response[0] = readl(&host->reg->rspreg0);
+ debug("cmd->resp[0]: %08x\n", cmd->response[0]);
+ } else {
+ cmd->response[0] = readl(&host->reg->rspreg0);
+ debug("cmd->resp[0]: %08x\n", cmd->response[0]);
+ }
+ }
+
+ if (data) {
+ while (1) {
+ mask = readl(&host->reg->norintsts);
+
+ if (mask & (1 << 15)) {
+ /* Error Interrupt */
+ writel(mask, &host->reg->norintsts);
+ printf("%s: error during transfer: 0x%08x\n",
+ __func__, mask);
+ return -1;
+ } else if (mask & (1 << 3)) {
+ /* DMA Interrupt */
+ debug("DMA end\n");
+ break;
+ } else if (mask & (1 << 1)) {
+ /* Transfer Complete */
+ debug("r/w is done\n");
+ break;
+ }
+ }
+ writel(mask, &host->reg->norintsts);
+ }
+
+ udelay(1000);
+ return 0;
+}
+
+static void mmc_change_clock(struct mmc_host *host, uint clock)
+{
+ int div, hw_div;
+ unsigned short clk;
+ unsigned long timeout;
+ unsigned int reg, hostbase;
+ struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ debug(" mmc_change_clock called\n");
+
+ /* Change Tegra2 SDMMCx clock divisor here */
+ /* Source is 216MHz, PLLP_OUT0 */
+ if (clock == 0)
+ goto out;
+
+ div = 1;
+ if (clock <= 400000) {
+ hw_div = ((9-1)<<1); /* Best match is 375KHz */
+ div = 64;
+ } else if (clock <= 20000000)
+ hw_div = ((11-1)<<1); /* Best match is 19.6MHz */
+ else if (clock <= 26000000)
+ hw_div = ((9-1)<<1); /* Use 24MHz */
+ else
+ hw_div = ((4-1)<<1) + 1; /* 4.5 divisor for 48MHz */
+
+ debug("mmc_change_clock: hw_div = %d, card clock div = %d\n",
+ hw_div, div);
+
+ /* Change SDMMCx divisor */
+
+ hostbase = readl(&host->base);
+ debug("mmc_change_clock: hostbase = %08X\n", hostbase);
+
+ if (hostbase == TEGRA2_SDMMC1_BASE) {
+ reg = readl(&clkrst->crc_clk_src_sdmmc1);
+ reg &= 0xFFFFFF00; /* divisor (7.1) = 00 */
+ reg |= hw_div; /* n-1 */
+ writel(reg, &clkrst->crc_clk_src_sdmmc1);
+ } else if (hostbase == TEGRA2_SDMMC2_BASE) {
+ reg = readl(&clkrst->crc_clk_src_sdmmc2);
+ reg &= 0xFFFFFF00; /* divisor (7.1) = 00 */
+ reg |= hw_div; /* n-1 */
+ writel(reg, &clkrst->crc_clk_src_sdmmc2);
+ } else if (hostbase == TEGRA2_SDMMC3_BASE) {
+ reg = readl(&clkrst->crc_clk_src_sdmmc3);
+ reg &= 0xFFFFFF00; /* divisor (7.1) = 00 */
+ reg |= hw_div; /* n-1 */
+ writel(reg, &clkrst->crc_clk_src_sdmmc3);
+ } else {
+ reg = readl(&clkrst->crc_clk_src_sdmmc4);
+ reg &= 0xFFFFFF00; /* divisor (7.1) = 00 */
+ reg |= hw_div; /* n-1 */
+ writel(reg, &clkrst->crc_clk_src_sdmmc4);
+ }
+
+ writew(0, &host->reg->clkcon);
+
+ div >>= 1;
+ /*
+ * CLKCON
+ * SELFREQ[15:8] : base clock divided by value
+ * ENSDCLK[2] : SD Clock Enable
+ * STBLINTCLK[1] : Internal Clock Stable
+ * ENINTCLK[0] : Internal Clock Enable
+ */
+ clk = (div << 8) | (1 << 0);
+ writew(clk, &host->reg->clkcon);
+
+ /* Wait max 10 ms */
+ timeout = 10;
+ while (!(readw(&host->reg->clkcon) & (1 << 1))) {
+ if (timeout == 0) {
+ printf("%s: timeout error\n", __func__);
+ return;
+ }
+ timeout--;
+ udelay(1000);
+ }
+
+ clk |= (1 << 2);
+ writew(clk, &host->reg->clkcon);
+
+ debug("mmc_change_clock: clkcon = %08X\n", clk);
+ debug("mmc_change_clock: CLK_SOURCE_SDMMCx = %08X\n", reg);
+
+out:
+ host->clock = clock;
+}
+
+static void mmc_set_ios(struct mmc *mmc)
+{
+ struct mmc_host *host = mmc->priv;
+ unsigned char ctrl;
+ debug(" mmc_set_ios called\n");
+
+ debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock);
+
+ /* Change clock first */
+
+ mmc_change_clock(host, mmc->clock);
+
+ ctrl = readb(&host->reg->hostctl);
+
+ /*
+ * WIDE8[5]
+ * 0 = Depend on WIDE4
+ * 1 = 8-bit mode
+ * WIDE4[1]
+ * 1 = 4-bit mode
+ * 0 = 1-bit mode
+ */
+ if (mmc->bus_width == 8)
+ ctrl |= (1 << 5);
+ else if (mmc->bus_width == 4)
+ ctrl |= (1 << 1);
+ else
+ ctrl &= ~(1 << 1);
+
+ writeb(ctrl, &host->reg->hostctl);
+ debug("mmc_set_ios: hostctl = %08X\n", ctrl);
+}
+
+static void mmc_reset(struct mmc_host *host)
+{
+ unsigned int timeout;
+ debug(" mmc_reset called\n");
+
+ /*
+ * RSTALL[0] : Software reset for all
+ * 1 = reset
+ * 0 = work
+ */
+ writeb((1 << 0), &host->reg->swrst);
+
+ host->clock = 0;
+
+ /* Wait max 100 ms */
+ timeout = 100;
+
+ /* hw clears the bit when it's done */
+ while (readb(&host->reg->swrst) & (1 << 0)) {
+ if (timeout == 0) {
+ printf("%s: timeout error\n", __func__);
+ return;
+ }
+ timeout--;
+ udelay(1000);
+ }
+}
+
+static int mmc_core_init(struct mmc *mmc)
+{
+ struct mmc_host *host = (struct mmc_host *)mmc->priv;
+ unsigned int mask;
+ debug(" mmc_core_init called\n");
+
+ mmc_reset(host);
+
+ host->version = readw(&host->reg->hcver);
+ debug("host version = %x\n", host->version);
+
+ /* mask all */
+ writel(0xffffffff, &host->reg->norintstsen);
+ writel(0xffffffff, &host->reg->norintsigen);
+
+ writeb(0xe, &host->reg->timeoutcon); /* TMCLK * 2^27 */
+ /*
+ * NORMAL Interrupt Status Enable Register init
+ * [5] ENSTABUFRDRDY : Buffer Read Ready Status Enable
+ * [4] ENSTABUFWTRDY : Buffer write Ready Status Enable
+ * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable
+ * [0] ENSTACMDCMPLT : Command Complete Status Enable
+ */
+ mask = readl(&host->reg->norintstsen);
+ mask &= ~(0xffff);
+ mask |= (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0);
+ writel(mask, &host->reg->norintstsen);
+
+ /*
+ * NORMAL Interrupt Signal Enable Register init
+ * [1] ENSTACMDCMPLT : Transfer Complete Signal Enable
+ */
+ mask = readl(&host->reg->norintsigen);
+ mask &= ~(0xffff);
+ mask |= (1 << 1);
+ writel(mask, &host->reg->norintsigen);
+
+ return 0;
+}
+
+static int tegra2_mmc_initialize(int dev_index, int bus_width)
+{
+ struct mmc *mmc;
+
+ debug(" mmc_initialize called\n");
+
+ mmc = &mmc_dev[dev_index];
+
+ sprintf(mmc->name, "Tegra2 SD/MMC");
+ mmc->priv = &mmc_host[dev_index];
+ mmc->send_cmd = mmc_send_cmd;
+ mmc->set_ios = mmc_set_ios;
+ mmc->init = mmc_core_init;
+
+ mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ if (bus_width == 8)
+ mmc->host_caps = MMC_MODE_8BIT;
+ else
+ mmc->host_caps = MMC_MODE_4BIT;
+ mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
+ /*
+ * min freq is for card identification, and is the highest
+ * low-speed SDIO card frequency (actually 400KHz)
+ * max freq is highest HS eMMC clock as per the SD/MMC spec
+ * (actually 52MHz)
+ * Both of these are the closest equivalents w/216MHz source
+ * clock and Tegra2 SDMMC divisors.
+ */
+ mmc->f_min = 375000;
+ mmc->f_max = 48000000;
+
+ mmc_host[dev_index].clock = 0;
+ mmc_host[dev_index].reg = tegra2_get_base_mmc(dev_index);
+ mmc_host[dev_index].base = (unsigned int)mmc_host[dev_index].reg;
+ mmc_register(mmc);
+
+ return 0;
+}
+
+int tegra2_mmc_init(int dev_index, int bus_width)
+{
+ debug(" tegra2_mmc_init: index %d, bus width %d\n",
+ dev_index, bus_width);
+ return tegra2_mmc_initialize(dev_index, bus_width);
+}
diff --git a/drivers/mmc/tegra2_mmc.h b/drivers/mmc/tegra2_mmc.h
new file mode 100644
index 0000000..4b80f9f
--- /dev/null
+++ b/drivers/mmc/tegra2_mmc.h
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2009 SAMSUNG Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Portions Copyright (C) 2011 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __TEGRA2_MMC_H_
+#define __TEGRA2_MMC_H_
+
+#define TEGRA2_SDMMC1_BASE 0xC8000000
+#define TEGRA2_SDMMC2_BASE 0xC8000200
+#define TEGRA2_SDMMC3_BASE 0xC8000400
+#define TEGRA2_SDMMC4_BASE 0xC8000600
+
+#ifndef __ASSEMBLY__
+struct tegra2_mmc {
+ unsigned int sysad; /* _SYSTEM_ADDRESS_0 */
+ unsigned short blksize; /* _BLOCK_SIZE_BLOCK_COUNT_0 15:00 */
+ unsigned short blkcnt; /* _BLOCK_SIZE_BLOCK_COUNT_0 31:16 */
+ unsigned int argument; /* _ARGUMENT_0 */
+ unsigned short trnmod; /* _CMD_XFER_MODE_0 15:00 xfer mode */
+ unsigned short cmdreg; /* _CMD_XFER_MODE_0 31:16 cmd reg */
+ unsigned int rspreg0; /* _RESPONSE_R0_R1_0 CMD RESP 31:00 */
+ unsigned int rspreg1; /* _RESPONSE_R2_R3_0 CMD RESP 63:32 */
+ unsigned int rspreg2; /* _RESPONSE_R4_R5_0 CMD RESP 95:64 */
+ unsigned int rspreg3; /* _RESPONSE_R6_R7_0 CMD RESP 127:96 */
+ unsigned int bdata; /* _BUFFER_DATA_PORT_0 */
+ unsigned int prnsts; /* _PRESENT_STATE_0 */
+ unsigned char hostctl; /* _POWER_CONTROL_HOST_0 7:00 */
+ unsigned char pwrcon; /* _POWER_CONTROL_HOST_0 15:8 */
+ unsigned char blkgap; /* _POWER_CONTROL_HOST_9 23:16 */
+ unsigned char wakcon; /* _POWER_CONTROL_HOST_0 31:24 */
+ unsigned short clkcon; /* _CLOCK_CONTROL_0 15:00 */
+ unsigned char timeoutcon; /* _TIMEOUT_CTRL 23:16 */
+ unsigned char swrst; /* _SW_RESET_ 31:24 */
+ unsigned int norintsts; /* _INTERRUPT_STATUS_0 */
+ unsigned int norintstsen; /* _INTERRUPT_STATUS_ENABLE_0 */
+ unsigned int norintsigen; /* _INTERRUPT_SIGNAL_ENABLE_0 */
+ unsigned short acmd12errsts; /* _AUTO_CMD12_ERR_STATUS_0 15:00 */
+ unsigned char res1[2]; /* _RESERVED 31:16 */
+ unsigned int capareg; /* _CAPABILITIES_0 */
+ unsigned char res2[4]; /* RESERVED, offset 44h-47h */
+ unsigned int maxcurr; /* _MAXIMUM_CURRENT_0 */
+ unsigned char res3[4]; /* RESERVED, offset 4Ch-4Fh */
+ unsigned short setacmd12err; /* offset 50h */
+ unsigned short setinterr; /* offset 52h */
+ unsigned char admaerr; /* offset 54h */
+ unsigned char res4[3]; /* RESERVED, offset 55h-57h */
+ unsigned long admaaddr; /* offset 58h-5Fh */
+ unsigned char res5[0x9c]; /* RESERVED, offset 60h-FBh */
+ unsigned short slotintstatus; /* offset FCh */
+ unsigned short hcver; /* HOST Version */
+ unsigned char res6[0x100]; /* RESERVED, offset 100h-1FFh */
+};
+
+struct mmc_host {
+ struct tegra2_mmc *reg;
+ unsigned int version; /* SDHCI spec. version */
+ unsigned int clock; /* Current clock (MHz) */
+ unsigned int base; /* Base address, SDMMC1/2/3/4 */
+};
+
+int tegra2_mmc_init(int dev_index, int bus_width);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __TEGRA2_MMC_H_ */
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 929f9a9..ac91dfd 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -573,7 +573,9 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
#endif
/* Wait for command completion */
+#ifdef CONFIG_SYS_LOW_RES_TIMER
reset_timer();
+#endif
start = get_timer (0);
while (flash_is_busy (info, sector)) {
if (get_timer (start) > tout) {
@@ -662,7 +664,9 @@ static int flash_status_poll(flash_info_t *info, void *src, void *dst,
#endif
/* Wait for command completion */
+#ifdef CONFIG_SYS_LOW_RES_TIMER
reset_timer();
+#endif
start = get_timer(0);
while (1) {
switch (info->portwidth) {
diff --git a/drivers/mtd/spi/eeprom_m95xxx.c b/drivers/mtd/spi/eeprom_m95xxx.c
index 632db4e..ef8ed6f 100644
--- a/drivers/mtd/spi/eeprom_m95xxx.c
+++ b/drivers/mtd/spi/eeprom_m95xxx.c
@@ -75,6 +75,7 @@ ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
{
struct spi_slave *slave;
char buf[3];
+ ulong start;
slave = spi_setup_slave(CONFIG_DEFAULT_SPI_BUS, 1, 1000000,
CONFIG_DEFAULT_SPI_MODE);
@@ -102,7 +103,7 @@ ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
if(spi_xfer(slave, len * 8, buffer, NULL, SPI_XFER_END))
return -1;
- reset_timer_masked();
+ start = get_timer(0);
do {
buf[0] = SPI_EEPROM_RDSR;
buf[1] = 0;
@@ -111,7 +112,7 @@ ssize_t spi_write (uchar *addr, int alen, uchar *buffer, int len)
if (!(buf[1] & 1))
break;
- } while (get_timer_masked() < CONFIG_SYS_SPI_WRITE_TOUT);
+ } while (get_timer(start) < CONFIG_SYS_SPI_WRITE_TOUT);
if (buf[1] & 1)
printf ("*** spi_write: Time out while writing!\n");
diff --git a/drivers/mtd/spi/eon.c b/drivers/mtd/spi/eon.c
index e3de3aa..806b44e 100644
--- a/drivers/mtd/spi/eon.c
+++ b/drivers/mtd/spi/eon.c
@@ -23,8 +23,6 @@
#define CMD_EN25Q128_DP 0xb9 /* Deep Power-down */
#define CMD_EN25Q128_RES 0xab /* Release from DP, and Read Signature */
-#define EON_ID_EN25Q128 0x18
-
struct eon_spi_flash_params {
u8 idcode1;
u16 page_size;
@@ -34,20 +32,9 @@ struct eon_spi_flash_params {
const char *name;
};
-/* spi_flash needs to be first so upper layers can free() it */
-struct eon_spi_flash {
- struct spi_flash flash;
- const struct eon_spi_flash_params *params;
-};
-
-static inline struct eon_spi_flash *to_eon_spi_flash(struct spi_flash *flash)
-{
- return container_of(flash, struct eon_spi_flash, flash);
-}
-
static const struct eon_spi_flash_params eon_spi_flash_table[] = {
{
- .idcode1 = EON_ID_EN25Q128,
+ .idcode1 = 0x18,
.page_size = 256,
.pages_per_sector = 16,
.sectors_per_block = 16,
@@ -56,69 +43,6 @@ static const struct eon_spi_flash_params eon_spi_flash_table[] = {
},
};
-static int eon_write(struct spi_flash *flash,
- u32 offset, size_t len, const void *buf)
-{
- struct eon_spi_flash *eon = to_eon_spi_flash(flash);
- unsigned long page_addr;
- unsigned long byte_addr;
- unsigned long page_size;
- size_t chunk_len;
- size_t actual;
- int ret;
- u8 cmd[4];
-
- page_size = eon->params->page_size;
- page_addr = offset / page_size;
- byte_addr = offset % page_size;
-
- ret = spi_claim_bus(flash->spi);
- if (ret) {
- debug("SF: Unable to claim SPI bus\n");
- return ret;
- }
-
- ret = 0;
- for (actual = 0; actual < len; actual += chunk_len) {
- chunk_len = min(len - actual, page_size - byte_addr);
-
- cmd[0] = CMD_EN25Q128_PP;
- cmd[1] = page_addr >> 8;
- cmd[2] = page_addr;
- cmd[3] = byte_addr;
-
- debug
- ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
- ret = spi_flash_cmd(flash->spi, CMD_EN25Q128_WREN, NULL, 0);
- if (ret < 0) {
- debug("SF: Enabling Write failed\n");
- break;
- }
-
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
- buf + actual, chunk_len);
- if (ret < 0) {
- debug("SF: EON Page Program failed\n");
- break;
- }
-
- ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
- if (ret)
- break;
-
- page_addr++;
- byte_addr = 0;
- }
-
- debug("SF: EON: Successfully programmed %u bytes @ 0x%x\n",
- len, offset);
-
- spi_release_bus(flash->spi);
- return ret;
-}
-
static int eon_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_EN25Q128_BE, offset, len);
@@ -127,7 +51,7 @@ static int eon_erase(struct spi_flash *flash, u32 offset, size_t len)
struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
{
const struct eon_spi_flash_params *params;
- struct eon_spi_flash *eon;
+ struct spi_flash *flash;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(eon_spi_flash_table); ++i) {
@@ -141,23 +65,23 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- eon = malloc(sizeof(*eon));
- if (!eon) {
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- eon->params = params;
- eon->flash.spi = spi;
- eon->flash.name = params->name;
+ flash->spi = spi;
+ flash->name = params->name;
- eon->flash.write = eon_write;
- eon->flash.erase = eon_erase;
- eon->flash.read = spi_flash_cmd_read_fast;
- eon->flash.sector_size = params->page_size * params->pages_per_sector
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = eon_erase;
+ flash->read = spi_flash_cmd_read_fast;
+ flash->page_size = params->page_size;
+ flash->sector_size = params->page_size * params->pages_per_sector
* params->sectors_per_block;
- eon->flash.size = params->page_size * params->pages_per_sector
+ flash->size = params->page_size * params->pages_per_sector
* params->nr_sectors;
- return &eon->flash;
+ return flash;
}
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index ff66f2a..e689562 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -58,17 +58,6 @@ struct macronix_spi_flash_params {
const char *name;
};
-struct macronix_spi_flash {
- struct spi_flash flash;
- const struct macronix_spi_flash_params *params;
-};
-
-static inline struct macronix_spi_flash *to_macronix_spi_flash(struct spi_flash
- *flash)
-{
- return container_of(flash, struct macronix_spi_flash, flash);
-}
-
static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
{
.idcode = 0x2015,
@@ -112,69 +101,6 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
},
};
-static int macronix_write(struct spi_flash *flash,
- u32 offset, size_t len, const void *buf)
-{
- struct macronix_spi_flash *mcx = to_macronix_spi_flash(flash);
- unsigned long page_addr;
- unsigned long byte_addr;
- unsigned long page_size;
- size_t chunk_len;
- size_t actual;
- int ret;
- u8 cmd[4];
-
- page_size = mcx->params->page_size;
- page_addr = offset / page_size;
- byte_addr = offset % page_size;
-
- ret = spi_claim_bus(flash->spi);
- if (ret) {
- debug("SF: Unable to claim SPI bus\n");
- return ret;
- }
-
- ret = 0;
- for (actual = 0; actual < len; actual += chunk_len) {
- chunk_len = min(len - actual, page_size - byte_addr);
-
- cmd[0] = CMD_MX25XX_PP;
- cmd[1] = page_addr >> 8;
- cmd[2] = page_addr;
- cmd[3] = byte_addr;
-
- debug
- ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
- ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0);
- if (ret < 0) {
- debug("SF: Enabling Write failed\n");
- break;
- }
-
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
- buf + actual, chunk_len);
- if (ret < 0) {
- debug("SF: Macronix Page Program failed\n");
- break;
- }
-
- ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
- if (ret)
- break;
-
- page_addr++;
- byte_addr = 0;
- }
-
- debug("SF: Macronix: Successfully programmed %u bytes @ 0x%x\n",
- len, offset);
-
- spi_release_bus(flash->spi);
- return ret;
-}
-
static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -183,7 +109,7 @@ static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
{
const struct macronix_spi_flash_params *params;
- struct macronix_spi_flash *mcx;
+ struct spi_flash *flash;
unsigned int i;
u16 id = idcode[2] | idcode[1] << 8;
@@ -198,22 +124,22 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- mcx = malloc(sizeof(*mcx));
- if (!mcx) {
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- mcx->params = params;
- mcx->flash.spi = spi;
- mcx->flash.name = params->name;
+ flash->spi = spi;
+ flash->name = params->name;
- mcx->flash.write = macronix_write;
- mcx->flash.erase = macronix_erase;
- mcx->flash.read = spi_flash_cmd_read_fast;
- mcx->flash.sector_size = params->page_size * params->pages_per_sector
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = macronix_erase;
+ flash->read = spi_flash_cmd_read_fast;
+ flash->page_size = params->page_size;
+ flash->sector_size = params->page_size * params->pages_per_sector
* params->sectors_per_block;
- mcx->flash.size = mcx->flash.sector_size * params->nr_blocks;
+ flash->size = flash->sector_size * params->nr_blocks;
- return &mcx->flash;
+ return flash;
}
diff --git a/drivers/mtd/spi/ramtron.c b/drivers/mtd/spi/ramtron.c
index 078d16c..27d4039 100644
--- a/drivers/mtd/spi/ramtron.c
+++ b/drivers/mtd/spi/ramtron.c
@@ -198,7 +198,7 @@ static int ramtron_common(struct spi_flash *flash,
if (command == CMD_RAMTRON_WRITE) {
/* send WREN */
- ret = spi_flash_cmd(flash->spi, CMD_RAMTRON_WREN, NULL, 0);
+ ret = spi_flash_cmd_write_enable(flash);
if (ret < 0) {
debug("SF: Enabling Write failed\n");
goto releasebus;
diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c
index a3401b3..28bb51a 100644
--- a/drivers/mtd/spi/spansion.c
+++ b/drivers/mtd/spi/spansion.c
@@ -63,17 +63,6 @@ struct spansion_spi_flash_params {
const char *name;
};
-struct spansion_spi_flash {
- struct spi_flash flash;
- const struct spansion_spi_flash_params *params;
-};
-
-static inline struct spansion_spi_flash *to_spansion_spi_flash(struct spi_flash
- *flash)
-{
- return container_of(flash, struct spansion_spi_flash, flash);
-}
-
static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
{
.idcode1 = SPSN_ID_S25FL008A,
@@ -133,69 +122,6 @@ static const struct spansion_spi_flash_params spansion_spi_flash_table[] = {
},
};
-static int spansion_write(struct spi_flash *flash,
- u32 offset, size_t len, const void *buf)
-{
- struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash);
- unsigned long page_addr;
- unsigned long byte_addr;
- unsigned long page_size;
- size_t chunk_len;
- size_t actual;
- int ret;
- u8 cmd[4];
-
- page_size = spsn->params->page_size;
- page_addr = offset / page_size;
- byte_addr = offset % page_size;
-
- ret = spi_claim_bus(flash->spi);
- if (ret) {
- debug("SF: Unable to claim SPI bus\n");
- return ret;
- }
-
- ret = 0;
- for (actual = 0; actual < len; actual += chunk_len) {
- chunk_len = min(len - actual, page_size - byte_addr);
-
- cmd[0] = CMD_S25FLXX_PP;
- cmd[1] = page_addr >> 8;
- cmd[2] = page_addr;
- cmd[3] = byte_addr;
-
- debug
- ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
- ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0);
- if (ret < 0) {
- debug("SF: Enabling Write failed\n");
- break;
- }
-
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
- buf + actual, chunk_len);
- if (ret < 0) {
- debug("SF: SPANSION Page Program failed\n");
- break;
- }
-
- ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
- if (ret)
- break;
-
- page_addr++;
- byte_addr = 0;
- }
-
- debug("SF: SPANSION: Successfully programmed %u bytes @ 0x%x\n",
- len, offset);
-
- spi_release_bus(flash->spi);
- return ret;
-}
-
static int spansion_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_S25FLXX_SE, offset, len);
@@ -204,7 +130,7 @@ static int spansion_erase(struct spi_flash *flash, u32 offset, size_t len)
struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
{
const struct spansion_spi_flash_params *params;
- struct spansion_spi_flash *spsn;
+ struct spi_flash *flash;
unsigned int i;
unsigned short jedec, ext_jedec;
@@ -224,21 +150,21 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- spsn = malloc(sizeof(struct spansion_spi_flash));
- if (!spsn) {
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- spsn->params = params;
- spsn->flash.spi = spi;
- spsn->flash.name = params->name;
+ flash->spi = spi;
+ flash->name = params->name;
- spsn->flash.write = spansion_write;
- spsn->flash.erase = spansion_erase;
- spsn->flash.read = spi_flash_cmd_read_fast;
- spsn->flash.sector_size = params->page_size * params->pages_per_sector;
- spsn->flash.size = spsn->flash.sector_size * params->nr_sectors;
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = spansion_erase;
+ flash->read = spi_flash_cmd_read_fast;
+ flash->page_size = params->page_size;
+ flash->sector_size = params->page_size * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
- return &spsn->flash;
+ return flash;
}
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 016b586..730c009 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -65,6 +65,63 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
return spi_flash_read_write(spi, cmd, cmd_len, data, NULL, data_len);
}
+int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
+ size_t len, const void *buf)
+{
+ unsigned long page_addr, byte_addr, page_size;
+ size_t chunk_len, actual;
+ int ret;
+ u8 cmd[4];
+
+ page_size = flash->page_size;
+ page_addr = offset / page_size;
+ byte_addr = offset % page_size;
+
+ ret = spi_claim_bus(flash->spi);
+ if (ret) {
+ debug("SF: unable to claim SPI bus\n");
+ return ret;
+ }
+
+ cmd[0] = CMD_PAGE_PROGRAM;
+ for (actual = 0; actual < len; actual += chunk_len) {
+ chunk_len = min(len - actual, page_size - byte_addr);
+
+ cmd[1] = page_addr >> 8;
+ cmd[2] = page_addr;
+ cmd[3] = byte_addr;
+
+ debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+ buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
+
+ ret = spi_flash_cmd_write_enable(flash);
+ if (ret < 0) {
+ debug("SF: enabling write failed\n");
+ break;
+ }
+
+ ret = spi_flash_cmd_write(flash->spi, cmd, 4,
+ buf + actual, chunk_len);
+ if (ret < 0) {
+ debug("SF: write failed\n");
+ break;
+ }
+
+ ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+ if (ret)
+ break;
+
+ page_addr++;
+ byte_addr = 0;
+ }
+
+ debug("SF: program %s %zu bytes @ %#x\n",
+ ret ? "failure" : "success", len, offset);
+
+ spi_release_bus(flash->spi);
+ return ret;
+}
+
int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
size_t cmd_len, void *data, size_t data_len)
{
@@ -163,7 +220,7 @@ int spi_flash_cmd_erase(struct spi_flash *flash, u8 erase_cmd,
debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
cmd[2], cmd[3], offset);
- ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
+ ret = spi_flash_cmd_write_enable(flash);
if (ret)
goto out;
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index fc109ce..91e036a 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -19,6 +19,8 @@
#define CMD_READ_ARRAY_FAST 0x0b
#define CMD_READ_ARRAY_LEGACY 0xe8
+#define CMD_PAGE_PROGRAM 0x02
+#define CMD_WRITE_DISABLE 0x04
#define CMD_READ_STATUS 0x05
#define CMD_WRITE_ENABLE 0x06
@@ -46,6 +48,29 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
const void *data, size_t data_len);
/*
+ * Write the requested data out breaking it up into multiple write
+ * commands as needed per the write size.
+ */
+int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
+ size_t len, const void *buf);
+
+/*
+ * Enable writing on the SPI flash.
+ */
+static inline int spi_flash_cmd_write_enable(struct spi_flash *flash)
+{
+ return spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
+}
+
+/*
+ * Disable writing on the SPI flash.
+ */
+static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
+{
+ return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0);
+}
+
+/*
* Same as spi_flash_cmd_read() except it also claims/releases the SPI
* bus. Used as common part of the ->read() operation.
*/
diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c
index 4dc2db2..9559c80 100644
--- a/drivers/mtd/spi/sst.c
+++ b/drivers/mtd/spi/sst.c
@@ -36,8 +36,12 @@
#define SST_SR_AAI (1 << 6) /* Addressing mode */
#define SST_SR_BPL (1 << 7) /* BP bits lock */
+#define SST_FEAT_WP (1 << 0) /* Supports AAI word program */
+#define SST_FEAT_MBP (1 << 1) /* Supports multibyte program */
+
struct sst_spi_flash_params {
u8 idcode1;
+ u8 flags;
u16 nr_sectors;
const char *name;
};
@@ -53,41 +57,51 @@ static inline struct sst_spi_flash *to_sst_spi_flash(struct spi_flash *flash)
}
#define SST_SECTOR_SIZE (4 * 1024)
+#define SST_PAGE_SIZE 256
static const struct sst_spi_flash_params sst_spi_flash_table[] = {
{
.idcode1 = 0x8d,
+ .flags = SST_FEAT_WP,
.nr_sectors = 128,
.name = "SST25VF040B",
},{
.idcode1 = 0x8e,
+ .flags = SST_FEAT_WP,
.nr_sectors = 256,
.name = "SST25VF080B",
},{
.idcode1 = 0x41,
+ .flags = SST_FEAT_WP,
.nr_sectors = 512,
.name = "SST25VF016B",
},{
.idcode1 = 0x4a,
+ .flags = SST_FEAT_WP,
.nr_sectors = 1024,
.name = "SST25VF032B",
},{
.idcode1 = 0x4b,
+ .flags = SST_FEAT_MBP,
.nr_sectors = 2048,
.name = "SST25VF064C",
},{
.idcode1 = 0x01,
+ .flags = SST_FEAT_WP,
.nr_sectors = 16,
.name = "SST25WF512",
},{
.idcode1 = 0x02,
+ .flags = SST_FEAT_WP,
.nr_sectors = 32,
.name = "SST25WF010",
},{
.idcode1 = 0x03,
+ .flags = SST_FEAT_WP,
.nr_sectors = 64,
.name = "SST25WF020",
},{
.idcode1 = 0x04,
+ .flags = SST_FEAT_WP,
.nr_sectors = 128,
.name = "SST25WF040",
},
@@ -96,7 +110,7 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
static int
sst_enable_writing(struct spi_flash *flash)
{
- int ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0);
+ int ret = spi_flash_cmd_write_enable(flash);
if (ret)
debug("SF: Enabling Write failed\n");
return ret;
@@ -105,7 +119,7 @@ sst_enable_writing(struct spi_flash *flash)
static int
sst_disable_writing(struct spi_flash *flash)
{
- int ret = spi_flash_cmd(flash->spi, CMD_SST_WRDI, NULL, 0);
+ int ret = spi_flash_cmd_write_disable(flash);
if (ret)
debug("SF: Disabling Write failed\n");
return ret;
@@ -137,7 +151,7 @@ sst_byte_write(struct spi_flash *flash, u32 offset, const void *buf)
}
static int
-sst_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
+sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
{
size_t actual, cmd_len;
int ret;
@@ -257,9 +271,13 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
stm->flash.spi = spi;
stm->flash.name = params->name;
- stm->flash.write = sst_write;
+ if (stm->params->flags & SST_FEAT_WP)
+ stm->flash.write = sst_write_wp;
+ else
+ stm->flash.write = spi_flash_cmd_write_multi;
stm->flash.erase = sst_erase;
stm->flash.read = spi_flash_cmd_read_fast;
+ stm->flash.page_size = SST_PAGE_SIZE;
stm->flash.sector_size = SST_SECTOR_SIZE;
stm->flash.size = stm->flash.sector_size * params->nr_sectors;
diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
index a1959ca..a9b33cf 100644
--- a/drivers/mtd/spi/stmicro.c
+++ b/drivers/mtd/spi/stmicro.c
@@ -46,15 +46,6 @@
#define CMD_M25PXX_DP 0xb9 /* Deep Power-down */
#define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */
-#define STM_ID_M25P10 0x11
-#define STM_ID_M25P16 0x15
-#define STM_ID_M25P20 0x12
-#define STM_ID_M25P32 0x16
-#define STM_ID_M25P40 0x13
-#define STM_ID_M25P64 0x17
-#define STM_ID_M25P80 0x14
-#define STM_ID_M25P128 0x18
-
struct stmicro_spi_flash_params {
u8 idcode1;
u16 page_size;
@@ -63,70 +54,58 @@ struct stmicro_spi_flash_params {
const char *name;
};
-/* spi_flash needs to be first so upper layers can free() it */
-struct stmicro_spi_flash {
- struct spi_flash flash;
- const struct stmicro_spi_flash_params *params;
-};
-
-static inline struct stmicro_spi_flash *to_stmicro_spi_flash(struct spi_flash
- *flash)
-{
- return container_of(flash, struct stmicro_spi_flash, flash);
-}
-
static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
{
- .idcode1 = STM_ID_M25P10,
+ .idcode1 = 0x11,
.page_size = 256,
.pages_per_sector = 128,
.nr_sectors = 4,
.name = "M25P10",
},
{
- .idcode1 = STM_ID_M25P16,
+ .idcode1 = 0x15,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 32,
.name = "M25P16",
},
{
- .idcode1 = STM_ID_M25P20,
+ .idcode1 = 0x12,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 4,
.name = "M25P20",
},
{
- .idcode1 = STM_ID_M25P32,
+ .idcode1 = 0x16,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 64,
.name = "M25P32",
},
{
- .idcode1 = STM_ID_M25P40,
+ .idcode1 = 0x13,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 8,
.name = "M25P40",
},
{
- .idcode1 = STM_ID_M25P64,
+ .idcode1 = 0x17,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 128,
.name = "M25P64",
},
{
- .idcode1 = STM_ID_M25P80,
+ .idcode1 = 0x14,
.page_size = 256,
.pages_per_sector = 256,
.nr_sectors = 16,
.name = "M25P80",
},
{
- .idcode1 = STM_ID_M25P128,
+ .idcode1 = 0x18,
.page_size = 256,
.pages_per_sector = 1024,
.nr_sectors = 64,
@@ -134,69 +113,6 @@ static const struct stmicro_spi_flash_params stmicro_spi_flash_table[] = {
},
};
-static int stmicro_write(struct spi_flash *flash,
- u32 offset, size_t len, const void *buf)
-{
- struct stmicro_spi_flash *stm = to_stmicro_spi_flash(flash);
- unsigned long page_addr;
- unsigned long byte_addr;
- unsigned long page_size;
- size_t chunk_len;
- size_t actual;
- int ret;
- u8 cmd[4];
-
- page_size = stm->params->page_size;
- page_addr = offset / page_size;
- byte_addr = offset % page_size;
-
- ret = spi_claim_bus(flash->spi);
- if (ret) {
- debug("SF: Unable to claim SPI bus\n");
- return ret;
- }
-
- ret = 0;
- for (actual = 0; actual < len; actual += chunk_len) {
- chunk_len = min(len - actual, page_size - byte_addr);
-
- cmd[0] = CMD_M25PXX_PP;
- cmd[1] = page_addr >> 8;
- cmd[2] = page_addr;
- cmd[3] = byte_addr;
-
- debug
- ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
- buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
- ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0);
- if (ret < 0) {
- debug("SF: Enabling Write failed\n");
- break;
- }
-
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
- buf + actual, chunk_len);
- if (ret < 0) {
- debug("SF: STMicro Page Program failed\n");
- break;
- }
-
- ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
- if (ret)
- break;
-
- page_addr++;
- byte_addr = 0;
- }
-
- debug("SF: STMicro: Successfully programmed %u bytes @ 0x%x\n",
- len, offset);
-
- spi_release_bus(flash->spi);
- return ret;
-}
-
static int stmicro_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_M25PXX_SE, offset, len);
@@ -205,7 +121,7 @@ static int stmicro_erase(struct spi_flash *flash, u32 offset, size_t len)
struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
{
const struct stmicro_spi_flash_params *params;
- struct stmicro_spi_flash *stm;
+ struct spi_flash *flash;
unsigned int i;
if (idcode[0] == 0xff) {
@@ -233,21 +149,21 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
return NULL;
}
- stm = malloc(sizeof(struct stmicro_spi_flash));
- if (!stm) {
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- stm->params = params;
- stm->flash.spi = spi;
- stm->flash.name = params->name;
+ flash->spi = spi;
+ flash->name = params->name;
- stm->flash.write = stmicro_write;
- stm->flash.erase = stmicro_erase;
- stm->flash.read = spi_flash_cmd_read_fast;
- stm->flash.sector_size = params->page_size * params->pages_per_sector;
- stm->flash.size = stm->flash.sector_size * params->nr_sectors;
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = stmicro_erase;
+ flash->read = spi_flash_cmd_read_fast;
+ flash->page_size = params->page_size;
+ flash->sector_size = params->page_size * params->pages_per_sector;
+ flash->size = flash->sector_size * params->nr_sectors;
- return &stm->flash;
+ return flash;
}
diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c
index e8d30ae..45bd146 100644
--- a/drivers/mtd/spi/winbond.c
+++ b/drivers/mtd/spi/winbond.c
@@ -34,18 +34,6 @@ struct winbond_spi_flash_params {
const char *name;
};
-/* spi_flash needs to be first so upper layers can free() it */
-struct winbond_spi_flash {
- struct spi_flash flash;
- const struct winbond_spi_flash_params *params;
-};
-
-static inline struct winbond_spi_flash *
-to_winbond_spi_flash(struct spi_flash *flash)
-{
- return container_of(flash, struct winbond_spi_flash, flash);
-}
-
static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
{
.id = 0x3015,
@@ -105,71 +93,6 @@ static const struct winbond_spi_flash_params winbond_spi_flash_table[] = {
},
};
-static int winbond_write(struct spi_flash *flash,
- u32 offset, size_t len, const void *buf)
-{
- struct winbond_spi_flash *stm = to_winbond_spi_flash(flash);
- unsigned long page_addr;
- unsigned long byte_addr;
- unsigned long page_size;
- unsigned int page_shift;
- size_t chunk_len;
- size_t actual;
- int ret;
- u8 cmd[4];
-
- page_shift = stm->params->l2_page_size;
- page_size = (1 << page_shift);
- page_addr = offset / page_size;
- byte_addr = offset % page_size;
-
- ret = spi_claim_bus(flash->spi);
- if (ret) {
- debug("SF: Unable to claim SPI bus\n");
- return ret;
- }
-
- for (actual = 0; actual < len; actual += chunk_len) {
- chunk_len = min(len - actual, page_size - byte_addr);
-
- cmd[0] = CMD_W25_PP;
- cmd[1] = page_addr >> (16 - page_shift);
- cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
- cmd[3] = byte_addr;
- debug("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n",
- buf + actual,
- cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
-
- ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
- if (ret < 0) {
- debug("SF: Enabling Write failed\n");
- goto out;
- }
-
- ret = spi_flash_cmd_write(flash->spi, cmd, 4,
- buf + actual, chunk_len);
- if (ret < 0) {
- debug("SF: Winbond Page Program failed\n");
- goto out;
- }
-
- ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
- if (ret)
- goto out;
-
- page_addr++;
- byte_addr = 0;
- }
-
- debug("SF: Winbond: Successfully programmed %u bytes @ 0x%x\n",
- len, offset);
- ret = 0;
-
-out:
- spi_release_bus(flash->spi);
- return ret;
-}
-
static int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
{
return spi_flash_cmd_erase(flash, CMD_W25_SE, offset, len);
@@ -178,9 +101,9 @@ static int winbond_erase(struct spi_flash *flash, u32 offset, size_t len)
struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
{
const struct winbond_spi_flash_params *params;
- unsigned page_size;
- struct winbond_spi_flash *stm;
+ struct spi_flash *flash;
unsigned int i;
+ unsigned page_size;
for (i = 0; i < ARRAY_SIZE(winbond_spi_flash_table); i++) {
params = &winbond_spi_flash_table[i];
@@ -194,27 +117,26 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- stm = malloc(sizeof(struct winbond_spi_flash));
- if (!stm) {
+ flash = malloc(sizeof(*flash));
+ if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- stm->params = params;
- stm->flash.spi = spi;
- stm->flash.name = params->name;
+ flash->spi = spi;
+ flash->name = params->name;
/* Assuming power-of-two page size initially. */
page_size = 1 << params->l2_page_size;
- stm->flash.write = winbond_write;
- stm->flash.erase = winbond_erase;
- stm->flash.read = spi_flash_cmd_read_fast;
- stm->flash.sector_size = (1 << stm->params->l2_page_size) *
- stm->params->pages_per_sector;
- stm->flash.size = page_size * params->pages_per_sector
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = winbond_erase;
+ flash->read = spi_flash_cmd_read_fast;
+ flash->page_size = page_size;
+ flash->sector_size = page_size * params->pages_per_sector;
+ flash->size = page_size * params->pages_per_sector
* params->sectors_per_block
* params->nr_blocks;
- return &stm->flash;
+ return flash;
}
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index b1763b1..e616aaf 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -1704,7 +1704,7 @@ int enetInt (struct eth_device *dev)
rc = 0;
}
- /* handle MAL RX EOB interupt from a receive */
+ /* handle MAL RX EOB interrupt from a receive */
/* check for EOB on valid channels */
if (uic_mal & UIC_MAL_RXEOB) {
mal_eob = mfdcr(MAL0_RXEOBISR);
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 3f5eeb7..bfa4384 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -368,11 +368,13 @@ static int configure_phy(struct eth_device *dev)
{
struct dw_eth_dev *priv = dev->priv;
int phy_addr;
- u16 bmcr, ctrl;
+ u16 bmcr;
#if defined(CONFIG_DW_AUTONEG)
u16 bmsr;
u32 timeout;
u16 anlpar, btsr;
+#else
+ u16 ctrl;
#endif
#if defined(CONFIG_DW_SEARCH_PHY)
@@ -381,6 +383,8 @@ static int configure_phy(struct eth_device *dev)
priv->address = phy_addr;
else
return -1;
+#else
+ phy_addr = priv->address;
#endif
if (dw_reset_phy(dev) < 0)
return -1;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 4e4cd27..ab90afa 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -86,7 +86,7 @@ static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
/*
* wait for the related interrupt
*/
- start = get_timer_masked();
+ start = get_timer(0);
while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) {
if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
printf("Read MDIO failed...\n");
@@ -138,7 +138,7 @@ static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
/*
* wait for the MII interrupt
*/
- start = get_timer_masked();
+ start = get_timer(0);
while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) {
if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
printf("Write MDIO failed...\n");
@@ -189,7 +189,7 @@ static int miiphy_wait_aneg(struct eth_device *dev)
/*
* Wait for AN completion
*/
- start = get_timer_masked();
+ start = get_timer(0);
do {
if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
printf("%s: Autonegotiation timeout\n", dev->name);
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 6c32226..2aab52f 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -576,7 +576,7 @@ int greth_recv(struct eth_device *dev)
GRETH_REGORIN(&regs->control, GRETH_RXEN);
}
done:
- /* return positive length of packet or 0 if non recieved */
+ /* return positive length of packet or 0 if non received */
return len;
}
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 14b2d35..9386adf 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -282,7 +282,7 @@ OUTL(struct eth_device *dev, int command, u_long addr)
* ready to send and receive packets.
*
* Side effects:
- * leaves the natsemi initialized, and ready to recieve packets.
+ * leaves the natsemi initialized, and ready to receive packets.
*
* Returns: struct eth_device *: pointer to NIC data structure
*/
diff --git a/drivers/net/netarm_eth.c b/drivers/net/netarm_eth.c
index c9e324e..f54817e 100644
--- a/drivers/net/netarm_eth.c
+++ b/drivers/net/netarm_eth.c
@@ -81,9 +81,10 @@ static unsigned int na_mii_read (int reg)
static int na_mii_poll_busy (void)
{
+ ulong start;
/* arm simple, non interrupt dependent timer */
- reset_timer_masked ();
- while (get_timer_masked () < NA_MII_POLL_BUSY_DELAY) {
+ start = get_timer(0));
+ while (get_timer(start) < NA_MII_POLL_BUSY_DELAY) {
if (!(GET_EADDR (NETARM_ETH_MII_IND) & NETARM_ETH_MIII_BUSY)) {
return 1;
}
@@ -164,19 +165,20 @@ static unsigned int na_mii_check_speed (void)
static int reset_eth (void)
{
int pt;
+ ulong start;
na_get_mac_addr ();
pt = na_mii_identify_phy ();
/* reset the phy */
na_mii_write (MII_PHY_CONTROL, 0x8000);
- reset_timer_masked ();
- while (get_timer_masked () < NA_MII_NEGOTIATE_DELAY) {
+ start = get_timer(0);
+ while (get_timer(start) < NA_MII_NEGOTIATE_DELAY) {
if ((na_mii_read (MII_PHY_STATUS) & 0x8000) == 0) {
break;
}
}
- if (get_timer_masked () >= NA_MII_NEGOTIATE_DELAY)
+ if (get_timer(start) >= NA_MII_NEGOTIATE_DELAY)
printf ("phy reset timeout\n");
/* set the PCS reg */
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index 45402cc..6dfcd0e 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -299,7 +299,7 @@ OUTL(struct eth_device *dev, int command, u_long addr)
* Description: Retrieves the MAC address of the card, and sets up some
* globals required by other routines, and initializes the NIC, making it
* ready to send and receive packets.
- * Side effects: initializes ns8382xs, ready to recieve packets.
+ * Side effects: initializes ns8382xs, ready to receive packets.
* Returns: int: number of cards found
*/
diff --git a/drivers/net/phy/generic_10g.c b/drivers/net/phy/generic_10g.c
index 60dec45..e4a499d 100644
--- a/drivers/net/phy/generic_10g.c
+++ b/drivers/net/phy/generic_10g.c
@@ -36,7 +36,7 @@ int gen10g_shutdown(struct phy_device *phydev)
int gen10g_startup(struct phy_device *phydev)
{
int devad, reg;
- u32 mmd_mask = phydev->mmds;
+ u32 mmd_mask = phydev->mmds & MDIO_DEVS_LINK;
phydev->link = 1;
@@ -44,8 +44,12 @@ int gen10g_startup(struct phy_device *phydev)
phydev->speed = SPEED_10000;
phydev->duplex = DUPLEX_FULL;
+ /*
+ * Go through all the link-reporting devices, and make sure
+ * they're all up and happy
+ */
for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
- if (!mmd_mask & 1)
+ if (!(mmd_mask & 1))
continue;
/* Read twice because link state is latched and a
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 05e007c..8ce08a9 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -384,6 +384,7 @@ static inline void smc911x_reg_write(struct eth_device *dev,
#define WUCSR_MPEN 0x00000002
/* Chip ID values */
+#define CHIP_89218 0x218a
#define CHIP_9115 0x115
#define CHIP_9116 0x116
#define CHIP_9117 0x117
@@ -402,6 +403,7 @@ struct chip_id {
};
static const struct chip_id chip_ids[] = {
+ { CHIP_89218, "LAN89218" },
{ CHIP_9115, "LAN9115" },
{ CHIP_9116, "LAN9116" },
{ CHIP_9117, "LAN9117" },
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index ab461b4..7f601d4 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -316,7 +316,7 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info)
hose->current_busno = hose->first_busno;
out_be32(&pci->pedr, 0xffffffff); /* Clear any errors */
- out_be32(&pci->peer, ~0x20140); /* Enable All Error Interupts except
+ out_be32(&pci->peer, ~0x20140); /* Enable All Error Interrupts except
* - Master abort (pci)
* - Master PERR (pci)
* - ICCA (PCIe)
diff --git a/drivers/rtc/mpc5xxx.c b/drivers/rtc/mpc5xxx.c
index ec0b0ef..6b3d5e6 100644
--- a/drivers/rtc/mpc5xxx.c
+++ b/drivers/rtc/mpc5xxx.c
@@ -44,7 +44,7 @@ typedef struct rtc5200 {
volatile ulong aier; /* MBAR+0x80C: alarm and interrupt enable register */
volatile ulong ctr; /* MBAR+0x810: current time register */
volatile ulong cdr; /* MBAR+0x814: current data register */
- volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interupt register */
+ volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interrupt register */
volatile ulong piber; /* MBAR+0x81C: periodic interrupt and bus error register */
volatile ulong trdr; /* MBAR+0x820: test register/divides register */
} RTC5200;
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 0e171b6..1dcc1c7 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -55,7 +55,10 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
COBJS-$(CONFIG_TEGRA2) += serial_tegra2.o
+
+ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_USB_TTY) += usbtty.o
+endif
COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 4032dfd..0d56e78 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -22,6 +22,7 @@
*/
#include <common.h>
+#include <linux/compiler.h>
#include <ns16550.h>
#ifdef CONFIG_NS87308
@@ -117,9 +118,8 @@ static NS16550_t serial_ports[4] = {
serial_puts_dev(port, s);}
/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port,name,bus) {\
+#define INIT_ESERIAL_STRUCTURE(port, name) {\
name,\
- bus,\
eserial##port##_init,\
NULL,\
eserial##port##_setbrg,\
@@ -325,14 +325,30 @@ serial_setbrg(void)
DECLARE_ESERIAL_FUNCTIONS(1);
struct serial_device eserial1_device =
- INIT_ESERIAL_STRUCTURE(1,"eserial0","EUART1");
+ INIT_ESERIAL_STRUCTURE(1, "eserial0");
DECLARE_ESERIAL_FUNCTIONS(2);
struct serial_device eserial2_device =
- INIT_ESERIAL_STRUCTURE(2,"eserial1","EUART2");
+ INIT_ESERIAL_STRUCTURE(2, "eserial1");
DECLARE_ESERIAL_FUNCTIONS(3);
struct serial_device eserial3_device =
- INIT_ESERIAL_STRUCTURE(3,"eserial2","EUART3");
+ INIT_ESERIAL_STRUCTURE(3, "eserial2");
DECLARE_ESERIAL_FUNCTIONS(4);
struct serial_device eserial4_device =
- INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4");
+ INIT_ESERIAL_STRUCTURE(4, "eserial3");
+
+__weak struct serial_device *default_serial_console(void)
+{
+#if CONFIG_CONS_INDEX == 1
+ return &eserial1_device;
+#elif CONFIG_CONS_INDEX == 2
+ return &eserial2_device;
+#elif CONFIG_CONS_INDEX == 3
+ return &eserial3_device;
+#elif CONFIG_CONS_INDEX == 4
+ return &eserial4_device;
+#else
+#error "Bad CONFIG_CONS_INDEX."
+#endif
+}
+
#endif /* CONFIG_SERIAL_MULTI */
diff --git a/drivers/serial/serial_pxa.c b/drivers/serial/serial_pxa.c
index e457980..68469a4 100644
--- a/drivers/serial/serial_pxa.c
+++ b/drivers/serial/serial_pxa.c
@@ -268,7 +268,6 @@ static int ffuart_tstc(void)
struct serial_device serial_ffuart_device =
{
"serial_ffuart",
- "PXA",
ffuart_init,
NULL,
ffuart_setbrg,
@@ -313,7 +312,6 @@ static int btuart_tstc(void)
struct serial_device serial_btuart_device =
{
"serial_btuart",
- "PXA",
btuart_init,
NULL,
btuart_setbrg,
@@ -358,7 +356,6 @@ static int stuart_tstc(void)
struct serial_device serial_stuart_device =
{
"serial_stuart",
- "PXA",
stuart_init,
NULL,
stuart_setbrg,
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index abdbff1..12bcdd3 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -19,6 +19,7 @@
*/
#include <common.h>
+#include <linux/compiler.h>
#include <asm/arch/s3c24x0_cpu.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -68,9 +69,8 @@ DECLARE_GLOBAL_DATA_PTR;
serial_puts_dev(port, s); \
}
-#define INIT_S3C_SERIAL_STRUCTURE(port, name, bus) { \
+#define INIT_S3C_SERIAL_STRUCTURE(port, name) { \
name, \
- bus, \
s3serial##port##_init, \
NULL,\
s3serial##port##_setbrg, \
@@ -303,11 +303,24 @@ void serial_puts(const char *s)
#if defined(CONFIG_SERIAL_MULTI)
DECLARE_S3C_SERIAL_FUNCTIONS(0);
struct serial_device s3c24xx_serial0_device =
-INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0", "S3UART1");
+INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0");
DECLARE_S3C_SERIAL_FUNCTIONS(1);
struct serial_device s3c24xx_serial1_device =
-INIT_S3C_SERIAL_STRUCTURE(1, "s3ser1", "S3UART2");
+INIT_S3C_SERIAL_STRUCTURE(1, "s3ser1");
DECLARE_S3C_SERIAL_FUNCTIONS(2);
struct serial_device s3c24xx_serial2_device =
-INIT_S3C_SERIAL_STRUCTURE(2, "s3ser2", "S3UART3");
+INIT_S3C_SERIAL_STRUCTURE(2, "s3ser2");
+
+__weak struct serial_device *default_serial_console(void)
+{
+#if defined(CONFIG_SERIAL1)
+ return &s3c24xx_serial0_device;
+#elif defined(CONFIG_SERIAL2)
+ return &s3c24xx_serial1_device;
+#elif defined(CONFIG_SERIAL3)
+ return &s3c24xx_serial2_device;
+#else
+#error "CONFIG_SERIAL? missing."
+#endif
+}
#endif /* CONFIG_SERIAL_MULTI */
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index f1ffa29..6819bb0 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -22,6 +22,7 @@
*/
#include <common.h>
+#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/arch/uart.h>
#include <asm/arch/clk.h>
@@ -182,9 +183,8 @@ int s5p_serial##port##_tstc(void) { return serial_tstc_dev(port); } \
void s5p_serial##port##_putc(const char c) { serial_putc_dev(c, port); } \
void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); }
-#define INIT_S5P_SERIAL_STRUCTURE(port, name, bus) { \
+#define INIT_S5P_SERIAL_STRUCTURE(port, name) { \
name, \
- bus, \
s5p_serial##port##_init, \
NULL, \
s5p_serial##port##_setbrg, \
@@ -195,13 +195,28 @@ void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); }
DECLARE_S5P_SERIAL_FUNCTIONS(0);
struct serial_device s5p_serial0_device =
- INIT_S5P_SERIAL_STRUCTURE(0, "s5pser0", "S5PUART0");
+ INIT_S5P_SERIAL_STRUCTURE(0, "s5pser0");
DECLARE_S5P_SERIAL_FUNCTIONS(1);
struct serial_device s5p_serial1_device =
- INIT_S5P_SERIAL_STRUCTURE(1, "s5pser1", "S5PUART1");
+ INIT_S5P_SERIAL_STRUCTURE(1, "s5pser1");
DECLARE_S5P_SERIAL_FUNCTIONS(2);
struct serial_device s5p_serial2_device =
- INIT_S5P_SERIAL_STRUCTURE(2, "s5pser2", "S5PUART2");
+ INIT_S5P_SERIAL_STRUCTURE(2, "s5pser2");
DECLARE_S5P_SERIAL_FUNCTIONS(3);
struct serial_device s5p_serial3_device =
- INIT_S5P_SERIAL_STRUCTURE(3, "s5pser3", "S5PUART3");
+ INIT_S5P_SERIAL_STRUCTURE(3, "s5pser3");
+
+__weak struct serial_device *default_serial_console(void)
+{
+#if defined(CONFIG_SERIAL0)
+ return &s5p_serial0_device;
+#elif defined(CONFIG_SERIAL1)
+ return &s5p_serial1_device;
+#elif defined(CONFIG_SERIAL2)
+ return &s5p_serial2_device;
+#elif defined(CONFIG_SERIAL3)
+ return &s5p_serial3_device;
+#else
+#error "CONFIG_SERIAL? missing."
+#endif
+}
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a9b1ca4..96c9642 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libspi.o
COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o
+COBJS-$(CONFIG_ANDES_SPI) += andes_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
diff --git a/drivers/spi/andes_spi.c b/drivers/spi/andes_spi.c
new file mode 100644
index 0000000..fdde139
--- /dev/null
+++ b/drivers/spi/andes_spi.c
@@ -0,0 +1,302 @@
+/*
+ * Driver of Andes SPI Controller
+ *
+ * (C) Copyright 2011 Andes Technology
+ * Macpaul Lin <macpaul@andestech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+#include <asm/io.h>
+#include "andes_spi.h"
+
+void spi_init(void)
+{
+ /* do nothing */
+}
+
+static void andes_spi_spit_en(struct andes_spi_slave *ds)
+{
+ unsigned int dcr = readl(&ds->regs->dcr);
+
+ debug("%s: dcr: %x, write value: %x\n",
+ __func__, dcr, (dcr | ANDES_SPI_DCR_SPIT));
+
+ writel((dcr | ANDES_SPI_DCR_SPIT), &ds->regs->dcr);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct andes_spi_slave *ds;
+
+ if (!spi_cs_is_valid(bus, cs))
+ return NULL;
+
+ ds = malloc(sizeof(*ds));
+ if (!ds)
+ return NULL;
+
+ ds->slave.bus = bus;
+ ds->slave.cs = cs;
+ ds->regs = (struct andes_spi_regs *)CONFIG_SYS_SPI_BASE;
+
+ /*
+ * The hardware of andes_spi will set its frequency according
+ * to APB/AHB bus clock. Hence the hardware doesn't allow changing of
+ * requency and so the user requested speed is always ignored.
+ */
+ ds->freq = max_hz;
+
+ return &ds->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct andes_spi_slave *ds = to_andes_spi(slave);
+
+ free(ds);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ struct andes_spi_slave *ds = to_andes_spi(slave);
+ unsigned int apb;
+ unsigned int baud;
+
+ /* Enable the SPI hardware */
+ writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr);
+ udelay(1000);
+
+ /* setup format */
+ baud = ((CONFIG_SYS_CLK_FREQ / CONFIG_SYS_SPI_CLK / 2) - 1) & 0xFF;
+
+ /*
+ * SPI_CLK = AHB bus clock / ((BAUD + 1)*2)
+ * BAUD = AHB bus clock / SPI_CLK / 2) - 1
+ */
+ apb = (readl(&ds->regs->apb) & 0xffffff00) | baud;
+ writel(apb, &ds->regs->apb);
+
+ /* no interrupts */
+ writel(0, &ds->regs->ie);
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ struct andes_spi_slave *ds = to_andes_spi(slave);
+
+ /* Disable the SPI hardware */
+ writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr);
+}
+
+static int andes_spi_read(struct spi_slave *slave, unsigned int len,
+ u8 *rxp, unsigned long flags)
+{
+ struct andes_spi_slave *ds = to_andes_spi(slave);
+ unsigned int i, left;
+ unsigned int data;
+
+ debug("%s: slave: %x, len: %d, rxp: %x, flags: %d\n",
+ __func__, slave, len, rxp, flags);
+
+ debug("%s: data: ", __func__);
+ while (len > 0) {
+ left = min(len, 4);
+ data = readl(&ds->regs->data);
+
+ debug(" ");
+ for (i = 0; i < left; i++) {
+ debug("%02x ", data & 0xff);
+ *rxp++ = data;
+ data >>= 8;
+ len--;
+ }
+ }
+ debug("\n");
+
+ return 0;
+}
+
+static int andes_spi_write(struct spi_slave *slave, unsigned int wlen,
+ unsigned int rlen, const u8 *txp, unsigned long flags)
+{
+ struct andes_spi_slave *ds = to_andes_spi(slave);
+ unsigned int data;
+ unsigned int i, left;
+ unsigned int spit_enabled = 0;
+
+ debug("%s: slave: %x, wlen: %d, rlen: %d, txp: %x, flags: %x\n",
+ __func__, slave, wlen, rlen, txp, flags);
+
+ /* The value of wlen and rlen wrote to register must minus 1 */
+ if (rlen == 0) /* write only */
+ writel(ANDES_SPI_DCR_MODE_WO | ANDES_SPI_DCR_WCNT(wlen-1) |
+ ANDES_SPI_DCR_RCNT(0), &ds->regs->dcr);
+ else /* write then read */
+ writel(ANDES_SPI_DCR_MODE_WR | ANDES_SPI_DCR_WCNT(wlen-1) |
+ ANDES_SPI_DCR_RCNT(rlen-1), &ds->regs->dcr);
+
+ /* wait till SPIBSY is cleared */
+ while (readl(&ds->regs->st) & ANDES_SPI_ST_SPIBSY)
+ ;
+
+ /* data write process */
+ debug("%s: txp: ", __func__);
+ while (wlen > 0) {
+ /* clear the data */
+ data = 0;
+
+ /* data are usually be read 32bits once a time */
+ left = min(wlen, 4);
+
+ for (i = 0; i < left; i++) {
+ debug("%x ", *txp);
+ data |= *txp++ << (i * 8);
+ wlen--;
+ }
+ debug("\n");
+
+ debug("data: %08x\n", data);
+ debug("streg before write: %08x\n", readl(&ds->regs->st));
+ /* wait till TXFULL is deasserted */
+ while (readl(&ds->regs->st) & ANDES_SPI_ST_TXFEL)
+ ;
+ writel(data, &ds->regs->data);
+ debug("streg after write: %08x\n", readl(&ds->regs->st));
+
+
+ if (spit_enabled == 0) {
+ /* enable SPIT bit - trigger the tx and rx progress */
+ andes_spi_spit_en(ds);
+ spit_enabled = 1;
+ }
+
+ }
+ debug("\n");
+
+ return 0;
+}
+
+/*
+ * spi_xfer:
+ * Since andes_spi doesn't support independent command transaction,
+ * that is, write and than read must be operated in continuous
+ * execution, there is no need to set dcr and trigger spit again in
+ * RX process.
+ */
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ unsigned int len;
+ static int op_nextime;
+ static u8 tmp_cmd[5];
+ static int tmp_wlen;
+ unsigned int i;
+
+ if (bitlen == 0)
+ /* Finish any previously submitted transfers */
+ goto out;
+
+ if (bitlen % 8) {
+ /* Errors always terminate an ongoing transfer */
+ flags |= SPI_XFER_END;
+ goto out;
+ }
+
+ len = bitlen / 8;
+
+ debug("%s: slave: %08x, bitlen: %d, dout: "
+ "%08x, din: %08x, flags: %d, len: %d\n",
+ __func__, slave, bitlen, dout, din, flags, len);
+
+ /*
+ * Important:
+ * andes_spi's hardware doesn't support 2 data channel. The read
+ * and write cmd/data share the same register (data register).
+ *
+ * If a command has write and read transaction, you cannot do write
+ * this time and then do read on next time.
+ *
+ * A command writes first with a read response must indicating
+ * the read length in write operation. Hence the write action must
+ * be stored temporary and wait until the next read action has been
+ * arrived. Then we flush the write and read action out together.
+ */
+ if (!dout) {
+ if (op_nextime == 1) {
+ /* flags should be SPI_XFER_END, value is 2 */
+ op_nextime = 0;
+ andes_spi_write(slave, tmp_wlen, len, tmp_cmd, flags);
+ }
+ return andes_spi_read(slave, len, din, flags);
+ } else if (!din) {
+ if (flags == SPI_XFER_BEGIN) {
+ /* store the write command and do operation next time */
+ op_nextime = 1;
+ memset(tmp_cmd, 0, sizeof(tmp_cmd));
+ memcpy(tmp_cmd, dout, len);
+
+ debug("%s: tmp_cmd: ", __func__);
+ for (i = 0; i < len; i++)
+ debug("%x ", *(tmp_cmd + i));
+ debug("\n");
+
+ tmp_wlen = len;
+ } else {
+ /*
+ * flags should be (SPI_XFER_BEGIN | SPI_XFER_END),
+ * the value is 3.
+ */
+ if (op_nextime == 1) {
+ /* flags should be SPI_XFER_END, value is 2 */
+ op_nextime = 0;
+ /* flags 3 implies write only */
+ andes_spi_write(slave, tmp_wlen, 0, tmp_cmd, 3);
+ }
+
+ debug("flags: %x\n", flags);
+ return andes_spi_write(slave, len, 0, dout, flags);
+ }
+ }
+
+out:
+ return 0;
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus == 0 && cs == 0;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ /* do nothing */
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ /* do nothing */
+}
diff --git a/drivers/spi/andes_spi.h b/drivers/spi/andes_spi.h
new file mode 100644
index 0000000..844bdba
--- /dev/null
+++ b/drivers/spi/andes_spi.h
@@ -0,0 +1,128 @@
+/*
+ * Register definitions for the Andes SPI Controller
+ *
+ * (C) Copyright 2011 Andes Technology
+ * Macpaul Lin <macpaul@andestech.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ANDES_SPI_H
+#define __ANDES_SPI_H
+
+struct andes_spi_regs {
+ unsigned int apb; /* 0x00 - APB SPI interface setting */
+ unsigned int pio; /* 0x04 - PIO reg */
+ unsigned int cr; /* 0x08 - SPI Control reg */
+ unsigned int st; /* 0x0c - SPI Status reg */
+ unsigned int ie; /* 0x10 - Interrupt Enable reg */
+ unsigned int ist; /* 0x14 - Interrupt Status reg */
+ unsigned int dcr; /* 0x18 - data control reg */
+ unsigned int data; /* 0x1c - data register */
+ unsigned int ahb; /* 0x20 - AHB SPI interface setting */
+ unsigned int ver; /* 0x3c - SPI version reg */
+};
+
+#define BIT(x) (1 << (x))
+
+/* 0x00 - APB SPI interface setting register */
+#define ANDES_SPI_APB_BAUD(x) (((x) & 0xff) < 0)
+#define ANDES_SPI_APB_CSHT(x) (((x) & 0xf) < 16)
+#define ANDES_SPI_APB_SPNTS BIT(20) /* 0: normal, 1: delay */
+#define ANDES_SPI_APB_CPHA BIT(24) /* 0: Sampling at odd edges */
+#define ANDES_SPI_APB_CPOL BIT(25) /* 0: SCK low, 1: SCK high */
+#define ANDES_SPI_APB_MSSL BIT(26) /* 0: SPI Master, 1: slave */
+
+/* 0x04 - PIO register */
+#define ANDES_SPI_PIO_MISO BIT(0) /* input value of pin MISO */
+#define ANDES_SPI_PIO_MOSI BIT(1) /* I/O value of pin MOSI */
+#define ANDES_SPI_PIO_SCK BIT(2) /* I/O value of pin SCK */
+#define ANDES_SPI_PIO_CS BIT(3) /* I/O value of pin CS */
+#define ANDES_SPI_PIO_PIOE BIT(4) /* Programming IO Enable */
+
+/* 0x08 - SPI Control register */
+#define ANDES_SPI_CR_SPIRST BIT(0) /* SPI mode reset */
+#define ANDES_SPI_CR_RXFRST BIT(1) /* RxFIFO reset */
+#define ANDES_SPI_CR_TXFRST BIT(2) /* TxFIFO reset */
+#define ANDES_SPI_CR_RXFTH(x) (((x) & 0x1f) << 10) /* RxFIFO Threshold */
+#define ANDES_SPI_CR_TXFTH(x) (((x) & 0x1f) << 18) /* TxFIFO Threshold */
+
+/* 0x0c - SPI Status register */
+#define ANDES_SPI_ST_SPIBSY BIT(0) /* SPI Transfer is active */
+#define ANDES_SPI_ST_RXFEM BIT(8) /* RxFIFO Empty Flag */
+#define ANDES_SPI_ST_RXFEL BIT(9) /* RxFIFO Full Flag */
+#define ANDES_SPI_ST_RXFVE(x) (((x) >> 10) & 0x1f)
+#define ANDES_SPI_ST_TXFEM BIT(16) /* TxFIFO Empty Flag */
+#define ANDES_SPI_ST_TXFEL BIT(7) /* TxFIFO Full Flag */
+#define ANDES_SPI_ST_TXFVE(x) (((x) >> 18) & 0x1f)
+
+/* 0x10 - Interrupt Enable register */
+#define ANDES_SPI_IE_RXFORIE BIT(0) /* RxFIFO overrun intr */
+#define ANDES_SPI_IE_TXFURIE BIT(1) /* TxFOFO underrun intr */
+#define ANDES_SPI_IE_RXFTHIE BIT(2) /* RxFIFO threshold intr */
+#define ANDES_SPI_IE_TXFTHIE BIT(3) /* TxFIFO threshold intr */
+#define ANDES_SPI_IE_SPIEIE BIT(4) /* SPI transmit END intr */
+#define ANDES_SPI_IE_SPCFIE BIT(5) /* AHB/APB TxReq conflict */
+
+/* 0x14 - Interrupt Status Register */
+#define ANDES_SPI_IST_RXFORI BIT(0) /* has RxFIFO overrun */
+#define ANDES_SPI_IST_TXFURI BIT(1) /* has TxFOFO underrun */
+#define ANDES_SPI_IST_RXFTHI BIT(2) /* has RxFIFO threshold */
+#define ANDES_SPI_IST_TXFTHI BIT(3) /* has TxFIFO threshold */
+#define ANDES_SPI_IST_SPIEI BIT(4) /* has SPI transmit END */
+#define ANDES_SPI_IST_SPCFI BIT(5) /* has AHB/APB TxReq conflict */
+
+/* 0x18 - Data Control Register */
+#define ANDES_SPI_DCR_RCNT(x) (((x) & 0x3ff) << 0)
+#define ANDES_SPI_DCR_DYCNT(x) (((x) & 0x7) << 12)
+#define ANDES_SPI_DCR_WCNT(x) (((x) & 0x3ff) << 16)
+#define ANDES_SPI_DCR_TRAMODE(x) (((x) & 0x7) << 28)
+#define ANDES_SPI_DCR_SPIT BIT(31) /* SPI bus trigger */
+
+#define ANDES_SPI_DCR_MODE_WRCON ANDES_SPI_DCR_TRAMODE(0) /* w/r at the same time */
+#define ANDES_SPI_DCR_MODE_WO ANDES_SPI_DCR_TRAMODE(1) /* write only */
+#define ANDES_SPI_DCR_MODE_RO ANDES_SPI_DCR_TRAMODE(2) /* read only */
+#define ANDES_SPI_DCR_MODE_WR ANDES_SPI_DCR_TRAMODE(3) /* write, read */
+#define ANDES_SPI_DCR_MODE_RW ANDES_SPI_DCR_TRAMODE(4) /* read, write */
+#define ANDES_SPI_DCR_MODE_WDR ANDES_SPI_DCR_TRAMODE(5) /* write, dummy, read */
+#define ANDES_SPI_DCR_MODE_RDW ANDES_SPI_DCR_TRAMODE(6) /* read, dummy, write */
+#define ANDES_SPI_DCR_MODE_RECEIVE ANDES_SPI_DCR_TRAMODE(7) /* receive */
+
+/* 0x20 - AHB SPI interface setting register */
+#define ANDES_SPI_AHB_BAUD(x) (((x) & 0xff) < 0)
+#define ANDES_SPI_AHB_CSHT(x) (((x) & 0xf) < 16)
+#define ANDES_SPI_AHB_SPNTS BIT(20) /* 0: normal, 1: delay */
+#define ANDES_SPI_AHB_CPHA BIT(24) /* 0: Sampling at odd edges */
+#define ANDES_SPI_AHB_CPOL BIT(25) /* 0: SCK low, 1: SCK high */
+#define ANDES_SPI_AHB_MSSL BIT(26) /* only Master mode */
+
+/* 0x3c - Version Register - (Year V.MAJOR.MINOR) */
+#define ANDES_SPI_VER_MINOR(x) (((x) >> 0) & 0xf)
+#define ANDES_SPI_VER_MAJOR(x) (((x) >> 8) & 0xf)
+#define ANDES_SPI_VER_YEAR(x) (((x) >> 16) & 0xf)
+
+struct andes_spi_slave {
+ struct spi_slave slave;
+ struct andes_spi_regs *regs;
+ unsigned int freq;
+};
+
+static inline struct andes_spi_slave *to_andes_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct andes_spi_slave, slave);
+}
+
+#endif /* __ANDES_SPI_H */
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index 698e726..81381d9 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -60,8 +60,6 @@ static unsigned long spi_bases[] = {
0x53f84000,
};
-#define mxc_get_clock(x) mx31_get_ipg_clk()
-
#elif defined(CONFIG_MX51)
#define MXC_CSPICTRL_EN (1 << 0)
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 6af35ab..a0cfbb7 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -29,6 +29,14 @@
#define USBCTRL_OTGBASE_OFFSET 0x600
+#ifdef CONFIG_MX25
+#define MX25_USB_CTRL_IP_PUE_DOWN_BIT (1<<6)
+#define MX25_USB_CTRL_HSTD_BIT (1<<5)
+#define MX25_USB_CTRL_USBTE_BIT (1<<4)
+#define MX25_USB_CTRL_OCPOL_OTG_BIT (1<<3)
+#endif
+
+#ifdef CONFIG_MX31
#define MX31_OTG_SIC_SHIFT 29
#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
#define MX31_OTG_PM_BIT (1 << 24)
@@ -42,12 +50,19 @@
#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT)
#define MX31_H1_PM_BIT (1 << 8)
#define MX31_H1_DT_BIT (1 << 4)
+#endif
static int mxc_set_usbcontrol(int port, unsigned int flags)
{
unsigned int v;
+
+#ifdef CONFIG_MX25
+ v = MX25_USB_CTRL_IP_PUE_DOWN_BIT | MX25_USB_CTRL_HSTD_BIT |
+ MX25_USB_CTRL_USBTE_BIT | MX25_USB_CTRL_OCPOL_OTG_BIT;
+#endif
+
#ifdef CONFIG_MX31
- v = readl(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET);
+ v = readl(IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET);
switch (port) {
case 0: /* OTG port */
@@ -85,36 +100,38 @@ static int mxc_set_usbcontrol(int port, unsigned int flags)
default:
return -EINVAL;
}
-
- writel(v, MX31_OTG_BASE_ADDR +
- USBCTRL_OTGBASE_OFFSET);
#endif
- return 0;
+
+ writel(v, IMX_USB_BASE + USBCTRL_OTGBASE_OFFSET);
+ return 0;
}
int ehci_hcd_init(void)
{
- u32 tmp;
struct usb_ehci *ehci;
+#ifdef CONFIG_MX31
+ u32 tmp;
struct clock_control_regs *sc_regs =
(struct clock_control_regs *)CCM_BASE;
tmp = __raw_readl(&sc_regs->ccmr);
__raw_writel(__raw_readl(&sc_regs->ccmr) | (1 << 9), &sc_regs->ccmr) ;
+#endif
udelay(80);
/* Take USB2 */
- ehci = (struct usb_ehci *)(MX31_OTG_BASE_ADDR +
+ ehci = (struct usb_ehci *)(IMX_USB_BASE +
(0x200 * CONFIG_MXC_USB_PORT));
hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
hcor = (struct ehci_hcor *)((uint32_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
setbits_le32(&ehci->usbmode, CM_HOST);
+#ifdef CONFIG_MX31
setbits_le32(&ehci->control, USB_EN);
__raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
-
+#endif
mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS);
udelay(10000);
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index b427c84..3a93b64 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -29,75 +29,83 @@
* At the moment only the 8x16 font is tested and the font fore- and
* background color is limited to black/white/gray colors. The Linux
* logo can be placed in the upper left corner and additional board
- * information strings (that normaly goes to serial port) can be drawed.
+ * information strings (that normally goes to serial port) can be drawn.
*
* The console driver can use the standard PC keyboard interface (i8042)
* for character input. Character output goes to a memory mapped video
* framebuffer with little or big-endian organisation.
* With environment setting 'console=serial' the console i/o can be
* forced to serial port.
-
- The driver uses graphic specific defines/parameters/functions:
-
- (for SMI LynxE graphic chip)
-
- CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
- VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian
- VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill
- VIDEO_HW_BITBLT - graphic driver supports hardware bit blt
-
- Console Parameters are set by graphic drivers global struct:
-
- VIDEO_VISIBLE_COLS - x resolution
- VIDEO_VISIBLE_ROWS - y resolution
- VIDEO_PIXEL_SIZE - storage size in byte per pixel
- VIDEO_DATA_FORMAT - graphical data format GDF
- VIDEO_FB_ADRS - start of video memory
-
- CONFIG_I8042_KBD - AT Keyboard driver for i8042
- VIDEO_KBD_INIT_FCT - init function for keyboard
- VIDEO_TSTC_FCT - keyboard_tstc function
- VIDEO_GETC_FCT - keyboard_getc function
-
- CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay
- loop in VIDEO_TSTC_FCT (i8042)
- CONFIG_SYS_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
- CONFIG_CONSOLE_TIME - display time/date in upper right corner,
- needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR
- CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner
- CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo
- CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings
- that normaly goes to serial port. This define
- requires a board specific function:
- video_drawstring (VIDEO_INFO_X,
- VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
- info);
- that fills a info buffer at i=row.
- s.a: board/eltec/bab7xx.
-CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised
- as an output only device. The Keyboard driver
- will not be set-up. This may be used, if you
- have none or more than one Keyboard devices
- (USB Keyboard, AT Keyboard).
-
-CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No
- blinking is provided. Uses the macros CURSOR_SET
- and CURSOR_OFF.
-CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
- graphic chip. Uses the macro CURSOR_SET.
- ATTENTION: If booting an OS, the display driver
- must disable the hardware register of the graphic
- chip. Otherwise a blinking field is displayed
-*/
+ *
+ * The driver uses graphic specific defines/parameters/functions:
+ *
+ * (for SMI LynxE graphic chip)
+ *
+ * CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
+ * VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian
+ * VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill
+ * VIDEO_HW_BITBLT - graphic driver supports hardware bit blt
+ *
+ * Console Parameters are set by graphic drivers global struct:
+ *
+ * VIDEO_VISIBLE_COLS - x resolution
+ * VIDEO_VISIBLE_ROWS - y resolution
+ * VIDEO_PIXEL_SIZE - storage size in byte per pixel
+ * VIDEO_DATA_FORMAT - graphical data format GDF
+ * VIDEO_FB_ADRS - start of video memory
+ *
+ * CONFIG_I8042_KBD - AT Keyboard driver for i8042
+ * VIDEO_KBD_INIT_FCT - init function for keyboard
+ * VIDEO_TSTC_FCT - keyboard_tstc function
+ * VIDEO_GETC_FCT - keyboard_getc function
+ *
+ * CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with
+ * delay loop in VIDEO_TSTC_FCT (i8042)
+ *
+ * CONFIG_SYS_CONSOLE_BLINK_COUNT - value for delay loop - blink rate
+ * CONFIG_CONSOLE_TIME - display time/date in upper right
+ * corner, needs CONFIG_CMD_DATE and
+ * CONFIG_CONSOLE_CURSOR
+ * CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner
+ * CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo
+ * CONFIG_CONSOLE_EXTRA_INFO - display additional board information
+ * strings that normaly goes to serial
+ * port. This define requires a board
+ * specific function:
+ * video_drawstring (VIDEO_INFO_X,
+ * VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
+ * info);
+ * that fills a info buffer at i=row.
+ * s.a: board/eltec/bab7xx.
+ * CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be
+ * initialized as an output only device.
+ * The Keyboard driver will not be
+ * set-up. This may be used, if you have
+ * no or more than one Keyboard devices
+ * (USB Keyboard, AT Keyboard).
+ *
+ * CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last
+ * character. No blinking is provided.
+ * Uses the macros CURSOR_SET and
+ * CURSOR_OFF.
+ *
+ * CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability
+ * of the graphic chip. Uses the macro
+ * CURSOR_SET. ATTENTION: If booting an
+ * OS, the display driver must disable
+ * the hardware register of the graphic
+ * chip. Otherwise a blinking field is
+ * displayed.
+ */
#include <common.h>
-
+#include <version.h>
#include <malloc.h>
-/*****************************************************************************/
-/* Console device defines with SMI graphic */
-/* Any other graphic must change this section */
-/*****************************************************************************/
+/*
+ * Console device defines with SMI graphic
+ * Any other graphic must change this section
+ */
#ifdef CONFIG_VIDEO_SMI_LYNXEM
@@ -106,9 +114,9 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#define VIDEO_HW_BITBLT
#endif
-/*****************************************************************************/
-/* Defines for the CT69000 driver */
-/*****************************************************************************/
+/*
+ * Defines for the CT69000 driver
+ */
#ifdef CONFIG_VIDEO_CT69000
#define VIDEO_FB_LITTLE_ENDIAN
@@ -116,9 +124,9 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#define VIDEO_HW_BITBLT
#endif
-/*****************************************************************************/
-/* Defines for the SED13806 driver */
-/*****************************************************************************/
+/*
+ * Defines for the SED13806 driver
+ */
#ifdef CONFIG_VIDEO_SED13806
#ifndef CONFIG_TOTAL5200
@@ -128,9 +136,9 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#define VIDEO_HW_BITBLT
#endif
-/*****************************************************************************/
-/* Defines for the SED13806 driver */
-/*****************************************************************************/
+/*
+ * Defines for the SED13806 driver
+ */
#ifdef CONFIG_VIDEO_SM501
#ifdef CONFIG_HH405
@@ -138,9 +146,9 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#endif
#endif
-/*****************************************************************************/
-/* Defines for the MB862xx driver */
-/*****************************************************************************/
+/*
+ * Defines for the MB862xx driver
+ */
#ifdef CONFIG_VIDEO_MB862xx
#ifdef CONFIG_VIDEO_CORALP
@@ -152,24 +160,24 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#endif
#endif
-/*****************************************************************************/
-/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */
-/*****************************************************************************/
+/*
+ * Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc.
+ */
#include <video_fb.h>
-/*****************************************************************************/
-/* some Macros */
-/*****************************************************************************/
+/*
+ * some Macros
+ */
#define VIDEO_VISIBLE_COLS (pGD->winSizeX)
#define VIDEO_VISIBLE_ROWS (pGD->winSizeY)
#define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP)
#define VIDEO_DATA_FORMAT (pGD->gdfIndex)
#define VIDEO_FB_ADRS (pGD->frameAdrs)
-/*****************************************************************************/
-/* Console device defines with i8042 keyboard controller */
-/* Any other keyboard controller must change this section */
-/*****************************************************************************/
+/*
+ * Console device defines with i8042 keyboard controller
+ * Any other keyboard controller must change this section
+ */
#ifdef CONFIG_I8042_KBD
#include <i8042.h>
@@ -179,9 +187,9 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#define VIDEO_GETC_FCT i8042_getc
#endif
-/*****************************************************************************/
-/* Console device */
-/*****************************************************************************/
+/*
+ * Console device
+ */
#include <version.h>
#include <linux/types.h>
@@ -202,20 +210,20 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#endif
-/*****************************************************************************/
-/* Cursor definition: */
-/* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/input/i8042.c) */
-/* to let the cursor blink. Uses the macros */
-/* CURSOR_OFF and CURSOR_ON. */
-/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */
-/* blinking is provided. Uses the macros CURSOR_SET */
-/* and CURSOR_OFF. */
-/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */
-/* graphic chip. Uses the macro CURSOR_SET. */
-/* ATTENTION: If booting an OS, the display driver */
-/* must disable the hardware register of the graphic */
-/* chip. Otherwise a blinking field is displayed */
-/*****************************************************************************/
+/*
+ * Cursor definition:
+ * CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/input/i8042.c)
+ * to let the cursor blink. Uses the macros
+ * CURSOR_OFF and CURSOR_ON.
+ * CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No
+ * blinking is provided. Uses the macros CURSOR_SET
+ * and CURSOR_OFF.
+ * CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the
+ * graphic chip. Uses the macro CURSOR_SET.
+ * ATTENTION: If booting an OS, the display driver
+ * must disable the hardware register of the graphic
+ * chip. Otherwise a blinking field is displayed
+ */
#if !defined(CONFIG_CONSOLE_CURSOR) && \
!defined(CONFIG_VIDEO_SW_CURSOR) && \
!defined(CONFIG_VIDEO_HW_CURSOR)
@@ -227,9 +235,11 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#ifdef CONFIG_CONSOLE_CURSOR
#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
+ or CONFIG_VIDEO_HW_CURSOR can be defined
#endif
-void console_cursor (int state);
+void console_cursor(int state);
+
#define CURSOR_ON console_cursor(1)
#define CURSOR_OFF console_cursor(0)
#define CURSOR_SET
@@ -244,7 +254,8 @@ void console_cursor (int state);
#ifdef CONFIG_VIDEO_SW_CURSOR
#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
+ or CONFIG_VIDEO_HW_CURSOR can be defined
#endif
#define CURSOR_ON
#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
@@ -255,13 +266,14 @@ void console_cursor (int state);
#ifdef CONFIG_VIDEO_HW_CURSOR
#ifdef CURSOR_ON
-#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#error only one of CONFIG_CONSOLE_CURSOR, CONFIG_VIDEO_SW_CURSOR, \
+ or CONFIG_VIDEO_HW_CURSOR can be defined
#endif
#define CURSOR_ON
#define CURSOR_OFF
#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
(console_row * VIDEO_FONT_HEIGHT) + video_logo_height)
-#endif /* CONFIG_VIDEO_HW_CURSOR */
+#endif /* CONFIG_VIDEO_HW_CURSOR */
#ifdef CONFIG_VIDEO_LOGO
#ifdef CONFIG_VIDEO_BMP_LOGO
@@ -271,7 +283,7 @@ void console_cursor (int state);
#define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET
#define VIDEO_LOGO_COLORS BMP_LOGO_COLORS
-#else /* CONFIG_VIDEO_BMP_LOGO */
+#else /* CONFIG_VIDEO_BMP_LOGO */
#define LINUX_LOGO_WIDTH 80
#define LINUX_LOGO_HEIGHT 80
#define LINUX_LOGO_COLORS 214
@@ -282,13 +294,13 @@ void console_cursor (int state);
#define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT
#define VIDEO_LOGO_LUT_OFFSET LINUX_LOGO_LUT_OFFSET
#define VIDEO_LOGO_COLORS LINUX_LOGO_COLORS
-#endif /* CONFIG_VIDEO_BMP_LOGO */
+#endif /* CONFIG_VIDEO_BMP_LOGO */
#define VIDEO_INFO_X (VIDEO_LOGO_WIDTH)
#define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2)
-#else /* CONFIG_VIDEO_LOGO */
+#else /* CONFIG_VIDEO_LOGO */
#define VIDEO_LOGO_WIDTH 0
#define VIDEO_LOGO_HEIGHT 0
-#endif /* CONFIG_VIDEO_LOGO */
+#endif /* CONFIG_VIDEO_LOGO */
#define VIDEO_COLS VIDEO_VISIBLE_COLS
#define VIDEO_ROWS VIDEO_VISIBLE_ROWS
@@ -313,101 +325,107 @@ void console_cursor (int state);
/* Macros */
#ifdef VIDEO_FB_LITTLE_ENDIAN
-#define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8))
-#define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
- (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) )
-#define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\
- (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) )
+#define SWAP16(x) ((((x) & 0x00ff) << 8) | \
+ ((x) >> 8) \
+ )
+#define SWAP32(x) ((((x) & 0x000000ff) << 24) | \
+ (((x) & 0x0000ff00) << 8) | \
+ (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0xff000000) >> 24) \
+ )
+#define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | \
+ (((x) & 0x0000ff00) >> 8) | \
+ (((x) & 0x00ff0000) << 8) | \
+ (((x) & 0xff000000) >> 8) \
+ )
#else
-#define SWAP16(x) (x)
-#define SWAP32(x) (x)
+#define SWAP16(x) (x)
+#define SWAP32(x) (x)
#if defined(VIDEO_FB_16BPP_WORD_SWAP)
-#define SHORTSWAP32(x) ( ((x) >> 16) | ((x) << 16) )
+#define SHORTSWAP32(x) (((x) >> 16) | ((x) << 16))
#else
-#define SHORTSWAP32(x) (x)
-#endif
+#define SHORTSWAP32(x) (x)
#endif
-
-#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
-#define PRINTD(x) printf(x)
-#else
-#define PRINTD(x)
#endif
-
#ifdef CONFIG_CONSOLE_EXTRA_INFO
-extern void video_get_info_str ( /* setup a board string: type, speed, etc. */
- int line_number, /* location to place info string beside logo */
- char *info /* buffer for info string */
- );
-
+/*
+ * setup a board string: type, speed, etc.
+ *
+ * line_number: location to place info string beside logo
+ * info: buffer for info string
+ */
+extern void video_get_info_str(int line_number, char *info);
#endif
/* Locals */
static GraphicDevice *pGD; /* Pointer to Graphic array */
-static void *video_fb_address; /* frame buffer address */
+static void *video_fb_address; /* frame buffer address */
static void *video_console_address; /* console buffer start address */
static int video_logo_height = VIDEO_LOGO_HEIGHT;
-static int console_col = 0; /* cursor col */
-static int console_row = 0; /* cursor row */
+static int console_col; /* cursor col */
+static int console_row; /* cursor row */
-static u32 eorx, fgx, bgx; /* color pats */
+static u32 eorx, fgx, bgx; /* color pats */
static const int video_font_draw_table8[] = {
- 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
- 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
- 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
- 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
+ 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+ 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+ 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+ 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
+};
static const int video_font_draw_table15[] = {
- 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
+ 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff
+};
static const int video_font_draw_table16[] = {
- 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+};
static const int video_font_draw_table24[16][3] = {
- { 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00ffffff },
- { 0x00000000, 0x0000ffff, 0xff000000 },
- { 0x00000000, 0x0000ffff, 0xffffffff },
- { 0x000000ff, 0xffff0000, 0x00000000 },
- { 0x000000ff, 0xffff0000, 0x00ffffff },
- { 0x000000ff, 0xffffffff, 0xff000000 },
- { 0x000000ff, 0xffffffff, 0xffffffff },
- { 0xffffff00, 0x00000000, 0x00000000 },
- { 0xffffff00, 0x00000000, 0x00ffffff },
- { 0xffffff00, 0x0000ffff, 0xff000000 },
- { 0xffffff00, 0x0000ffff, 0xffffffff },
- { 0xffffffff, 0xffff0000, 0x00000000 },
- { 0xffffffff, 0xffff0000, 0x00ffffff },
- { 0xffffffff, 0xffffffff, 0xff000000 },
- { 0xffffffff, 0xffffffff, 0xffffffff } };
+ {0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00ffffff},
+ {0x00000000, 0x0000ffff, 0xff000000},
+ {0x00000000, 0x0000ffff, 0xffffffff},
+ {0x000000ff, 0xffff0000, 0x00000000},
+ {0x000000ff, 0xffff0000, 0x00ffffff},
+ {0x000000ff, 0xffffffff, 0xff000000},
+ {0x000000ff, 0xffffffff, 0xffffffff},
+ {0xffffff00, 0x00000000, 0x00000000},
+ {0xffffff00, 0x00000000, 0x00ffffff},
+ {0xffffff00, 0x0000ffff, 0xff000000},
+ {0xffffff00, 0x0000ffff, 0xffffffff},
+ {0xffffffff, 0xffff0000, 0x00000000},
+ {0xffffffff, 0xffff0000, 0x00ffffff},
+ {0xffffffff, 0xffffffff, 0xff000000},
+ {0xffffffff, 0xffffffff, 0xffffffff}
+};
static const int video_font_draw_table32[16][4] = {
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
- { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
- { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
- { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
- { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
- { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
- { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
- { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
- { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
- { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
- { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
- { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
- { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
- { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
-
-
-/******************************************************************************/
-
-static void video_drawchars (int xx, int yy, unsigned char *s, int count)
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00ffffff},
+ {0x00000000, 0x00000000, 0x00ffffff, 0x00000000},
+ {0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff},
+ {0x00000000, 0x00ffffff, 0x00000000, 0x00000000},
+ {0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff},
+ {0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000},
+ {0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff},
+ {0x00ffffff, 0x00000000, 0x00000000, 0x00000000},
+ {0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff},
+ {0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000},
+ {0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff},
+ {0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000},
+ {0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff},
+ {0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000},
+ {0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff}
+};
+
+
+static void video_drawchars(int xx, int yy, unsigned char *s, int count)
{
u8 *cdat, *dest, *dest0;
int rows, offset, c;
@@ -422,12 +440,15 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
c = *s;
cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
- rows--;
- dest += VIDEO_LINE_LEN) {
+ rows--; dest += VIDEO_LINE_LEN) {
u8 bits = *cdat++;
- ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
- ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
+ ((u32 *) dest)[0] =
+ (video_font_draw_table8[bits >> 4] &
+ eorx) ^ bgx;
+ ((u32 *) dest)[1] =
+ (video_font_draw_table8[bits & 15] &
+ eorx) ^ bgx;
}
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
@@ -439,14 +460,25 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
c = *s;
cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
- rows--;
- dest += VIDEO_LINE_LEN) {
+ rows--; dest += VIDEO_LINE_LEN) {
u8 bits = *cdat++;
- ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx);
- ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx);
- ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx);
- ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx);
+ ((u32 *) dest)[0] =
+ SHORTSWAP32((video_font_draw_table15
+ [bits >> 6] & eorx) ^
+ bgx);
+ ((u32 *) dest)[1] =
+ SHORTSWAP32((video_font_draw_table15
+ [bits >> 4 & 3] & eorx) ^
+ bgx);
+ ((u32 *) dest)[2] =
+ SHORTSWAP32((video_font_draw_table15
+ [bits >> 2 & 3] & eorx) ^
+ bgx);
+ ((u32 *) dest)[3] =
+ SHORTSWAP32((video_font_draw_table15
+ [bits & 3] & eorx) ^
+ bgx);
}
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
@@ -458,14 +490,25 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
c = *s;
cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
- rows--;
- dest += VIDEO_LINE_LEN) {
+ rows--; dest += VIDEO_LINE_LEN) {
u8 bits = *cdat++;
- ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx);
- ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx);
- ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx);
- ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx);
+ ((u32 *) dest)[0] =
+ SHORTSWAP32((video_font_draw_table16
+ [bits >> 6] & eorx) ^
+ bgx);
+ ((u32 *) dest)[1] =
+ SHORTSWAP32((video_font_draw_table16
+ [bits >> 4 & 3] & eorx) ^
+ bgx);
+ ((u32 *) dest)[2] =
+ SHORTSWAP32((video_font_draw_table16
+ [bits >> 2 & 3] & eorx) ^
+ bgx);
+ ((u32 *) dest)[3] =
+ SHORTSWAP32((video_font_draw_table16
+ [bits & 3] & eorx) ^
+ bgx);
}
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
@@ -477,18 +520,33 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
c = *s;
cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
- rows--;
- dest += VIDEO_LINE_LEN) {
+ rows--; dest += VIDEO_LINE_LEN) {
u8 bits = *cdat++;
- ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx);
- ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx);
- ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx);
- ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx);
- ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx);
- ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx);
- ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx);
- ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx);
+ ((u32 *) dest)[0] =
+ SWAP32((video_font_draw_table32
+ [bits >> 4][0] & eorx) ^ bgx);
+ ((u32 *) dest)[1] =
+ SWAP32((video_font_draw_table32
+ [bits >> 4][1] & eorx) ^ bgx);
+ ((u32 *) dest)[2] =
+ SWAP32((video_font_draw_table32
+ [bits >> 4][2] & eorx) ^ bgx);
+ ((u32 *) dest)[3] =
+ SWAP32((video_font_draw_table32
+ [bits >> 4][3] & eorx) ^ bgx);
+ ((u32 *) dest)[4] =
+ SWAP32((video_font_draw_table32
+ [bits & 15][0] & eorx) ^ bgx);
+ ((u32 *) dest)[5] =
+ SWAP32((video_font_draw_table32
+ [bits & 15][1] & eorx) ^ bgx);
+ ((u32 *) dest)[6] =
+ SWAP32((video_font_draw_table32
+ [bits & 15][2] & eorx) ^ bgx);
+ ((u32 *) dest)[7] =
+ SWAP32((video_font_draw_table32
+ [bits & 15][3] & eorx) ^ bgx);
}
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
@@ -500,16 +558,27 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
c = *s;
cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
- rows--;
- dest += VIDEO_LINE_LEN) {
+ rows--; dest += VIDEO_LINE_LEN) {
u8 bits = *cdat++;
- ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
- ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
- ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
- ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
- ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
- ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
+ ((u32 *) dest)[0] =
+ (video_font_draw_table24[bits >> 4][0]
+ & eorx) ^ bgx;
+ ((u32 *) dest)[1] =
+ (video_font_draw_table24[bits >> 4][1]
+ & eorx) ^ bgx;
+ ((u32 *) dest)[2] =
+ (video_font_draw_table24[bits >> 4][2]
+ & eorx) ^ bgx;
+ ((u32 *) dest)[3] =
+ (video_font_draw_table24[bits & 15][0]
+ & eorx) ^ bgx;
+ ((u32 *) dest)[4] =
+ (video_font_draw_table24[bits & 15][1]
+ & eorx) ^ bgx;
+ ((u32 *) dest)[5] =
+ (video_font_draw_table24[bits & 15][2]
+ & eorx) ^ bgx;
}
dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
s++;
@@ -518,23 +587,18 @@ static void video_drawchars (int xx, int yy, unsigned char *s, int count)
}
}
-/*****************************************************************************/
-
-static inline void video_drawstring (int xx, int yy, unsigned char *s)
+static inline void video_drawstring(int xx, int yy, unsigned char *s)
{
- video_drawchars (xx, yy, s, strlen ((char *)s));
+ video_drawchars(xx, yy, s, strlen((char *) s));
}
-/*****************************************************************************/
-
-static void video_putchar (int xx, int yy, unsigned char c)
+static void video_putchar(int xx, int yy, unsigned char c)
{
- video_drawchars (xx, yy + video_logo_height, &c, 1);
+ video_drawchars(xx, yy + video_logo_height, &c, 1);
}
-/*****************************************************************************/
#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
-static void video_set_cursor (void)
+static void video_set_cursor(void)
{
/* swap drawing colors */
eorx = fgx;
@@ -542,9 +606,8 @@ static void video_set_cursor (void)
bgx = eorx;
eorx = fgx ^ bgx;
/* draw cursor */
- video_putchar (console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT,
- ' ');
+ video_putchar(console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
/* restore drawing colors */
eorx = fgx;
fgx = bgx;
@@ -552,9 +615,9 @@ static void video_set_cursor (void)
eorx = fgx ^ bgx;
}
#endif
-/*****************************************************************************/
+
#ifdef CONFIG_CONSOLE_CURSOR
-void console_cursor (int state)
+void console_cursor(int state)
{
static int last_state = 0;
@@ -564,92 +627,88 @@ void console_cursor (int state)
/* time update only if cursor is on (faster scroll) */
if (state) {
- rtc_get (&tm);
-
- sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
- tm.tm_sec);
- video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
- VIDEO_INFO_Y, (uchar *)info);
-
- sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
- tm.tm_year);
- video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
- VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info);
+ rtc_get(&tm);
+
+ sprintf(info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
+ tm.tm_sec);
+ video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y, (uchar *) info);
+
+ sprintf(info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
+ tm.tm_year);
+ video_drawstring(VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT,
+ (uchar *) info);
}
#endif
if (state && (last_state != state)) {
- video_set_cursor ();
+ video_set_cursor();
}
if (!state && (last_state != state)) {
/* clear cursor */
- video_putchar (console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT,
- ' ');
+ video_putchar(console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
}
last_state = state;
}
#endif
-/*****************************************************************************/
-
#ifndef VIDEO_HW_RECTFILL
-static void memsetl (int *p, int c, int v)
+static void memsetl(int *p, int c, int v)
{
while (c--)
*(p++) = v;
}
#endif
-/*****************************************************************************/
-
#ifndef VIDEO_HW_BITBLT
-static void memcpyl (int *d, int *s, int c)
+static void memcpyl(int *d, int *s, int c)
{
while (c--)
*(d++) = *(s++);
}
#endif
-/*****************************************************************************/
-
-static void console_scrollup (void)
+static void console_scrollup(void)
{
/* copy up rows ignoring the first one */
#ifdef VIDEO_HW_BITBLT
- video_hw_bitblt (VIDEO_PIXEL_SIZE, /* bytes per pixel */
- 0, /* source pos x */
- video_logo_height + VIDEO_FONT_HEIGHT, /* source pos y */
- 0, /* dest pos x */
- video_logo_height, /* dest pos y */
- VIDEO_VISIBLE_COLS, /* frame width */
- VIDEO_VISIBLE_ROWS - video_logo_height - VIDEO_FONT_HEIGHT /* frame height */
+ video_hw_bitblt(VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ 0, /* source pos x */
+ video_logo_height +
+ VIDEO_FONT_HEIGHT, /* source pos y */
+ 0, /* dest pos x */
+ video_logo_height, /* dest pos y */
+ VIDEO_VISIBLE_COLS, /* frame width */
+ VIDEO_VISIBLE_ROWS
+ - video_logo_height
+ - VIDEO_FONT_HEIGHT /* frame height */
);
#else
- memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
- CONSOLE_SCROLL_SIZE >> 2);
+ memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
+ CONSOLE_SCROLL_SIZE >> 2);
#endif
/* clear the last one */
#ifdef VIDEO_HW_RECTFILL
- video_hw_rectfill (VIDEO_PIXEL_SIZE, /* bytes per pixel */
- 0, /* dest pos x */
- VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */
- VIDEO_VISIBLE_COLS, /* frame width */
- VIDEO_FONT_HEIGHT, /* frame height */
- CONSOLE_BG_COL /* fill color */
+ video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ 0, /* dest pos x */
+ VIDEO_VISIBLE_ROWS
+ - VIDEO_FONT_HEIGHT, /* dest pos y */
+ VIDEO_VISIBLE_COLS, /* frame width */
+ VIDEO_FONT_HEIGHT, /* frame height */
+ CONSOLE_BG_COL /* fill color */
);
#else
- memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
+ memsetl(CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
#endif
}
-/*****************************************************************************/
-
-static void console_back (void)
+static void console_back(void)
{
CURSOR_OFF;
console_col--;
@@ -660,14 +719,11 @@ static void console_back (void)
if (console_row < 0)
console_row = 0;
}
- video_putchar (console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT,
- ' ');
+ video_putchar(console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, ' ');
}
-/*****************************************************************************/
-
-static void console_newline (void)
+static void console_newline(void)
{
/* Check if last character in the line was just drawn. If so, cursor was
overwriten and need not to be cleared. Cursor clearing without this
@@ -682,33 +738,31 @@ static void console_newline (void)
/* Check if we need to scroll the terminal */
if (console_row >= CONSOLE_ROWS) {
/* Scroll everything up */
- console_scrollup ();
+ console_scrollup();
/* Decrement row number */
console_row--;
}
}
-static void console_cr (void)
+static void console_cr(void)
{
CURSOR_OFF;
console_col = 0;
}
-/*****************************************************************************/
-
-void video_putc (const char c)
+void video_putc(const char c)
{
static int nl = 1;
switch (c) {
case 13: /* back to first column */
- console_cr ();
+ console_cr();
break;
case '\n': /* next line */
if (console_col || (!console_col && nl))
- console_newline ();
+ console_newline();
nl = 1;
break;
@@ -718,52 +772,47 @@ void video_putc (const char c)
console_col &= ~0x0007;
if (console_col >= CONSOLE_COLS)
- console_newline ();
+ console_newline();
break;
case 8: /* backspace */
- console_back ();
+ console_back();
break;
default: /* draw the char */
- video_putchar (console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT,
- c);
+ video_putchar(console_col * VIDEO_FONT_WIDTH,
+ console_row * VIDEO_FONT_HEIGHT, c);
console_col++;
/* check for newline */
if (console_col >= CONSOLE_COLS) {
- console_newline ();
+ console_newline();
nl = 0;
}
}
CURSOR_SET;
}
-
-/*****************************************************************************/
-
-void video_puts (const char *s)
+void video_puts(const char *s)
{
- int count = strlen (s);
+ int count = strlen(s);
while (count--)
- video_putc (*s++);
+ video_putc(*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 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")));
+
+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)
@@ -773,17 +822,26 @@ void video_set_lut (unsigned int, unsigned char, unsigned char, unsigned char)
}
#define FILL_15BIT_555RGB(r,g,b) { \
- *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
+ *(unsigned short *)fb = \
+ SWAP16((unsigned short)(((r>>3)<<10) | \
+ ((g>>3)<<5) | \
+ (b>>3))); \
fb += 2; \
}
#define FILL_16BIT_565RGB(r,g,b) { \
- *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
+ *(unsigned short *)fb = \
+ SWAP16((unsigned short)((((r)>>3)<<11)| \
+ (((g)>>2)<<5) | \
+ ((b)>>3))); \
fb += 2; \
}
#define FILL_32BIT_X888RGB(r,g,b) { \
- *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \
+ *(unsigned long *)fb = \
+ SWAP32((unsigned long)(((r<<16) | \
+ (g<<8) | \
+ b))); \
fb += 4; \
}
@@ -804,13 +862,12 @@ void video_set_lut (unsigned int, unsigned char, unsigned char, unsigned char)
#endif
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
-static void inline fill_555rgb_pswap(uchar *fb, int x,
- u8 r, u8 g, u8 b)
+static inline void fill_555rgb_pswap(uchar *fb, int x, u8 r, u8 g, u8 b)
{
- ushort *dst = (ushort *)fb;
- ushort color = (ushort)(((r >> 3) << 10) |
- ((g >> 3) << 5) |
- (b >> 3));
+ ushort *dst = (ushort *) fb;
+ ushort color = (ushort) (((r >> 3) << 10) |
+ ((g >> 3) << 5) |
+ (b >> 3));
if (x & 1)
*(--dst) = color;
else
@@ -826,18 +883,18 @@ static void inline fill_555rgb_pswap(uchar *fb, int x,
/* Pre-calculated color table entry */
struct palette {
union {
- unsigned short w; /* word */
- unsigned int dw; /* double word */
- } ce; /* color entry */
+ unsigned short w; /* word */
+ unsigned int dw; /* double word */
+ } ce; /* color entry */
};
/*
* Helper to draw encoded/unencoded run.
*/
-static void draw_bitmap (uchar **fb, uchar *bm, struct palette *p,
- int cnt, int enc)
+static void draw_bitmap(uchar **fb, uchar *bm, struct palette *p,
+ int cnt, int enc)
{
- ulong addr = (ulong)*fb;
+ ulong addr = (ulong) *fb;
int *off;
int enc_off = 1;
int i;
@@ -851,28 +908,28 @@ static void draw_bitmap (uchar **fb, uchar *bm, struct palette *p,
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_INDEX:
for (i = 0; i < cnt; i++)
- *(unsigned char *)addr++ = bm[*off];
+ *(unsigned char *) addr++ = bm[*off];
break;
case GDF_15BIT_555RGB:
case GDF_16BIT_565RGB:
/* differences handled while pre-calculating palette */
for (i = 0; i < cnt; i++) {
- *(unsigned short *)addr = p[bm[*off]].ce.w;
+ *(unsigned short *) addr = p[bm[*off]].ce.w;
addr += 2;
}
break;
case GDF_32BIT_X888RGB:
for (i = 0; i < cnt; i++) {
- *(unsigned long *)addr = p[bm[*off]].ce.dw;
+ *(unsigned long *) addr = p[bm[*off]].ce.dw;
addr += 4;
}
break;
}
- *fb = (uchar *)addr; /* return modified address */
+ *fb = (uchar *) addr; /* return modified address */
}
-static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
- int width, int height)
+static int display_rle8_bitmap(bmp_image_t *img, int xoff, int yoff,
+ int width, int height)
{
unsigned char *bm;
unsigned char *fbp;
@@ -889,17 +946,17 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
y = __le32_to_cpu(img->header.height) - 1;
ncolors = __le32_to_cpu(img->header.colors_used);
bpp = VIDEO_PIXEL_SIZE;
- fbp = (unsigned char *)((unsigned int)video_fb_address +
- (((y + yoff) * VIDEO_COLS) + xoff) * bpp);
+ fbp = (unsigned char *) ((unsigned int) video_fb_address +
+ (((y + yoff) * VIDEO_COLS) + xoff) * bpp);
- bm = (uchar *)img + __le32_to_cpu(img->header.data_offset);
+ bm = (uchar *) img + __le32_to_cpu(img->header.data_offset);
/* pre-calculate and setup palette */
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_INDEX:
for (i = 0; i < ncolors; i++) {
cte = img->color_table[i];
- video_set_lut (i, cte.red, cte.green, cte.blue);
+ video_set_lut(i, cte.red, cte.green, cte.blue);
}
break;
case GDF_15BIT_555RGB:
@@ -922,13 +979,14 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
case GDF_32BIT_X888RGB:
for (i = 0; i < ncolors; i++) {
cte = img->color_table[i];
- p[i].ce.dw = SWAP32((cte.red << 16) | (cte.green << 8) |
+ p[i].ce.dw = SWAP32((cte.red << 16) |
+ (cte.green << 8) |
cte.blue);
}
break;
default:
printf("RLE Bitmap unsupported in video mode 0x%x\n",
- VIDEO_DATA_FORMAT);
+ VIDEO_DATA_FORMAT);
return -1;
}
@@ -942,7 +1000,7 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
x = 0;
y--;
fbp = (unsigned char *)
- ((unsigned int)video_fb_address +
+ ((unsigned int) video_fb_address +
(((y + yoff) * VIDEO_COLS) +
xoff) * bpp);
continue;
@@ -955,7 +1013,7 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
x += bm[2];
y -= bm[3];
fbp = (unsigned char *)
- ((unsigned int)video_fb_address +
+ ((unsigned int) video_fb_address +
(((y + yoff) * VIDEO_COLS) +
x + xoff) * bpp);
bm += 4;
@@ -976,13 +1034,13 @@ static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
}
if (x + runlen > width)
cnt = width - x;
- draw_bitmap (&fbp, bm, p, cnt, 0);
+ draw_bitmap(&fbp, bm, p, cnt, 0);
x += runlen;
}
next_run:
bm += runlen;
if (runlen & 1)
- bm++; /* 0 padding if length is odd */
+ bm++; /* 0 padding if length is odd */
}
break;
default:
@@ -993,7 +1051,7 @@ next_run:
if (pixels > limit)
goto error;
- if (y < height) { /* only draw into visible area */
+ if (y < height) { /* only draw into visible area */
if (x >= width) {
x += runlen;
bm += 2;
@@ -1001,7 +1059,7 @@ next_run:
}
if (x + runlen > width)
cnt = width - x;
- draw_bitmap (&fbp, bm, p, cnt, 1);
+ draw_bitmap(&fbp, bm, p, cnt, 1);
x += runlen;
}
bm += 2;
@@ -1018,7 +1076,7 @@ error:
/*
* Display the BMP file located at address bmp_image.
*/
-int video_display_bitmap (ulong bmp_image, int x, int y)
+int video_display_bitmap(ulong bmp_image, int x, int y)
{
ushort xcount, ycount;
uchar *fb;
@@ -1029,12 +1087,13 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
unsigned colors;
unsigned long compression;
bmp_color_table_entry_t cte;
+
#ifdef CONFIG_VIDEO_BMP_GZIP
unsigned char *dst = NULL;
ulong len;
#endif
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
@@ -1047,50 +1106,55 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
if (dst == NULL) {
printf("Error: malloc in gunzip failed!\n");
- return(1);
+ return 1;
}
- if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
- printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
+ if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE,
+ (uchar *) bmp_image,
+ &len) != 0) {
+ printf("Error: no valid bmp or bmp.gz image at %lx\n",
+ bmp_image);
free(dst);
return 1;
}
if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) {
- printf("Image could be truncated (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
+ printf("Image could be truncated "
+ "(increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
}
/*
* Set addr to decompressed image
*/
- bmp = (bmp_image_t *)dst;
+ bmp = (bmp_image_t *) dst;
if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
- printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
+ printf("Error: no valid bmp.gz image at %lx\n",
+ bmp_image);
free(dst);
return 1;
}
#else
- printf ("Error: no valid bmp image at %lx\n", bmp_image);
+ printf("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
#endif /* CONFIG_VIDEO_BMP_GZIP */
}
- width = le32_to_cpu (bmp->header.width);
- height = le32_to_cpu (bmp->header.height);
- bpp = le16_to_cpu (bmp->header.bit_count);
- colors = le32_to_cpu (bmp->header.colors_used);
- compression = le32_to_cpu (bmp->header.compression);
+ width = le32_to_cpu(bmp->header.width);
+ height = le32_to_cpu(bmp->header.height);
+ bpp = le16_to_cpu(bmp->header.bit_count);
+ colors = le32_to_cpu(bmp->header.colors_used);
+ compression = le32_to_cpu(bmp->header.compression);
- debug ("Display-bmp: %d x %d with %d colors\n",
- width, height, colors);
+ debug("Display-bmp: %d x %d with %d colors\n",
+ width, height, colors);
if (compression != BMP_BI_RGB
#ifdef CONFIG_VIDEO_BMP_RLE8
&& compression != BMP_BI_RLE8
#endif
- ) {
- printf ("Error: compression type %ld not supported\n",
- compression);
+ ) {
+ printf("Error: compression type %ld not supported\n",
+ compression);
#ifdef CONFIG_VIDEO_BMP_GZIP
if (dst)
free(dst);
@@ -1117,20 +1181,19 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
if ((y + height) > VIDEO_VISIBLE_ROWS)
height = VIDEO_VISIBLE_ROWS - y;
- bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset);
+ bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
fb = (uchar *) (video_fb_address +
((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
x * VIDEO_PIXEL_SIZE);
#ifdef CONFIG_VIDEO_BMP_RLE8
if (compression == BMP_BI_RLE8) {
- return display_rle8_bitmap(bmp,
- x, y, width, height);
+ return display_rle8_bitmap(bmp, x, y, width, height);
}
#endif
/* We handle only 4, 8, or 24 bpp bitmaps */
- switch (le16_to_cpu (bmp->header.bit_count)) {
+ switch (le16_to_cpu(bmp->header.bit_count)) {
case 4:
padded_line -= width / 2;
ycount = height;
@@ -1138,7 +1201,7 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
switch (VIDEO_DATA_FORMAT) {
case GDF_32BIT_X888RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
/*
* Don't assume that 'width' is an
* even number
@@ -1157,7 +1220,7 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
}
bmap += padded_line;
fb -= (VIDEO_VISIBLE_COLS + width) *
- VIDEO_PIXEL_SIZE;
+ VIDEO_PIXEL_SIZE;
}
break;
default:
@@ -1173,32 +1236,36 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
/* Copy colormap */
for (xcount = 0; xcount < colors; ++xcount) {
cte = bmp->color_table[xcount];
- video_set_lut (xcount, cte.red, cte.green, cte.blue);
+ video_set_lut(xcount, cte.red, cte.green,
+ cte.blue);
}
}
ycount = height;
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_INDEX:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
*fb++ = *bmap++;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF__8BIT_332RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
- FILL_8BIT_332RGB (cte.red, cte.green, cte.blue);
+ FILL_8BIT_332RGB(cte.red, cte.green,
+ cte.blue);
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_15BIT_555RGB:
@@ -1206,56 +1273,65 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
int xpos = x;
#endif
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
- fill_555rgb_pswap (fb, xpos++, cte.red,
- cte.green, cte.blue);
+ fill_555rgb_pswap(fb, xpos++, cte.red,
+ cte.green,
+ cte.blue);
fb += 2;
#else
- FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
+ FILL_15BIT_555RGB(cte.red, cte.green,
+ cte.blue);
#endif
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_16BIT_565RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
- FILL_16BIT_565RGB (cte.red, cte.green, cte.blue);
+ FILL_16BIT_565RGB(cte.red, cte.green,
+ cte.blue);
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_32BIT_X888RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
- FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue);
+ FILL_32BIT_X888RGB(cte.red, cte.green,
+ cte.blue);
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_24BIT_888RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
- FILL_24BIT_888RGB (cte.red, cte.green, cte.blue);
+ FILL_24BIT_888RGB(cte.red, cte.green,
+ cte.blue);
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
}
@@ -1266,14 +1342,16 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_332RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
- FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]);
+ FILL_8BIT_332RGB(bmap[2], bmap[1],
+ bmap[0]);
bmap += 3;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_15BIT_555RGB:
@@ -1281,66 +1359,75 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
int xpos = x;
#endif
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
- fill_555rgb_pswap (fb, xpos++, bmap[2],
- bmap[1], bmap[0]);
+ fill_555rgb_pswap(fb, xpos++, bmap[2],
+ bmap[1], bmap[0]);
fb += 2;
#else
- FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
+ FILL_15BIT_555RGB(bmap[2], bmap[1],
+ bmap[0]);
#endif
bmap += 3;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_16BIT_565RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
- FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]);
+ FILL_16BIT_565RGB(bmap[2], bmap[1],
+ bmap[0]);
bmap += 3;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_32BIT_X888RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
- FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]);
+ FILL_32BIT_X888RGB(bmap[2], bmap[1],
+ bmap[0]);
bmap += 3;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
case GDF_24BIT_888RGB:
while (ycount--) {
- WATCHDOG_RESET ();
+ WATCHDOG_RESET();
xcount = width;
while (xcount--) {
- FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]);
+ FILL_24BIT_888RGB(bmap[2], bmap[1],
+ bmap[0]);
bmap += 3;
}
bmap += padded_line;
- fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+ fb -= (VIDEO_VISIBLE_COLS + width) *
+ VIDEO_PIXEL_SIZE;
}
break;
default:
- printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n");
+ printf("Error: 24 bits/pixel bitmap incompatible "
+ "with current video mode\n");
break;
}
break;
default:
- printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
- le16_to_cpu (bmp->header.bit_count));
+ printf("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
+ le16_to_cpu(bmp->header.bit_count));
break;
}
@@ -1354,28 +1441,26 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
}
#endif
-/*****************************************************************************/
#ifdef CONFIG_VIDEO_LOGO
-void logo_plot (void *screen, int width, int x, int y)
+void logo_plot(void *screen, int width, int x, int y)
{
int xcount, i;
- int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
+ int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
int ycount = video_logo_height;
unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
unsigned char *source;
- unsigned char *dest = (unsigned char *)screen +
- ((y * width * VIDEO_PIXEL_SIZE) +
- x * VIDEO_PIXEL_SIZE);
+ unsigned char *dest = (unsigned char *) screen +
+ ((y * width * VIDEO_PIXEL_SIZE) + x * VIDEO_PIXEL_SIZE);
#ifdef CONFIG_VIDEO_BMP_LOGO
source = bmp_logo_bitmap;
/* Allocate temporary space for computing colormap */
- logo_red = malloc (BMP_LOGO_COLORS);
- logo_green = malloc (BMP_LOGO_COLORS);
- logo_blue = malloc (BMP_LOGO_COLORS);
+ logo_red = malloc(BMP_LOGO_COLORS);
+ logo_green = malloc(BMP_LOGO_COLORS);
+ logo_blue = malloc(BMP_LOGO_COLORS);
/* Compute color map */
for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
@@ -1391,8 +1476,9 @@ void logo_plot (void *screen, int width, int x, int y)
if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
- video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
- logo_red[i], logo_green[i], logo_blue[i]);
+ video_set_lut(i + VIDEO_LOGO_LUT_OFFSET,
+ logo_red[i], logo_green[i],
+ logo_blue[i]);
}
}
@@ -1411,23 +1497,34 @@ void logo_plot (void *screen, int width, int x, int y)
*dest = *source;
break;
case GDF__8BIT_332RGB:
- *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
+ *dest = ((r >> 5) << 5) |
+ ((g >> 5) << 2) |
+ (b >> 6);
break;
case GDF_15BIT_555RGB:
#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
- fill_555rgb_pswap (dest, xpos++, r, g, b);
+ fill_555rgb_pswap(dest, xpos++, r, g, b);
#else
*(unsigned short *) dest =
- SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
+ SWAP16((unsigned short) (
+ ((r >> 3) << 10) |
+ ((g >> 3) << 5) |
+ (b >> 3)));
#endif
break;
case GDF_16BIT_565RGB:
*(unsigned short *) dest =
- SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)));
+ SWAP16((unsigned short) (
+ ((r >> 3) << 11) |
+ ((g >> 2) << 5) |
+ (b >> 3)));
break;
case GDF_32BIT_X888RGB:
*(unsigned long *) dest =
- SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b));
+ SWAP32((unsigned long) (
+ (r << 16) |
+ (g << 8) |
+ b));
break;
case GDF_24BIT_888RGB:
#ifdef VIDEO_FB_LITTLE_ENDIAN
@@ -1447,94 +1544,100 @@ void logo_plot (void *screen, int width, int x, int y)
dest += skip;
}
#ifdef CONFIG_VIDEO_BMP_LOGO
- free (logo_red);
- free (logo_green);
- free (logo_blue);
+ free(logo_red);
+ free(logo_green);
+ free(logo_blue);
#endif
}
-/*****************************************************************************/
-
-static void *video_logo (void)
+static void *video_logo(void)
{
char info[128];
- extern char version_string;
int space, len, y_off = 0;
#ifdef CONFIG_SPLASH_SCREEN
char *s;
ulong addr;
- if ((s = getenv ("splashimage")) != NULL) {
+ s = getenv("splashimage");
+ if (s != NULL) {
int x = 0, y = 0;
- addr = simple_strtoul (s, NULL, 16);
+ addr = simple_strtoul(s, NULL, 16);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
- if ((s = getenv ("splashpos")) != NULL) {
+ s = getenv("splashpos");
+ if (s != NULL) {
if (s[0] == 'm')
x = BMP_ALIGN_CENTER;
else
- x = simple_strtol (s, NULL, 0);
+ x = simple_strtol(s, NULL, 0);
- if ((s = strchr (s + 1, ',')) != NULL) {
+ s = strchr(s + 1, ',');
+ if (s != NULL) {
if (s[1] == 'm')
y = BMP_ALIGN_CENTER;
else
- y = simple_strtol (s + 1, NULL, 0);
+ y = simple_strtol(s + 1, NULL, 0);
}
}
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
- if (video_display_bitmap (addr, x, y) == 0) {
+ if (video_display_bitmap(addr, x, y) == 0) {
video_logo_height = 0;
return ((void *) (video_fb_address));
}
}
#endif /* CONFIG_SPLASH_SCREEN */
- logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
+ logo_plot(video_fb_address, VIDEO_COLS, 0, 0);
- sprintf (info, " %s", &version_string);
+ sprintf(info, " %s", version_string);
space = (VIDEO_LINE_LEN / 2 - VIDEO_INFO_X) / VIDEO_FONT_WIDTH;
len = strlen(info);
if (len > space) {
- video_drawchars (VIDEO_INFO_X, VIDEO_INFO_Y,
- (uchar *)info, space);
- video_drawchars (VIDEO_INFO_X + VIDEO_FONT_WIDTH,
- VIDEO_INFO_Y + VIDEO_FONT_HEIGHT,
- (uchar *)info + space, len - space);
+ video_drawchars(VIDEO_INFO_X, VIDEO_INFO_Y,
+ (uchar *) info, space);
+ video_drawchars(VIDEO_INFO_X + VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y + VIDEO_FONT_HEIGHT,
+ (uchar *) info + space, len - space);
y_off = 1;
} else
- video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info);
+ video_drawstring(VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *) info);
#ifdef CONFIG_CONSOLE_EXTRA_INFO
{
- int i, n = ((video_logo_height - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
+ int i, n =
+ ((video_logo_height -
+ VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
for (i = 1; i < n; i++) {
- video_get_info_str (i, info);
+ video_get_info_str(i, info);
if (!*info)
continue;
len = strlen(info);
if (len > space) {
- video_drawchars (VIDEO_INFO_X,
- VIDEO_INFO_Y +
- (i + y_off) * VIDEO_FONT_HEIGHT,
- (uchar *)info, space);
+ video_drawchars(VIDEO_INFO_X,
+ VIDEO_INFO_Y +
+ (i + y_off) *
+ VIDEO_FONT_HEIGHT,
+ (uchar *) info, space);
y_off++;
- video_drawchars (VIDEO_INFO_X + VIDEO_FONT_WIDTH,
- VIDEO_INFO_Y +
- (i + y_off) * VIDEO_FONT_HEIGHT,
- (uchar *)info + space,
- len - space);
+ video_drawchars(VIDEO_INFO_X +
+ VIDEO_FONT_WIDTH,
+ VIDEO_INFO_Y +
+ (i + y_off) *
+ VIDEO_FONT_HEIGHT,
+ (uchar *) info + space,
+ len - space);
} else {
- video_drawstring (VIDEO_INFO_X,
- VIDEO_INFO_Y +
- (i + y_off) * VIDEO_FONT_HEIGHT,
- (uchar *)info);
+ video_drawstring(VIDEO_INFO_X,
+ VIDEO_INFO_Y +
+ (i + y_off) *
+ VIDEO_FONT_HEIGHT,
+ (uchar *) info);
}
}
}
@@ -1544,74 +1647,94 @@ static void *video_logo (void)
}
#endif
-
-/*****************************************************************************/
-
-static int video_init (void)
+static int video_init(void)
{
unsigned char color8;
- if ((pGD = video_hw_init ()) == NULL)
+ pGD = video_hw_init();
+ if (pGD == NULL)
return -1;
video_fb_address = (void *) VIDEO_FB_ADRS;
#ifdef CONFIG_VIDEO_HW_CURSOR
- video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
+ video_init_hw_cursor(VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
#endif
/* Init drawing pats */
switch (VIDEO_DATA_FORMAT) {
case GDF__8BIT_INDEX:
- video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
- video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
+ video_set_lut(0x01, CONSOLE_FG_COL, CONSOLE_FG_COL,
+ CONSOLE_FG_COL);
+ video_set_lut(0x00, CONSOLE_BG_COL, CONSOLE_BG_COL,
+ CONSOLE_BG_COL);
fgx = 0x01010101;
bgx = 0x00000000;
break;
case GDF__8BIT_332RGB:
color8 = ((CONSOLE_FG_COL & 0xe0) |
- ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6);
- fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+ ((CONSOLE_FG_COL >> 3) & 0x1c) |
+ CONSOLE_FG_COL >> 6);
+ fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
+ color8;
color8 = ((CONSOLE_BG_COL & 0xe0) |
- ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6);
- bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+ ((CONSOLE_BG_COL >> 3) & 0x1c) |
+ CONSOLE_BG_COL >> 6);
+ bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) |
+ color8;
break;
case GDF_15BIT_555RGB:
fgx = (((CONSOLE_FG_COL >> 3) << 26) |
- ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
- ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) |
- (CONSOLE_FG_COL >> 3));
+ ((CONSOLE_FG_COL >> 3) << 21) |
+ ((CONSOLE_FG_COL >> 3) << 16) |
+ ((CONSOLE_FG_COL >> 3) << 10) |
+ ((CONSOLE_FG_COL >> 3) << 5) |
+ (CONSOLE_FG_COL >> 3));
bgx = (((CONSOLE_BG_COL >> 3) << 26) |
- ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
- ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) |
- (CONSOLE_BG_COL >> 3));
+ ((CONSOLE_BG_COL >> 3) << 21) |
+ ((CONSOLE_BG_COL >> 3) << 16) |
+ ((CONSOLE_BG_COL >> 3) << 10) |
+ ((CONSOLE_BG_COL >> 3) << 5) |
+ (CONSOLE_BG_COL >> 3));
break;
case GDF_16BIT_565RGB:
fgx = (((CONSOLE_FG_COL >> 3) << 27) |
- ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
- ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) |
- (CONSOLE_FG_COL >> 3));
+ ((CONSOLE_FG_COL >> 2) << 21) |
+ ((CONSOLE_FG_COL >> 3) << 16) |
+ ((CONSOLE_FG_COL >> 3) << 11) |
+ ((CONSOLE_FG_COL >> 2) << 5) |
+ (CONSOLE_FG_COL >> 3));
bgx = (((CONSOLE_BG_COL >> 3) << 27) |
- ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
- ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) |
- (CONSOLE_BG_COL >> 3));
+ ((CONSOLE_BG_COL >> 2) << 21) |
+ ((CONSOLE_BG_COL >> 3) << 16) |
+ ((CONSOLE_BG_COL >> 3) << 11) |
+ ((CONSOLE_BG_COL >> 2) << 5) |
+ (CONSOLE_BG_COL >> 3));
break;
case GDF_32BIT_X888RGB:
- fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
- bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+ fgx = (CONSOLE_FG_COL << 16) |
+ (CONSOLE_FG_COL << 8) |
+ CONSOLE_FG_COL;
+ bgx = (CONSOLE_BG_COL << 16) |
+ (CONSOLE_BG_COL << 8) |
+ CONSOLE_BG_COL;
break;
case GDF_24BIT_888RGB:
- fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) |
- (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
- bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) |
- (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+ fgx = (CONSOLE_FG_COL << 24) |
+ (CONSOLE_FG_COL << 16) |
+ (CONSOLE_FG_COL << 8) |
+ CONSOLE_FG_COL;
+ bgx = (CONSOLE_BG_COL << 24) |
+ (CONSOLE_BG_COL << 16) |
+ (CONSOLE_BG_COL << 8) |
+ CONSOLE_BG_COL;
break;
}
eorx = fgx ^ bgx;
#ifdef CONFIG_VIDEO_LOGO
/* Plot the logo and get start point of console */
- PRINTD ("Video: Drawing the logo ...\n");
- video_console_address = video_logo ();
+ debug("Video: Drawing the logo ...\n");
+ video_console_address = video_logo();
#else
video_console_address = video_fb_address;
#endif
@@ -1623,9 +1746,6 @@ static int video_init (void)
return 0;
}
-
-/*****************************************************************************/
-
/*
* Implement a weak default function for boards that optionally
* need to skip the video initialization.
@@ -1635,9 +1755,11 @@ int __board_video_skip(void)
/* As default, don't skip test */
return 0;
}
-int board_video_skip(void) __attribute__((weak, alias("__board_video_skip")));
-int drv_video_init (void)
+int board_video_skip(void)
+ __attribute__ ((weak, alias("__board_video_skip")));
+
+int drv_video_init(void)
{
int skip_dev_init;
struct stdio_dev console_dev;
@@ -1647,10 +1769,10 @@ int drv_video_init (void)
return 0;
/* Init video chip - returns with framebuffer cleared */
- skip_dev_init = (video_init () == -1);
+ skip_dev_init = (video_init() == -1);
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
- PRINTD ("KBD: Keyboard init ...\n");
+ debug("KBD: Keyboard init ...\n");
skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
#endif
@@ -1658,8 +1780,8 @@ int drv_video_init (void)
return 0;
/* Init vga device */
- memset (&console_dev, 0, sizeof (console_dev));
- strcpy (console_dev.name, "vga");
+ memset(&console_dev, 0, sizeof(console_dev));
+ strcpy(console_dev.name, "vga");
console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */
console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
console_dev.putc = video_putc; /* 'putc' function */
@@ -1674,7 +1796,7 @@ int drv_video_init (void)
console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
- if (stdio_register (&console_dev) != 0)
+ if (stdio_register(&console_dev) != 0)
return 0;
/* Return success */