summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c401
-rw-r--r--drivers/block/fsl_sata.c81
-rw-r--r--drivers/block/fsl_sata.h13
-rw-r--r--drivers/block/sata_sil.c13
-rw-r--r--drivers/gpio/mpc83xx_gpio.c4
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/mmc/fsl_esdhc.c7
-rw-r--r--drivers/mmc/mmc.c37
-rw-r--r--drivers/mtd/cfi_flash.c22
-rw-r--r--drivers/mtd/nand/nand_base.c13
-rw-r--r--drivers/mtd/nand/nand_ecc.c1
-rw-r--r--drivers/mtd/nand/tegra_nand.c36
-rw-r--r--drivers/mtd/ubi/crc32.c12
-rw-r--r--drivers/net/fm/eth.c2
-rw-r--r--drivers/net/fm/p1023.c2
-rw-r--r--drivers/net/fm/p4080.c2
-rw-r--r--drivers/net/fm/p5020.c2
-rw-r--r--drivers/net/fm/tgec_phy.c10
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/phy/atheros.c2
-rw-r--r--drivers/net/phy/phy.c19
-rw-r--r--drivers/net/phy/vitesse.c2
-rw-r--r--drivers/net/smc91111.c2
-rw-r--r--drivers/net/vsc7385.c1
-rw-r--r--drivers/serial/s3c64xx.c2
-rw-r--r--drivers/serial/serial_ns16550.c78
-rw-r--r--drivers/usb/gadget/ether.c4
-rw-r--r--drivers/video/cfb_console.c328
-rw-r--r--drivers/video/mxc_ipuv3_fb.c8
29 files changed, 843 insertions, 265 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 7b2ec50..8c785ae 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -37,11 +37,28 @@
#include <linux/ctype.h>
#include <ahci.h>
+static int ata_io_flush(u8 port);
+
struct ahci_probe_ent *probe_ent = NULL;
hd_driveid_t *ataid[AHCI_MAX_PORTS];
#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
+/*
+ * Some controllers limit number of blocks they can read/write at once.
+ * Contemporary SSD devices work much faster if the read/write size is aligned
+ * to a power of 2. Let's set default to 128 and allowing to be overwritten if
+ * needed.
+ */
+#ifndef MAX_SATA_BLOCKS_READ_WRITE
+#define MAX_SATA_BLOCKS_READ_WRITE 0x80
+#endif
+
+/* Maximum timeouts for each event */
+#define WAIT_MS_SPINUP 10000
+#define WAIT_MS_DATAIO 5000
+#define WAIT_MS_FLUSH 5000
+#define WAIT_MS_LINKUP 4
static inline u32 ahci_port_base(u32 base, u32 port)
{
@@ -60,7 +77,39 @@ static void ahci_setup_port(struct ahci_ioports *port, unsigned long base,
#define msleep(a) udelay(a * 1000)
-#define ssleep(a) msleep(a * 1000)
+
+static void ahci_dcache_flush_range(unsigned begin, unsigned len)
+{
+ const unsigned long start = begin;
+ const unsigned long end = start + len;
+
+ debug("%s: flush dcache: [%#lx, %#lx)\n", __func__, start, end);
+ flush_dcache_range(start, end);
+}
+
+/*
+ * SATA controller DMAs to physical RAM. Ensure data from the
+ * controller is invalidated from dcache; next access comes from
+ * physical RAM.
+ */
+static void ahci_dcache_invalidate_range(unsigned begin, unsigned len)
+{
+ const unsigned long start = begin;
+ const unsigned long end = start + len;
+
+ debug("%s: invalidate dcache: [%#lx, %#lx)\n", __func__, start, end);
+ invalidate_dcache_range(start, end);
+}
+
+/*
+ * Ensure data for SATA controller is flushed out of dcache and
+ * written to physical memory.
+ */
+static void ahci_dcache_flush_sata_cmd(struct ahci_ioports *pp)
+{
+ ahci_dcache_flush_range((unsigned long)pp->cmd_slot,
+ AHCI_PORT_PRIV_DMA_SZ);
+}
static int waiting_for_cmd_completed(volatile u8 *offset,
int timeout_msec,
@@ -84,13 +133,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
unsigned short vendor;
#endif
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
- u32 tmp, cap_save;
+ u32 tmp, cap_save, cmd;
int i, j;
volatile u8 *port_mmio;
+ debug("ahci_host_init: start\n");
+
cap_save = readl(mmio + HOST_CAP);
cap_save &= ((1 << 28) | (1 << 17));
- cap_save |= (1 << 27);
+ cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
/* global controller reset */
tmp = readl(mmio + HOST_CTL);
@@ -100,13 +151,15 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
/* reset must complete within 1 second, or
* the hardware should be considered fried.
*/
- ssleep(1);
-
- tmp = readl(mmio + HOST_CTL);
- if (tmp & HOST_RESET) {
- debug("controller reset failed (0x%x)\n", tmp);
- return -1;
- }
+ i = 1000;
+ do {
+ udelay(1000);
+ tmp = readl(mmio + HOST_CTL);
+ if (!i--) {
+ debug("controller reset failed (0x%x)\n", tmp);
+ return -1;
+ }
+ } while (tmp & HOST_RESET);
writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL);
writel(cap_save, mmio + HOST_CAP);
@@ -129,6 +182,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
debug("cap 0x%x port_map 0x%x n_ports %d\n",
probe_ent->cap, probe_ent->port_map, probe_ent->n_ports);
+ if (probe_ent->n_ports > CONFIG_SYS_SCSI_MAX_SCSI_ID)
+ probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
+
for (i = 0; i < probe_ent->n_ports; i++) {
probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
port_mmio = (u8 *) probe_ent->port[i].port_mmio;
@@ -138,6 +194,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
tmp = readl(port_mmio + PORT_CMD);
if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
PORT_CMD_FIS_RX | PORT_CMD_START)) {
+ debug("Port %d is active. Deactivating.\n", i);
tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
PORT_CMD_FIS_RX | PORT_CMD_START);
writel_with_flush(tmp, port_mmio + PORT_CMD);
@@ -148,16 +205,53 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
msleep(500);
}
- writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
-
+ /* Add the spinup command to whatever mode bits may
+ * already be on in the command register.
+ */
+ cmd = readl(port_mmio + PORT_CMD);
+ cmd |= PORT_CMD_FIS_RX;
+ cmd |= PORT_CMD_SPIN_UP;
+ writel_with_flush(cmd, port_mmio + PORT_CMD);
+
+ /* Bring up SATA link.
+ * SATA link bringup time is usually less than 1 ms; only very
+ * rarely has it taken between 1-2 ms. Never seen it above 2 ms.
+ */
j = 0;
- while (j < 100) {
- msleep(10);
+ while (j < WAIT_MS_LINKUP) {
tmp = readl(port_mmio + PORT_SCR_STAT);
if ((tmp & 0xf) == 0x3)
break;
+ udelay(1000);
j++;
}
+ if (j == WAIT_MS_LINKUP) {
+ printf("SATA link %d timeout.\n", i);
+ continue;
+ } else {
+ debug("SATA link ok.\n");
+ }
+
+ /* Clear error status */
+ tmp = readl(port_mmio + PORT_SCR_ERR);
+ if (tmp)
+ writel(tmp, port_mmio + PORT_SCR_ERR);
+
+ debug("Spinning up device on SATA port %d... ", i);
+
+ j = 0;
+ while (j < WAIT_MS_SPINUP) {
+ tmp = readl(port_mmio + PORT_TFDATA);
+ if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ)))
+ break;
+ udelay(1000);
+ j++;
+ }
+ printf("Target spinup took %d ms.\n", j);
+ if (j == WAIT_MS_SPINUP)
+ debug("timeout.\n");
+ else
+ debug("ok.\n");
tmp = readl(port_mmio + PORT_SCR_ERR);
debug("PORT_SCR_ERR 0x%x\n", tmp);
@@ -174,9 +268,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
/* set irq mask (enables interrupts) */
writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
- /*register linkup ports */
+ /* register linkup ports */
tmp = readl(port_mmio + PORT_SCR_STAT);
- debug("Port %d status: 0x%x\n", i, tmp);
+ debug("SATA port %d status: 0x%x\n", i, tmp);
if ((tmp & 0xf) == 0x03)
probe_ent->link_port_map |= (0x01 << i);
}
@@ -202,12 +296,13 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
u16 cc;
#endif
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
- u32 vers, cap, impl, speed;
+ u32 vers, cap, cap2, impl, speed;
const char *speed_s;
const char *scc_s;
vers = readl(mmio + HOST_VERSION);
cap = probe_ent->cap;
+ cap2 = readl(mmio + HOST_CAP2);
impl = probe_ent->port_map;
speed = (cap >> 20) & 0xf;
@@ -215,6 +310,8 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
speed_s = "1.5";
else if (speed == 2)
speed_s = "3";
+ else if (speed == 3)
+ speed_s = "6";
else
speed_s = "?";
@@ -240,8 +337,9 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
((cap >> 8) & 0x1f) + 1, (cap & 0x1f) + 1, speed_s, impl, scc_s);
printf("flags: "
- "%s%s%s%s%s%s"
- "%s%s%s%s%s%s%s\n",
+ "%s%s%s%s%s%s%s"
+ "%s%s%s%s%s%s%s"
+ "%s%s%s%s%s%s\n",
cap & (1 << 31) ? "64bit " : "",
cap & (1 << 30) ? "ncq " : "",
cap & (1 << 28) ? "ilck " : "",
@@ -252,9 +350,16 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
cap & (1 << 19) ? "nz " : "",
cap & (1 << 18) ? "only " : "",
cap & (1 << 17) ? "pmp " : "",
+ cap & (1 << 16) ? "fbss " : "",
cap & (1 << 15) ? "pio " : "",
cap & (1 << 14) ? "slum " : "",
- cap & (1 << 13) ? "part " : "");
+ cap & (1 << 13) ? "part " : "",
+ cap & (1 << 7) ? "ccc " : "",
+ cap & (1 << 6) ? "ems " : "",
+ cap & (1 << 5) ? "sxs " : "",
+ cap2 & (1 << 2) ? "apst " : "",
+ cap2 & (1 << 1) ? "nvmp " : "",
+ cap2 & (1 << 0) ? "boh " : "");
}
#ifndef CONFIG_SCSI_AHCI_PLAT
@@ -277,8 +382,8 @@ static int ahci_init_one(pci_dev_t pdev)
probe_ent->pio_mask = 0x1f;
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
- probe_ent->mmio_base = (u32)pci_map_bar(pdev, AHCI_PCI_BAR,
- PCI_REGION_MEM);
+ pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base);
+ debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base);
/* Take from kernel:
* JMicron-specific fixup:
@@ -342,6 +447,7 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts)
}
+#ifdef CONFIG_AHCI_SETFEATURES_XFER
static void ahci_set_feature(u8 port)
{
struct ahci_ioports *pp = &(probe_ent->port[port]);
@@ -349,23 +455,26 @@ static void ahci_set_feature(u8 port)
u32 cmd_fis_len = 5; /* five dwords */
u8 fis[20];
- /*set feature */
- memset(fis, 0, 20);
+ /* set feature */
+ memset(fis, 0, sizeof(fis));
fis[0] = 0x27;
fis[1] = 1 << 7;
fis[2] = ATA_CMD_SETF;
fis[3] = SETFEATURES_XFER;
fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
- memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
+ memcpy((unsigned char *)pp->cmd_tbl, fis, sizeof(fis));
ahci_fill_cmd_slot(pp, cmd_fis_len);
+ ahci_dcache_flush_sata_cmd(pp);
writel(1, port_mmio + PORT_CMD_ISSUE);
readl(port_mmio + PORT_CMD_ISSUE);
- if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
- printf("set feature error!\n");
+ if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
+ WAIT_MS_DATAIO, 0x1)) {
+ printf("set feature error on port %d!\n", port);
}
}
+#endif
static int ahci_port_start(u8 port)
@@ -397,25 +506,27 @@ static int ahci_port_start(u8 port)
* First item in chunk of DMA memory: 32-slot command table,
* 32 bytes each in size
*/
- pp->cmd_slot = (struct ahci_cmd_hdr *)mem;
- debug("cmd_slot = %p\n", pp->cmd_slot);
+ pp->cmd_slot =
+ (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem);
+ debug("cmd_slot = 0x%x\n", (unsigned)pp->cmd_slot);
mem += (AHCI_CMD_SLOT_SZ + 224);
/*
* Second item: Received-FIS area
*/
- pp->rx_fis = mem;
+ pp->rx_fis = virt_to_phys((void *)mem);
mem += AHCI_RX_FIS_SZ;
/*
* Third item: data area for storing a single command
* and its scatter-gather table
*/
- pp->cmd_tbl = mem;
+ pp->cmd_tbl = virt_to_phys((void *)mem);
debug("cmd_tbl_dma = 0x%x\n", pp->cmd_tbl);
mem += AHCI_CMD_TBL_HDR;
- pp->cmd_tbl_sg = (struct ahci_sg *)mem;
+ pp->cmd_tbl_sg =
+ (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem);
writel_with_flush((u32) pp->cmd_slot, port_mmio + PORT_LST_ADDR);
@@ -431,8 +542,8 @@ static int ahci_port_start(u8 port)
}
-static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
- int buf_len)
+static int ahci_device_data_io(u8 port, u8 *fis, int fis_len, u8 *buf,
+ int buf_len, u8 is_write)
{
struct ahci_ioports *pp = &(probe_ent->port[port]);
@@ -441,10 +552,10 @@ static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
u32 port_status;
int sg_count;
- debug("Enter get_ahci_device_data: for port %d\n", port);
+ debug("Enter %s: for port %d\n", __func__, port);
if (port > probe_ent->n_ports) {
- printf("Invaild port number %d\n", port);
+ printf("Invalid port number %d\n", port);
return -1;
}
@@ -457,17 +568,22 @@ static int get_ahci_device_data(u8 port, u8 *fis, int fis_len, u8 *buf,
memcpy((unsigned char *)pp->cmd_tbl, fis, fis_len);
sg_count = ahci_fill_sg(port, buf, buf_len);
- opts = (fis_len >> 2) | (sg_count << 16);
+ opts = (fis_len >> 2) | (sg_count << 16) | (is_write << 6);
ahci_fill_cmd_slot(pp, opts);
+ ahci_dcache_flush_sata_cmd(pp);
+ ahci_dcache_flush_range((unsigned)buf, (unsigned)buf_len);
+
writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
- if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 150, 0x1)) {
+ if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
+ WAIT_MS_DATAIO, 0x1)) {
printf("timeout exit!\n");
return -1;
}
- debug("get_ahci_device_data: %d byte transferred.\n",
- pp->cmd_slot->status);
+
+ ahci_dcache_invalidate_range((unsigned)buf, (unsigned)buf_len);
+ debug("%s: %d byte transferred.\n", __func__, pp->cmd_slot->status);
return 0;
}
@@ -526,7 +642,7 @@ static int ata_scsiop_inquiry(ccb *pccb)
if (pccb->datalen <= 35)
return 0;
- memset(fis, 0, 20);
+ memset(fis, 0, sizeof(fis));
/* Construct the FIS */
fis[0] = 0x27; /* Host to device FIS. */
fis[1] = 1 << 7; /* Command FIS. */
@@ -537,8 +653,8 @@ static int ata_scsiop_inquiry(ccb *pccb)
if (!(tmpid = malloc(sizeof(hd_driveid_t))))
return -ENOMEM;
- if (get_ahci_device_data(port, (u8 *) & fis, 20,
- tmpid, sizeof(hd_driveid_t))) {
+ if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), tmpid,
+ sizeof(hd_driveid_t), 0)) {
debug("scsi_ahci: SCSI inquiry command failure.\n");
return -EIO;
}
@@ -557,46 +673,91 @@ static int ata_scsiop_inquiry(ccb *pccb)
/*
- * SCSI READ10 command operation.
+ * SCSI READ10/WRITE10 command operation.
*/
-static int ata_scsiop_read10(ccb * pccb)
+static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
{
- u32 len = 0;
+ u32 lba = 0;
+ u16 blocks = 0;
u8 fis[20];
+ u8 *user_buffer = pccb->pdata;
+ u32 user_buffer_size = pccb->datalen;
- len = (((u32) pccb->cmd[7]) << 8) | ((u32) pccb->cmd[8]);
+ /* Retrieve the base LBA number from the ccb structure. */
+ memcpy(&lba, pccb->cmd + 2, sizeof(lba));
+ lba = be32_to_cpu(lba);
- /* For 10-byte and 16-byte SCSI R/W commands, transfer
+ /*
+ * And the number of blocks.
+ *
+ * For 10-byte and 16-byte SCSI R/W commands, transfer
* length 0 means transfer 0 block of data.
* However, for ATA R/W commands, sector count 0 means
* 256 or 65536 sectors, not 0 sectors as in SCSI.
*
* WARNING: one or two older ATA drives treat 0 as 0...
*/
- if (!len)
- return 0;
- memset(fis, 0, 20);
+ blocks = (((u16)pccb->cmd[7]) << 8) | ((u16) pccb->cmd[8]);
- /* Construct the FIS */
- fis[0] = 0x27; /* Host to device FIS. */
- fis[1] = 1 << 7; /* Command FIS. */
- fis[2] = ATA_CMD_RD_DMA; /* Command byte. */
-
- /* LBA address, only support LBA28 in this driver */
- fis[4] = pccb->cmd[5];
- fis[5] = pccb->cmd[4];
- fis[6] = pccb->cmd[3];
- fis[7] = (pccb->cmd[2] & 0x0f) | 0xe0;
-
- /* Sector Count */
- fis[12] = pccb->cmd[8];
- fis[13] = pccb->cmd[7];
-
- /* Read from ahci */
- if (get_ahci_device_data(pccb->target, (u8 *) & fis, 20,
- pccb->pdata, pccb->datalen)) {
- debug("scsi_ahci: SCSI READ10 command failure.\n");
- return -EIO;
+ debug("scsi_ahci: %s %d blocks starting from lba 0x%x\n",
+ is_write ? "write" : "read", (unsigned)lba, blocks);
+
+ /* Preset the FIS */
+ memset(fis, 0, sizeof(fis));
+ fis[0] = 0x27; /* Host to device FIS. */
+ fis[1] = 1 << 7; /* Command FIS. */
+ /* Command byte (read/write). */
+ fis[2] = is_write ? ATA_CMD_WRITE_EXT : ATA_CMD_READ_EXT;
+
+ while (blocks) {
+ u16 now_blocks; /* number of blocks per iteration */
+ u32 transfer_size; /* number of bytes per iteration */
+
+ now_blocks = min(MAX_SATA_BLOCKS_READ_WRITE, blocks);
+
+ transfer_size = ATA_BLOCKSIZE * now_blocks;
+ if (transfer_size > user_buffer_size) {
+ printf("scsi_ahci: Error: buffer too small.\n");
+ return -EIO;
+ }
+
+ /* LBA48 SATA command but only use 32bit address range within
+ * that. The next smaller command range (28bit) is too small.
+ */
+ fis[4] = (lba >> 0) & 0xff;
+ fis[5] = (lba >> 8) & 0xff;
+ fis[6] = (lba >> 16) & 0xff;
+ fis[7] = 1 << 6; /* device reg: set LBA mode */
+ fis[8] = ((lba >> 24) & 0xff);
+ fis[3] = 0xe0; /* features */
+
+ /* Block (sector) count */
+ fis[12] = (now_blocks >> 0) & 0xff;
+ fis[13] = (now_blocks >> 8) & 0xff;
+
+ /* Read/Write from ahci */
+ if (ahci_device_data_io(pccb->target, (u8 *) &fis, sizeof(fis),
+ user_buffer, user_buffer_size,
+ is_write)) {
+ debug("scsi_ahci: SCSI %s10 command failure.\n",
+ is_write ? "WRITE" : "READ");
+ return -EIO;
+ }
+
+ /* If this transaction is a write, do a following flush.
+ * Writes in u-boot are so rare, and the logic to know when is
+ * the last write and do a flush only there is sufficiently
+ * difficult. Just do a flush after every write. This incurs,
+ * usually, one extra flush when the rare writes do happen.
+ */
+ if (is_write) {
+ if (-EIO == ata_io_flush(pccb->target))
+ return -EIO;
+ }
+ user_buffer += transfer_size;
+ user_buffer_size -= transfer_size;
+ blocks -= now_blocks;
+ lba += now_blocks;
}
return 0;
@@ -609,6 +770,7 @@ static int ata_scsiop_read10(ccb * pccb)
static int ata_scsiop_read_capacity10(ccb *pccb)
{
u32 cap;
+ u32 block_size;
if (!ataid[pccb->target]) {
printf("scsi_ahci: SCSI READ CAPACITY10 command failure. "
@@ -618,11 +780,52 @@ static int ata_scsiop_read_capacity10(ccb *pccb)
}
cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
+ if (cap == 0xfffffff) {
+ unsigned short *cap48 = ataid[pccb->target]->lba48_capacity;
+ if (cap48[2] || cap48[3]) {
+ cap = 0xffffffff;
+ } else {
+ cap = (le16_to_cpu(cap48[1]) << 16) |
+ (le16_to_cpu(cap48[0]));
+ }
+ }
+
+ cap = cpu_to_be32(cap);
+ memcpy(pccb->pdata, &cap, sizeof(cap));
+
+ block_size = cpu_to_be32((u32)512);
+ memcpy(&pccb->pdata[4], &block_size, 4);
+
+ return 0;
+}
+
+
+/*
+ * SCSI READ CAPACITY16 command operation.
+ */
+static int ata_scsiop_read_capacity16(ccb *pccb)
+{
+ u64 cap;
+ u64 block_size;
+
+ if (!ataid[pccb->target]) {
+ printf("scsi_ahci: SCSI READ CAPACITY16 command failure. "
+ "\tNo ATA info!\n"
+ "\tPlease run SCSI commmand INQUIRY firstly!\n");
+ return -EPERM;
+ }
+
+ cap = le32_to_cpu(ataid[pccb->target]->lba_capacity);
+ if (cap == 0xfffffff) {
+ memcpy(&cap, ataid[pccb->target]->lba48_capacity, sizeof(cap));
+ cap = le64_to_cpu(cap);
+ }
+
+ cap = cpu_to_be64(cap);
memcpy(pccb->pdata, &cap, sizeof(cap));
- pccb->pdata[4] = pccb->pdata[5] = 0;
- pccb->pdata[6] = 512 >> 8;
- pccb->pdata[7] = 512 & 0xff;
+ block_size = cpu_to_be64((u64)512);
+ memcpy(&pccb->pdata[8], &block_size, 8);
return 0;
}
@@ -643,11 +846,17 @@ int scsi_exec(ccb *pccb)
switch (pccb->cmd[0]) {
case SCSI_READ10:
- ret = ata_scsiop_read10(pccb);
+ ret = ata_scsiop_read_write(pccb, 0);
break;
- case SCSI_RD_CAPAC:
+ case SCSI_WRITE10:
+ ret = ata_scsiop_read_write(pccb, 1);
+ break;
+ case SCSI_RD_CAPAC10:
ret = ata_scsiop_read_capacity10(pccb);
break;
+ case SCSI_RD_CAPAC16:
+ ret = ata_scsiop_read_capacity16(pccb);
+ break;
case SCSI_TST_U_RDY:
ret = ata_scsiop_test_unit_ready(pccb);
break;
@@ -685,7 +894,9 @@ void scsi_low_level_init(int busdevfunc)
printf("Can not start port %d\n", i);
continue;
}
+#ifdef CONFIG_AHCI_SETFEATURES_XFER
ahci_set_feature((u8) i);
+#endif
}
}
}
@@ -726,7 +937,9 @@ int ahci_init(u32 base)
printf("Can not start port %d\n", i);
continue;
}
+#ifdef CONFIG_AHCI_SETFEATURES_XFER
ahci_set_feature((u8) i);
+#endif
}
}
err_out:
@@ -734,6 +947,42 @@ err_out:
}
#endif
+/*
+ * In the general case of generic rotating media it makes sense to have a
+ * flush capability. It probably even makes sense in the case of SSDs because
+ * one cannot always know for sure what kind of internal cache/flush mechanism
+ * is embodied therein. At first it was planned to invoke this after the last
+ * write to disk and before rebooting. In practice, knowing, a priori, which
+ * is the last write is difficult. Because writing to the disk in u-boot is
+ * very rare, this flush command will be invoked after every block write.
+ */
+static int ata_io_flush(u8 port)
+{
+ u8 fis[20];
+ struct ahci_ioports *pp = &(probe_ent->port[port]);
+ volatile u8 *port_mmio = (volatile u8 *)pp->port_mmio;
+ u32 cmd_fis_len = 5; /* five dwords */
+
+ /* Preset the FIS */
+ memset(fis, 0, 20);
+ fis[0] = 0x27; /* Host to device FIS. */
+ fis[1] = 1 << 7; /* Command FIS. */
+ fis[2] = ATA_CMD_FLUSH_EXT;
+
+ memcpy((unsigned char *)pp->cmd_tbl, fis, 20);
+ ahci_fill_cmd_slot(pp, cmd_fis_len);
+ writel_with_flush(1, port_mmio + PORT_CMD_ISSUE);
+
+ if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE,
+ WAIT_MS_FLUSH, 0x1)) {
+ debug("scsi_ahci: flush command timeout on port %d.\n", port);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
void scsi_bus_reset(void)
{
/*Not implement*/
diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c
index fda3389..1f9d7b0 100644
--- a/drivers/block/fsl_sata.c
+++ b/drivers/block/fsl_sata.c
@@ -56,25 +56,6 @@ static inline void sdelay(unsigned long sec)
mdelay(1000);
}
-void dprint_buffer(unsigned char *buf, int len)
-{
- int i, j;
-
- i = 0;
- j = 0;
- printf("\n\r");
-
- for (i = 0; i < len; i++) {
- printf("%02x ", *buf++);
- j++;
- if (j == 16) {
- printf("\n\r");
- j = 0;
- }
- }
- printf("\n\r");
-}
-
static void fsl_sata_dump_sfis(struct sata_fis_d2h *s)
{
printf("Status FIS dump:\n\r");
@@ -94,7 +75,7 @@ static void fsl_sata_dump_sfis(struct sata_fis_d2h *s)
printf("sector_count_exp: %02x\n\r", s->sector_count_exp);
}
-static int ata_wait_register(volatile unsigned *addr, u32 mask,
+static int ata_wait_register(unsigned __iomem *addr, u32 mask,
u32 val, u32 timeout_msec)
{
int i;
@@ -112,7 +93,7 @@ int init_sata(int dev)
cmd_hdr_tbl_t *cmd_hdr;
u32 cda;
u32 val32;
- fsl_sata_reg_t *reg;
+ fsl_sata_reg_t __iomem *reg;
u32 sig;
int i;
fsl_sata_t *sata;
@@ -287,42 +268,7 @@ int init_sata(int dev)
return 0;
}
-/* Hardware reset, like Power-on and COMRESET */
-void fsl_sata_hardware_reset(u32 reg_base)
-{
- fsl_sata_reg_t *reg = (fsl_sata_reg_t *)reg_base;
- u32 scontrol;
-
- /* Disable the SATA interface and put PHY offline */
- scontrol = in_le32(&reg->scontrol);
- scontrol = (scontrol & 0x0f0) | 0x304;
- out_le32(&reg->scontrol, scontrol);
-
- /* No speed strict */
- scontrol = in_le32(&reg->scontrol);
- scontrol = scontrol & ~0x0f0;
- out_le32(&reg->scontrol, scontrol);
-
- /* Issue PHY wake/reset, Hardware_reset_asserted */
- scontrol = in_le32(&reg->scontrol);
- scontrol = (scontrol & 0x0f0) | 0x301;
- out_le32(&reg->scontrol, scontrol);
-
- mdelay(100);
-
- /* Resume PHY, COMRESET negated, the device initialize hardware
- * and execute diagnostics, send good status-signature to host,
- * which is D2H register FIS, and then the device enter idle state.
- */
- scontrol = in_le32(&reg->scontrol);
- scontrol = (scontrol & 0x0f0) | 0x300;
- out_le32(&reg->scontrol, scontrol);
-
- mdelay(100);
- return;
-}
-
-static void fsl_sata_dump_regs(fsl_sata_reg_t *reg)
+static void fsl_sata_dump_regs(fsl_sata_reg_t __iomem *reg)
{
printf("\n\rSATA: %08x\n\r", (u32)reg);
printf("CQR: %08x\n\r", in_le32(&reg->cqr));
@@ -363,7 +309,7 @@ static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct sata_fis_h2d *cfis
u32 prde_count;
u32 val32;
u32 ttl;
- fsl_sata_reg_t *reg = sata->reg_base;
+ fsl_sata_reg_t __iomem *reg = sata->reg_base;
int i;
/* Check xfer length */
@@ -620,7 +566,7 @@ static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_wr
return blkcnt;
}
-void fsl_sata_flush_cache(int dev)
+static void fsl_sata_flush_cache(int dev)
{
fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
struct sata_fis_h2d h2d, *cfis = &h2d;
@@ -664,7 +610,8 @@ static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int i
return blkcnt;
}
-u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+static u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer,
+ int is_write)
{
fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
struct sata_fis_h2d h2d, *cfis = &h2d;
@@ -707,7 +654,7 @@ u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write
return blkcnt;
}
-void fsl_sata_flush_cache_ext(int dev)
+static void fsl_sata_flush_cache_ext(int dev)
{
fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
struct sata_fis_h2d h2d, *cfis = &h2d;
@@ -721,12 +668,6 @@ void fsl_sata_flush_cache_ext(int dev)
fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
}
-/* Software reset, set SRST of the Device Control register */
-void fsl_sata_software_reset(int dev)
-{
- return;
-}
-
static void fsl_sata_init_wcache(int dev, u16 *id)
{
fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
@@ -757,7 +698,7 @@ static int fsl_sata_get_flush_ext(int dev)
return sata->flush_ext;
}
-u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
+static u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
const void *buffer, int is_write)
{
u32 start, blks;
@@ -792,8 +733,8 @@ u32 ata_low_level_rw_lba48(int dev, u32 blknr, lbaint_t blkcnt,
return blkcnt;
}
-u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt, const void *buffer,
- int is_write)
+static u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt,
+ const void *buffer, int is_write)
{
u32 start, blks;
u8 *addr;
diff --git a/drivers/block/fsl_sata.h b/drivers/block/fsl_sata.h
index cecff68..a9c27bc 100644
--- a/drivers/block/fsl_sata.h
+++ b/drivers/block/fsl_sata.h
@@ -176,10 +176,11 @@ typedef struct fsl_sata_reg {
* Command Header Entry
*/
typedef struct cmd_hdr_entry {
- u32 cda; /* Command Descriptor Address, 4 bytes aligned */
- u32 prde_fis_len; /* Number of PRD entries and FIS length */
- u32 ttl; /* Total transfer length */
- u32 attribute; /* the attribute of command */
+ __le32 cda; /* Command Descriptor Address,
+ 4 bytes aligned */
+ __le32 prde_fis_len; /* Number of PRD entries and FIS length */
+ __le32 ttl; /* Total transfer length */
+ __le32 attribute; /* the attribute of command */
} __attribute__ ((packed)) cmd_hdr_entry_t;
#define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry)
@@ -230,10 +231,10 @@ typedef struct cmd_hdr_tbl {
* PRD entry - Physical Region Descriptor entry
*/
typedef struct prd_entry {
- u32 dba; /* Data base address, 4 bytes aligned */
+ __le32 dba; /* Data base address, 4 bytes aligned */
u32 res1;
u32 res2;
- u32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */
+ __le32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */
} __attribute__ ((packed)) prd_entry_t;
#define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry)
diff --git a/drivers/block/sata_sil.c b/drivers/block/sata_sil.c
index 245b872..b70f04d 100644
--- a/drivers/block/sata_sil.c
+++ b/drivers/block/sata_sil.c
@@ -27,6 +27,7 @@
#include <fis.h>
#include <sata.h>
#include <libata.h>
+#include <sata.h>
#include "sata_sil.h"
/* Convert sectorsize to wordsize */
@@ -369,8 +370,8 @@ static ulong sil_sata_rw_cmd_ext(int dev, ulong start, ulong blkcnt,
return blkcnt;
}
-ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt,
- const void *buffer, int is_write)
+static ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt,
+ const void *buffer, int is_write)
{
ulong start, blks, max_blks;
u8 *addr;
@@ -397,8 +398,8 @@ ulong sil_sata_rw_lba28(int dev, ulong blknr, lbaint_t blkcnt,
return blkcnt;
}
-ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt,
- const void *buffer, int is_write)
+static ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt,
+ const void *buffer, int is_write)
{
ulong start, blks, max_blks;
u8 *addr;
@@ -427,7 +428,7 @@ ulong sil_sata_rw_lba48(int dev, ulong blknr, lbaint_t blkcnt,
return blkcnt;
}
-void sil_sata_cmd_flush_cache(int dev)
+static void sil_sata_cmd_flush_cache(int dev)
{
struct sil_cmd_block cmdb, *pcmd = &cmdb;
@@ -439,7 +440,7 @@ void sil_sata_cmd_flush_cache(int dev)
sil_exec_cmd(dev, pcmd, 0);
}
-void sil_sata_cmd_flush_cache_ext(int dev)
+static void sil_sata_cmd_flush_cache_ext(int dev)
{
struct sil_cmd_block cmdb, *pcmd = &cmdb;
diff --git a/drivers/gpio/mpc83xx_gpio.c b/drivers/gpio/mpc83xx_gpio.c
index a9afcb2..e167852 100644
--- a/drivers/gpio/mpc83xx_gpio.c
+++ b/drivers/gpio/mpc83xx_gpio.c
@@ -163,7 +163,7 @@ int gpio_set_value(unsigned gpio, int value)
}
/* Configure GPIO registers early */
-void mpc83xx_gpio_init_f()
+void mpc83xx_gpio_init_f(void)
{
immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
@@ -187,7 +187,7 @@ void mpc83xx_gpio_init_f()
}
/* Initialize GPIO soft-copies */
-void mpc83xx_gpio_init_r()
+void mpc83xx_gpio_init_r(void)
{
#if MPC83XX_GPIO_CTRLRS >= 1
gpio_output_value[0] = CONFIG_MPC83XX_GPIO_0_INIT_VALUE;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 9800667..04fa5f0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -110,7 +110,7 @@ static struct {
/* Maximum number of output characters that an ANSI sequence expands to */
#define ANSI_CHAR_MAX 3
-int input_queue_ascii(struct input_config *config, int ch)
+static int input_queue_ascii(struct input_config *config, int ch)
{
if (config->fifo_in + 1 == INPUT_BUFFER_LEN) {
if (!config->fifo_out)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 3f8d30d..e93e38a 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -68,7 +68,7 @@ struct fsl_esdhc {
};
/* Return the XFERTYP flags for a given command and data packet */
-uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
+static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
{
uint xfertyp = 0;
@@ -410,12 +410,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
return 0;
}
-void set_sysctl(struct mmc *mmc, uint clock)
+static void set_sysctl(struct mmc *mmc, uint clock)
{
- int sdhc_clk = gd->sdhc_clk;
int div, pre_div;
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+ int sdhc_clk = cfg->sdhc_clk;
uint clk;
if (clock < mmc->f_min)
@@ -598,6 +598,7 @@ int fsl_esdhc_mmc_init(bd_t *bis)
cfg = malloc(sizeof(struct fsl_esdhc_cfg));
memset(cfg, 0, sizeof(struct fsl_esdhc_cfg));
cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
+ cfg->sdhc_clk = gd->sdhc_clk;
return fsl_esdhc_initialize(bis, cfg);
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5fbf956..5ffd8c5 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -47,7 +47,8 @@ int __board_mmc_getcd(struct mmc *mmc) {
int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
alias("__board_mmc_getcd")));
-int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
{
struct mmc_data backup;
int ret;
@@ -108,7 +109,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
return ret;
}
-int mmc_send_status(struct mmc *mmc, int timeout)
+static int mmc_send_status(struct mmc *mmc, int timeout)
{
struct mmc_cmd cmd;
int err, retries = 5;
@@ -152,7 +153,7 @@ int mmc_send_status(struct mmc *mmc, int timeout)
return 0;
}
-int mmc_set_blocklen(struct mmc *mmc, int len)
+static int mmc_set_blocklen(struct mmc *mmc, int len)
{
struct mmc_cmd cmd;
@@ -345,7 +346,8 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
return blkcnt;
}
-int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
+static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
+ lbaint_t blkcnt)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -415,7 +417,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
return blkcnt;
}
-int mmc_go_idle(struct mmc* mmc)
+static int mmc_go_idle(struct mmc *mmc)
{
struct mmc_cmd cmd;
int err;
@@ -436,8 +438,7 @@ int mmc_go_idle(struct mmc* mmc)
return 0;
}
-int
-sd_send_op_cond(struct mmc *mmc)
+static int sd_send_op_cond(struct mmc *mmc)
{
int timeout = 1000;
int err;
@@ -502,7 +503,7 @@ sd_send_op_cond(struct mmc *mmc)
return 0;
}
-int mmc_send_op_cond(struct mmc *mmc)
+static int mmc_send_op_cond(struct mmc *mmc)
{
int timeout = 10000;
struct mmc_cmd cmd;
@@ -566,7 +567,7 @@ int mmc_send_op_cond(struct mmc *mmc)
}
-int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
+static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -588,7 +589,7 @@ int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
}
-int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
{
struct mmc_cmd cmd;
int timeout = 1000;
@@ -610,7 +611,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
}
-int mmc_change_freq(struct mmc *mmc)
+static int mmc_change_freq(struct mmc *mmc)
{
ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
char cardtype;
@@ -680,7 +681,7 @@ int mmc_getcd(struct mmc *mmc)
return cd;
}
-int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
+static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -701,7 +702,7 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
}
-int sd_change_freq(struct mmc *mmc)
+static int sd_change_freq(struct mmc *mmc)
{
int err;
struct mmc_cmd cmd;
@@ -840,7 +841,7 @@ static const int multipliers[] = {
80,
};
-void mmc_set_ios(struct mmc *mmc)
+static void mmc_set_ios(struct mmc *mmc)
{
mmc->set_ios(mmc);
}
@@ -858,14 +859,14 @@ void mmc_set_clock(struct mmc *mmc, uint clock)
mmc_set_ios(mmc);
}
-void mmc_set_bus_width(struct mmc *mmc, uint width)
+static void mmc_set_bus_width(struct mmc *mmc, uint width)
{
mmc->bus_width = width;
mmc_set_ios(mmc);
}
-int mmc_startup(struct mmc *mmc)
+static int mmc_startup(struct mmc *mmc)
{
int err, width;
uint mult, freq;
@@ -1013,7 +1014,7 @@ int mmc_startup(struct mmc *mmc)
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[EXT_CSD_REV] >= 2)) {
+ if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
/*
* According to the JEDEC Standard, the value of
* ext_csd's capacity is valid if the value is more
@@ -1148,7 +1149,7 @@ int mmc_startup(struct mmc *mmc)
return 0;
}
-int mmc_send_if_cond(struct mmc *mmc)
+static int mmc_send_if_cond(struct mmc *mmc)
{
struct mmc_cmd cmd;
int err;
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 43140f3..b2dfc53 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -752,8 +752,8 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
*/
static flash_sect_t find_sector (flash_info_t * info, ulong addr)
{
- static flash_sect_t saved_sector = 0; /* previously found sector */
- static flash_info_t *saved_info = 0; /* previously used flash bank */
+ static flash_sect_t saved_sector; /* previously found sector */
+ static flash_info_t *saved_info; /* previously used flash bank */
flash_sect_t sector = saved_sector;
if ((info != saved_info) || (sector >= info->sector_count))
@@ -1147,8 +1147,9 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
}
if (use_flash_status_poll(info)) {
- cfiword_t cword = (cfiword_t)0xffffffffffffffffULL;
+ cfiword_t cword;
void *dest;
+ cword.ll = 0xffffffffffffffffULL;
dest = flash_map(info, sect, 0);
st = flash_status_poll(info, &cword, dest,
info->erase_blk_tout, "erase");
@@ -1430,8 +1431,8 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot)
{
- if ((info->manufacturer_id == (uchar)INTEL_MANUFACT) &&
- (info->device_id == NUMONYX_256MBIT)) {
+ if (info->manufacturer_id == ((INTEL_MANUFACT & FLASH_VENDMASK) >> 16)
+ && info->device_id == NUMONYX_256MBIT) {
/*
* see errata called
* "Numonyx Axcell P33/P30 Specification Update" :)
@@ -1487,7 +1488,8 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
case CFI_CMDSET_AMD_EXTENDED:
case CFI_CMDSET_AMD_STANDARD:
/* U-Boot only checks the first byte */
- if (info->manufacturer_id == (uchar)ATM_MANUFACT) {
+ if (info->manufacturer_id ==
+ ((ATM_MANUFACT & FLASH_VENDMASK) >> 16)) {
if (prot) {
flash_unlock_seq (info, 0);
flash_write_cmd (info, 0,
@@ -1505,7 +1507,8 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
0, ATM_CMD_UNLOCK_SECT);
}
}
- if (info->manufacturer_id == (uchar)AMD_MANUFACT) {
+ if (info->manufacturer_id ==
+ ((AMD_MANUFACT & FLASH_VENDMASK) >> 16)) {
int flag = disable_interrupts();
int lock_flag;
@@ -1735,7 +1738,8 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
#ifdef CONFIG_SYS_FLASH_PROTECTION
- if (info->ext_addr && info->manufacturer_id == (uchar)AMD_MANUFACT) {
+ if (info->ext_addr && info->manufacturer_id ==
+ ((AMD_MANUFACT & FLASH_VENDMASK) >> 16)) {
ushort spus;
/* read sector protect/unprotect scheme */
@@ -1854,7 +1858,7 @@ static void flash_read_cfi (flash_info_t *info, void *buf,
p[i] = flash_read_uchar(info, start + i);
}
-void __flash_cmd_reset(flash_info_t *info)
+static void __flash_cmd_reset(flash_info_t *info)
{
/*
* We do not yet know what kind of commandset to use, so we issue
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 71f5027..d3b71a5 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2601,6 +2601,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
int *maf_id, int *dev_id,
const struct nand_flash_dev *type)
{
+ const char *name;
int i, maf_idx;
u8 id_data[8];
int ret;
@@ -2848,14 +2849,14 @@ ident_done:
chip->cmdfunc = nand_command_lp;
/* TODO onfi flash name */
- MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
- nand_manuf_ids[maf_idx].name,
+ name = type->name;
#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
- chip->onfi_version ? chip->onfi_params.model : type->name);
-#else
- type->name);
+ if (chip->onfi_version)
+ name = chip->onfi_params.model;
#endif
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:"
+ " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id,
+ nand_manuf_ids[maf_idx].name, name);
return type;
}
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 81f0e08..097cf62 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -39,6 +39,7 @@
#include <asm/errno.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand_ecc.h>
/* The PPC4xx NDFC uses Smart Media (SMC) bytes order */
#ifdef CONFIG_NAND_NDFC
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index 5408c51..4d94cc6 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -219,6 +219,34 @@ static uint8_t read_byte(struct mtd_info *mtd)
}
/**
+ * Read len bytes from the chip into a buffer
+ *
+ * @param mtd MTD device structure
+ * @param buf buffer to store data to
+ * @param len number of bytes to read
+ *
+ * Read function for 8bit bus-width
+ */
+static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i, s;
+ unsigned int reg;
+ struct nand_chip *chip = mtd->priv;
+ struct nand_drv *info = (struct nand_drv *)chip->priv;
+
+ for (i = 0; i < len; i += 4) {
+ s = (len - i) > 4 ? 4 : len - i;
+ writel(CMD_PIO | CMD_RX | CMD_A_VALID | CMD_CE0 |
+ ((s - 1) << CMD_TRANS_SIZE_SHIFT) | CMD_GO,
+ &info->reg->command);
+ if (!nand_waitfor_cmd_completion(info->reg))
+ puts("Command timeout during read_buf\n");
+ reg = readl(&info->reg->resp);
+ memcpy(buf + i, &reg, s);
+ }
+}
+
+/**
* Check NAND status to see if it is ready or not
*
* @param mtd MTD device structure
@@ -317,6 +345,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
switch (command) {
case NAND_CMD_READID:
writel(NAND_CMD_READID, &info->reg->cmd_reg1);
+ writel(column & 0xFF, &info->reg->addr_reg1);
writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_PIO
| CMD_RX |
((4 - 1) << CMD_TRANS_SIZE_SHIFT)
@@ -324,6 +353,12 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
&info->reg->command);
info->pio_byte_index = 0;
break;
+ case NAND_CMD_PARAM:
+ writel(NAND_CMD_PARAM, &info->reg->cmd_reg1);
+ writel(column & 0xFF, &info->reg->addr_reg1);
+ writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0,
+ &info->reg->command);
+ break;
case NAND_CMD_READ0:
writel(NAND_CMD_READ0, &info->reg->cmd_reg1);
writel(NAND_CMD_READSTART, &info->reg->cmd_reg2);
@@ -976,6 +1011,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum)
nand->options = LP_OPTIONS;
nand->cmdfunc = nand_command;
nand->read_byte = read_byte;
+ nand->read_buf = read_buf;
nand->ecc.read_page = nand_read_page_hwecc;
nand->ecc.write_page = nand_write_page_hwecc;
nand->ecc.read_page_raw = nand_read_page_raw;
diff --git a/drivers/mtd/ubi/crc32.c b/drivers/mtd/ubi/crc32.c
index a7e26b0..ab439b3 100644
--- a/drivers/mtd/ubi/crc32.c
+++ b/drivers/mtd/ubi/crc32.c
@@ -38,17 +38,9 @@
#include "crc32defs.h"
#define CRC_LE_BITS 8
-# define __force
-#ifndef __constant_cpu_to_le32
-#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x))
-#endif
-#ifndef __constant_le32_to_cpu
-#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x))
-#endif
-
#if CRC_LE_BITS == 8
-#define tole(x) __constant_cpu_to_le32(x)
-#define tobe(x) __constant_cpu_to_be32(x)
+#define tole(x) cpu_to_le32(x)
+#define tobe(x) cpu_to_be32(x)
#else
#define tole(x) (x)
#define tobe(x) (x)
diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c
index 82c787b..54b142f 100644
--- a/drivers/net/fm/eth.c
+++ b/drivers/net/fm/eth.c
@@ -46,7 +46,7 @@ static int num_controllers;
TBICR_FULL_DUPLEX | TBICR_SPEED1_SET)
/* Configure the TBI for SGMII operation */
-void dtsec_configure_serdes(struct fm_eth *priv)
+static void dtsec_configure_serdes(struct fm_eth *priv)
{
#ifdef CONFIG_SYS_FMAN_V3
u32 value;
diff --git a/drivers/net/fm/p1023.c b/drivers/net/fm/p1023.c
index 9765da5..387d2a3 100644
--- a/drivers/net/fm/p1023.c
+++ b/drivers/net/fm/p1023.c
@@ -23,7 +23,7 @@
#include <asm/immap_85xx.h>
#include <asm/fsl_serdes.h>
-u32 port_to_devdisr[] = {
+static u32 port_to_devdisr[] = {
[FM1_DTSEC1] = MPC85xx_DEVDISR_TSEC1,
[FM1_DTSEC2] = MPC85xx_DEVDISR_TSEC2,
};
diff --git a/drivers/net/fm/p4080.c b/drivers/net/fm/p4080.c
index 9dc6049..b04fd0f 100644
--- a/drivers/net/fm/p4080.c
+++ b/drivers/net/fm/p4080.c
@@ -23,7 +23,7 @@
#include <asm/immap_85xx.h>
#include <asm/fsl_serdes.h>
-u32 port_to_devdisr[] = {
+static u32 port_to_devdisr[] = {
[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
diff --git a/drivers/net/fm/p5020.c b/drivers/net/fm/p5020.c
index a7a6e43..5391044 100644
--- a/drivers/net/fm/p5020.c
+++ b/drivers/net/fm/p5020.c
@@ -23,7 +23,7 @@
#include <asm/immap_85xx.h>
#include <asm/fsl_serdes.h>
-u32 port_to_devdisr[] = {
+static u32 port_to_devdisr[] = {
[FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1,
[FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2,
[FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3,
diff --git a/drivers/net/fm/tgec_phy.c b/drivers/net/fm/tgec_phy.c
index 2d349ad..2be69d7 100644
--- a/drivers/net/fm/tgec_phy.c
+++ b/drivers/net/fm/tgec_phy.c
@@ -30,8 +30,8 @@
* until the write is done before it returns. All PHY configuration has to be
* done through the TSEC1 MIIM regs
*/
-int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
- int regnum, u16 value)
+static int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
+ int regnum, u16 value)
{
u32 mdio_ctl;
u32 stat_val;
@@ -72,8 +72,8 @@ int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
* Clears miimcom first. All PHY configuration has to be done through the
* TSEC1 MIIM regs
*/
-int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
- int regnum)
+static int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
+ int regnum)
{
u32 mdio_ctl;
u32 stat_val;
@@ -114,7 +114,7 @@ int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
return in_be32(&regs->mdio_data) & 0xffff;
}
-int tgec_mdio_reset(struct mii_dev *bus)
+static int tgec_mdio_reset(struct mii_dev *bus)
{
return 0;
}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0e1ced7..8bacbda 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -51,8 +51,6 @@
#include "macb.h"
-#define barrier() asm volatile("" ::: "memory")
-
#define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096
#define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128)
#define CONFIG_SYS_MACB_TX_RING_SIZE 16
diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c
index 798473d..9b3808b 100644
--- a/drivers/net/phy/atheros.c
+++ b/drivers/net/phy/atheros.c
@@ -30,7 +30,7 @@ static int ar8021_config(struct phy_device *phydev)
return 0;
}
-struct phy_driver AR8021_driver = {
+static struct phy_driver AR8021_driver = {
.name = "AR8021",
.uid = 0x4dd040,
.mask = 0xfffff0,
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index baef60f..1ffa791 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -43,7 +43,7 @@
* what is supported. Returns < 0 on error, 0 if the PHY's advertisement
* hasn't changed, and > 0 if it has changed.
*/
-int genphy_config_advert(struct phy_device *phydev)
+static int genphy_config_advert(struct phy_device *phydev)
{
u32 advertise;
int oldadv, adv;
@@ -118,7 +118,7 @@ int genphy_config_advert(struct phy_device *phydev)
* Description: Configures MII_BMCR to force speed/duplex
* to the values in phydev. Assumes that the values are valid.
*/
-int genphy_setup_forced(struct phy_device *phydev)
+static int genphy_setup_forced(struct phy_device *phydev)
{
int err;
int ctl = 0;
@@ -465,7 +465,7 @@ int phy_register(struct phy_driver *drv)
return 0;
}
-int phy_probe(struct phy_device *phydev)
+static int phy_probe(struct phy_device *phydev)
{
int err = 0;
@@ -488,7 +488,7 @@ static struct phy_driver *generic_for_interface(phy_interface_t interface)
return &genphy_driver;
}
-struct phy_driver *get_phy_driver(struct phy_device *phydev,
+static struct phy_driver *get_phy_driver(struct phy_device *phydev,
phy_interface_t interface)
{
struct list_head *entry;
@@ -505,8 +505,9 @@ struct phy_driver *get_phy_driver(struct phy_device *phydev,
return generic_for_interface(interface);
}
-struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id,
- phy_interface_t interface)
+static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
+ int phy_id,
+ phy_interface_t interface)
{
struct phy_device *dev;
@@ -549,7 +550,7 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id,
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, stores it in @phy_id and returns zero on success.
*/
-int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
{
int phy_reg;
@@ -581,8 +582,8 @@ int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, then allocates and returns the phy_device to represent it.
*/
-struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
- phy_interface_t interface)
+static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
+ phy_interface_t interface)
{
u32 phy_id = 0x1fffffff;
int i;
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 0a0f40d..6c5cb99 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -123,7 +123,7 @@ static int cis8204_config(struct phy_device *phydev)
}
/* Vitesse VSC8601 */
-int vsc8601_config(struct phy_device *phydev)
+static int vsc8601_config(struct phy_device *phydev)
{
/* Configure some basic stuff */
#ifdef CONFIG_SYS_VSC8601_SKEWFIX
diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c
index 6dc7ad5..1357ede 100644
--- a/drivers/net/smc91111.c
+++ b/drivers/net/smc91111.c
@@ -178,8 +178,6 @@ static void smc_phy_configure(struct eth_device *dev);
* inx,outx functions fixed this problem.
*/
-#define barrier() __asm__ __volatile__("": : :"memory")
-
static inline word SMC_inw(struct eth_device *dev, dword offset)
{
word v;
diff --git a/drivers/net/vsc7385.c b/drivers/net/vsc7385.c
index ada42c4..a5110e5 100644
--- a/drivers/net/vsc7385.c
+++ b/drivers/net/vsc7385.c
@@ -16,6 +16,7 @@
#include <common.h>
#include <asm/io.h>
#include <asm/errno.h>
+#include "vsc7385.h"
/*
* Upload a Vitesse VSC7385 firmware image to the hardware
diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c
index ea8d734..f53c2bf 100644
--- a/drivers/serial/s3c64xx.c
+++ b/drivers/serial/s3c64xx.c
@@ -40,8 +40,6 @@ DECLARE_GLOBAL_DATA_PTR;
#error "Bad: you didn't configure serial ..."
#endif
-#define barrier() asm volatile("" ::: "memory")
-
/*
* The coefficient, used to calculate the baudrate on S3C6400 UARTs is
* calculated as
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 4176e25..c1c0134 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -34,7 +34,7 @@
DECLARE_GLOBAL_DATA_PTR;
#if !defined(CONFIG_CONS_INDEX)
-#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
+#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 6)
#error "Invalid console index value."
#endif
@@ -46,12 +46,16 @@ DECLARE_GLOBAL_DATA_PTR;
#error "Console port 3 defined but not configured."
#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
#error "Console port 4 defined but not configured."
+#elif CONFIG_CONS_INDEX == 5 && !defined(CONFIG_SYS_NS16550_COM5)
+#error "Console port 5 defined but not configured."
+#elif CONFIG_CONS_INDEX == 6 && !defined(CONFIG_SYS_NS16550_COM6)
+#error "Console port 6 defined but not configured."
#endif
/* Note: The port number specified in the functions is 1 based.
* the array is 0 based.
*/
-static NS16550_t serial_ports[4] = {
+static NS16550_t serial_ports[6] = {
#ifdef CONFIG_SYS_NS16550_COM1
(NS16550_t)CONFIG_SYS_NS16550_COM1,
#else
@@ -68,7 +72,17 @@ static NS16550_t serial_ports[4] = {
NULL,
#endif
#ifdef CONFIG_SYS_NS16550_COM4
- (NS16550_t)CONFIG_SYS_NS16550_COM4
+ (NS16550_t)CONFIG_SYS_NS16550_COM4,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_NS16550_COM5
+ (NS16550_t)CONFIG_SYS_NS16550_COM5,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_NS16550_COM6
+ (NS16550_t)CONFIG_SYS_NS16550_COM6
#else
NULL
#endif
@@ -78,21 +92,33 @@ static NS16550_t serial_ports[4] = {
/* Multi serial device functions */
#define DECLARE_ESERIAL_FUNCTIONS(port) \
- static int eserial##port##_init (void) {\
- int clock_divisor; \
- clock_divisor = calc_divisor(serial_ports[port-1]); \
- NS16550_init(serial_ports[port-1], clock_divisor); \
- return(0);}\
- static void eserial##port##_setbrg (void) {\
- serial_setbrg_dev(port);}\
- static int eserial##port##_getc (void) {\
- return serial_getc_dev(port);}\
- static int eserial##port##_tstc (void) {\
- return serial_tstc_dev(port);}\
- static void eserial##port##_putc (const char c) {\
- serial_putc_dev(port, c);}\
- static void eserial##port##_puts (const char *s) {\
- serial_puts_dev(port, s);}
+ static int eserial##port##_init(void) \
+ { \
+ int clock_divisor; \
+ clock_divisor = calc_divisor(serial_ports[port-1]); \
+ NS16550_init(serial_ports[port-1], clock_divisor); \
+ return 0 ; \
+ } \
+ static void eserial##port##_setbrg(void) \
+ { \
+ serial_setbrg_dev(port); \
+ } \
+ static int eserial##port##_getc(void) \
+ { \
+ return serial_getc_dev(port); \
+ } \
+ static int eserial##port##_tstc(void) \
+ { \
+ return serial_tstc_dev(port); \
+ } \
+ static void eserial##port##_putc(const char c) \
+ { \
+ serial_putc_dev(port, c); \
+ } \
+ static void eserial##port##_puts(const char *s) \
+ { \
+ serial_puts_dev(port, s); \
+ }
/* Serial device descriptor */
#define INIT_ESERIAL_STRUCTURE(port, __name) { \
@@ -231,6 +257,12 @@ struct serial_device eserial3_device =
DECLARE_ESERIAL_FUNCTIONS(4);
struct serial_device eserial4_device =
INIT_ESERIAL_STRUCTURE(4, "eserial3");
+DECLARE_ESERIAL_FUNCTIONS(5);
+struct serial_device eserial5_device =
+ INIT_ESERIAL_STRUCTURE(5, "eserial4");
+DECLARE_ESERIAL_FUNCTIONS(6);
+struct serial_device eserial6_device =
+ INIT_ESERIAL_STRUCTURE(6, "eserial5");
__weak struct serial_device *default_serial_console(void)
{
@@ -242,6 +274,10 @@ __weak struct serial_device *default_serial_console(void)
return &eserial3_device;
#elif CONFIG_CONS_INDEX == 4
return &eserial4_device;
+#elif CONFIG_CONS_INDEX == 5
+ return &eserial5_device;
+#elif CONFIG_CONS_INDEX == 6
+ return &eserial6_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
@@ -261,4 +297,10 @@ void ns16550_serial_initialize(void)
#if defined(CONFIG_SYS_NS16550_COM4)
serial_register(&eserial4_device);
#endif
+#if defined(CONFIG_SYS_NS16550_COM5)
+ serial_register(&eserial5_device);
+#endif
+#if defined(CONFIG_SYS_NS16550_COM6)
+ serial_register(&eserial6_device);
+#endif
}
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 1e187e5..8b24e00 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1978,8 +1978,8 @@ static int is_eth_addr_valid(char *str)
p = q;
}
- if (i == 6) /* it looks ok */
- return 1;
+ /* Now check the contents. */
+ return is_valid_ether_addr(ea);
}
return 0;
}
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 9f7794f..9c67b63 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -385,6 +385,13 @@ static u32 eorx, fgx, bgx; /* color pats */
static int cfb_do_flush_cache;
+#ifdef CONFIG_CFB_CONSOLE_ANSI
+static char ansi_buf[10];
+static int ansi_buf_size;
+static int ansi_colors_need_revert;
+static int ansi_cursor_hidden;
+#endif
+
static const int video_font_draw_table8[] = {
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
@@ -768,9 +775,97 @@ static void console_back(void)
}
}
-static void console_newline(void)
+#ifdef CONFIG_CFB_CONSOLE_ANSI
+
+static void console_clear(void)
+{
+#ifdef VIDEO_HW_RECTFILL
+ video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */
+ 0, /* dest pos x */
+ video_logo_height, /* dest pos y */
+ VIDEO_VISIBLE_COLS, /* frame width */
+ VIDEO_VISIBLE_ROWS, /* frame height */
+ bgx /* fill color */
+ );
+#else
+ memsetl(CONSOLE_ROW_FIRST, CONSOLE_SIZE, bgx);
+#endif
+}
+
+static void console_cursor_fix(void)
+{
+ if (console_row < 0)
+ console_row = 0;
+ if (console_row >= CONSOLE_ROWS)
+ console_row = CONSOLE_ROWS - 1;
+ if (console_col < 0)
+ console_col = 0;
+ if (console_col >= CONSOLE_COLS)
+ console_col = CONSOLE_COLS - 1;
+}
+
+static void console_cursor_up(int n)
+{
+ console_row -= n;
+ console_cursor_fix();
+}
+
+static void console_cursor_down(int n)
+{
+ console_row += n;
+ console_cursor_fix();
+}
+
+static void console_cursor_left(int n)
+{
+ console_col -= n;
+ console_cursor_fix();
+}
+
+static void console_cursor_right(int n)
+{
+ console_col += n;
+ console_cursor_fix();
+}
+
+static void console_cursor_set_position(int row, int col)
+{
+ if (console_row != -1)
+ console_row = row;
+ if (console_col != -1)
+ console_col = col;
+ console_cursor_fix();
+}
+
+static void console_previousline(int n)
{
- console_row++;
+ /* FIXME: also scroll terminal ? */
+ console_row -= n;
+ console_cursor_fix();
+}
+
+static void console_swap_colors(void)
+{
+ eorx = fgx;
+ fgx = bgx;
+ bgx = eorx;
+ eorx = fgx ^ bgx;
+}
+
+static inline int console_cursor_is_visible(void)
+{
+ return !ansi_cursor_hidden;
+}
+#else
+static inline int console_cursor_is_visible(void)
+{
+ return 1;
+}
+#endif
+
+static void console_newline(int n)
+{
+ console_row += n;
console_col = 0;
/* Check if we need to scroll the terminal */
@@ -779,7 +874,7 @@ static void console_newline(void)
console_scrollup();
/* Decrement row number */
- console_row--;
+ console_row = CONSOLE_ROWS - 1;
}
}
@@ -788,11 +883,12 @@ static void console_cr(void)
console_col = 0;
}
-void video_putc(const char c)
+static void parse_putc(const char c)
{
static int nl = 1;
- CURSOR_OFF;
+ if (console_cursor_is_visible())
+ CURSOR_OFF;
switch (c) {
case 13: /* back to first column */
@@ -801,7 +897,7 @@ void video_putc(const char c)
case '\n': /* next line */
if (console_col || (!console_col && nl))
- console_newline();
+ console_newline(1);
nl = 1;
break;
@@ -810,7 +906,7 @@ void video_putc(const char c)
console_col &= ~0x0007;
if (console_col >= CONSOLE_COLS)
- console_newline();
+ console_newline(1);
break;
case 8: /* backspace */
@@ -827,11 +923,225 @@ void video_putc(const char c)
/* check for newline */
if (console_col >= CONSOLE_COLS) {
- console_newline();
+ console_newline(1);
nl = 0;
}
}
- CURSOR_SET;
+
+ if (console_cursor_is_visible())
+ CURSOR_SET;
+}
+
+void video_putc(const char c)
+{
+#ifdef CONFIG_CFB_CONSOLE_ANSI
+ int i;
+
+ if (c == 27) {
+ for (i = 0; i < ansi_buf_size; ++i)
+ parse_putc(ansi_buf[i]);
+ ansi_buf[0] = 27;
+ ansi_buf_size = 1;
+ return;
+ }
+
+ if (ansi_buf_size > 0) {
+ /*
+ * 0 - ESC
+ * 1 - [
+ * 2 - num1
+ * 3 - ..
+ * 4 - ;
+ * 5 - num2
+ * 6 - ..
+ * - cchar
+ */
+ int next = 0;
+
+ int flush = 0;
+ int fail = 0;
+
+ int num1 = 0;
+ int num2 = 0;
+ int cchar = 0;
+
+ ansi_buf[ansi_buf_size++] = c;
+
+ if (ansi_buf_size >= sizeof(ansi_buf))
+ fail = 1;
+
+ for (i = 0; i < ansi_buf_size; ++i) {
+ if (fail)
+ break;
+
+ switch (next) {
+ case 0:
+ if (ansi_buf[i] == 27)
+ next = 1;
+ else
+ fail = 1;
+ break;
+
+ case 1:
+ if (ansi_buf[i] == '[')
+ next = 2;
+ else
+ fail = 1;
+ break;
+
+ case 2:
+ if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
+ num1 = ansi_buf[i]-'0';
+ next = 3;
+ } else if (ansi_buf[i] != '?') {
+ --i;
+ num1 = 1;
+ next = 4;
+ }
+ break;
+
+ case 3:
+ if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
+ num1 *= 10;
+ num1 += ansi_buf[i]-'0';
+ } else {
+ --i;
+ next = 4;
+ }
+ break;
+
+ case 4:
+ if (ansi_buf[i] != ';') {
+ --i;
+ next = 7;
+ } else
+ next = 5;
+ break;
+
+ case 5:
+ if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
+ num2 = ansi_buf[i]-'0';
+ next = 6;
+ } else
+ fail = 1;
+ break;
+
+ case 6:
+ if (ansi_buf[i] >= '0' && ansi_buf[i] <= '9') {
+ num2 *= 10;
+ num2 += ansi_buf[i]-'0';
+ } else {
+ --i;
+ next = 7;
+ }
+ break;
+
+ case 7:
+ if ((ansi_buf[i] >= 'A' && ansi_buf[i] <= 'H')
+ || ansi_buf[i] == 'J'
+ || ansi_buf[i] == 'K'
+ || ansi_buf[i] == 'h'
+ || ansi_buf[i] == 'l'
+ || ansi_buf[i] == 'm') {
+ cchar = ansi_buf[i];
+ flush = 1;
+ } else
+ fail = 1;
+ break;
+ }
+ }
+
+ if (fail) {
+ for (i = 0; i < ansi_buf_size; ++i)
+ parse_putc(ansi_buf[i]);
+ ansi_buf_size = 0;
+ return;
+ }
+
+ if (flush) {
+ if (!ansi_cursor_hidden)
+ CURSOR_OFF;
+ ansi_buf_size = 0;
+ switch (cchar) {
+ case 'A':
+ /* move cursor num1 rows up */
+ console_cursor_up(num1);
+ break;
+ case 'B':
+ /* move cursor num1 rows down */
+ console_cursor_down(num1);
+ break;
+ case 'C':
+ /* move cursor num1 columns forward */
+ console_cursor_right(num1);
+ break;
+ case 'D':
+ /* move cursor num1 columns back */
+ console_cursor_left(num1);
+ break;
+ case 'E':
+ /* move cursor num1 rows up at begin of row */
+ console_previousline(num1);
+ break;
+ case 'F':
+ /* move cursor num1 rows down at begin of row */
+ console_newline(num1);
+ break;
+ case 'G':
+ /* move cursor to column num1 */
+ console_cursor_set_position(-1, num1-1);
+ break;
+ case 'H':
+ /* move cursor to row num1, column num2 */
+ console_cursor_set_position(num1-1, num2-1);
+ break;
+ case 'J':
+ /* clear console and move cursor to 0, 0 */
+ console_clear();
+ console_cursor_set_position(0, 0);
+ break;
+ case 'K':
+ /* clear line */
+ if (num1 == 0)
+ console_clear_line(console_row,
+ console_col,
+ CONSOLE_COLS-1);
+ else if (num1 == 1)
+ console_clear_line(console_row,
+ 0, console_col);
+ else
+ console_clear_line(console_row,
+ 0, CONSOLE_COLS-1);
+ break;
+ case 'h':
+ ansi_cursor_hidden = 0;
+ break;
+ case 'l':
+ ansi_cursor_hidden = 1;
+ break;
+ case 'm':
+ if (num1 == 0) { /* reset swapped colors */
+ if (ansi_colors_need_revert) {
+ console_swap_colors();
+ ansi_colors_need_revert = 0;
+ }
+ } else if (num1 == 7) { /* once swap colors */
+ if (!ansi_colors_need_revert) {
+ console_swap_colors();
+ ansi_colors_need_revert = 1;
+ }
+ }
+ break;
+ }
+ if (!ansi_cursor_hidden)
+ CURSOR_SET;
+ }
+ } else {
+ parse_putc(c);
+ }
+#else
+ parse_putc(c);
+#endif
}
void video_puts(const char *s)
diff --git a/drivers/video/mxc_ipuv3_fb.c b/drivers/video/mxc_ipuv3_fb.c
index 47b336e..ace226c 100644
--- a/drivers/video/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc_ipuv3_fb.c
@@ -45,7 +45,7 @@ static int mxcfb_unmap_video_memory(struct fb_info *fbi);
/* graphics setup */
static GraphicDevice panel;
-static struct fb_videomode *gmode;
+static struct fb_videomode const *gmode;
static uint8_t gdisp;
static uint32_t gpixfmt;
@@ -503,7 +503,7 @@ static struct fb_info *mxcfb_init_fbinfo(void)
* @return Appropriate error code to the kernel common code
*/
static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
- struct fb_videomode *mode)
+ struct fb_videomode const *mode)
{
struct fb_info *fbi;
struct mxcfb_info *mxcfbi;
@@ -619,7 +619,9 @@ void video_set_lut(unsigned int index, /* color number */
return;
}
-int ipuv3_fb_init(struct fb_videomode *mode, uint8_t disp, uint32_t pixfmt)
+int ipuv3_fb_init(struct fb_videomode const *mode,
+ uint8_t disp,
+ uint32_t pixfmt)
{
gmode = mode;
gdisp = disp;