summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/ahci.c142
-rw-r--r--drivers/dfu/dfu_nand.c38
-rw-r--r--drivers/gpio/at91_gpio.c295
-rw-r--r--drivers/mmc/mxsmmc.c3
-rw-r--r--drivers/mtd/nand/atmel_nand.c201
-rw-r--r--drivers/net/fec_mxc.c2
-rw-r--r--drivers/net/macb.c12
-rw-r--r--drivers/power/pmic/pmic_max77686.c192
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/mxs_auart.c151
-rw-r--r--drivers/serial/serial.c2
-rw-r--r--drivers/usb/gadget/g_dnl.c17
-rw-r--r--drivers/usb/host/ehci-mx5.c15
-rw-r--r--drivers/usb/host/ehci-omap.c33
-rw-r--r--drivers/usb/musb-new/linux-compat.h16
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/formike.c511
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/omap_wdt.c121
19 files changed, 1515 insertions, 239 deletions
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index e455ba5..8cc9379 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -16,14 +16,14 @@
#include <asm/io.h>
#include <malloc.h>
#include <scsi.h>
-#include <ata.h>
+#include <libata.h>
#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];
+u16 *ataid[AHCI_MAX_PORTS];
#define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0)
@@ -38,7 +38,7 @@ hd_driveid_t *ataid[AHCI_MAX_PORTS];
#endif
/* Maximum timeouts for each event */
-#define WAIT_MS_SPINUP 10000
+#define WAIT_MS_SPINUP 20000
#define WAIT_MS_DATAIO 5000
#define WAIT_MS_FLUSH 5000
#define WAIT_MS_LINKUP 4
@@ -107,6 +107,27 @@ static int waiting_for_cmd_completed(volatile u8 *offset,
return (i < timeout_msec) ? 0 : -1;
}
+int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port)
+{
+ u32 tmp;
+ int j = 0;
+ u8 *port_mmio = (u8 *)probe_ent->port[port].port_mmio;
+
+ /*
+ * 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.
+ */
+ while (j < WAIT_MS_LINKUP) {
+ tmp = readl(port_mmio + PORT_SCR_STAT);
+ tmp &= PORT_SCR_STAT_DET_MASK;
+ if (tmp == PORT_SCR_STAT_DET_PHYRDY)
+ return 0;
+ udelay(1000);
+ j++;
+ }
+ return 1;
+}
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
@@ -117,8 +138,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
#endif
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
u32 tmp, cap_save, cmd;
- int i, j;
+ int i, j, ret;
volatile u8 *port_mmio;
+ u32 port_map;
debug("ahci_host_init: start\n");
@@ -160,6 +182,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
#endif
probe_ent->cap = readl(mmio + HOST_CAP);
probe_ent->port_map = readl(mmio + HOST_PORTS_IMPL);
+ port_map = probe_ent->port_map;
probe_ent->n_ports = (probe_ent->cap & 0x1f) + 1;
debug("cap 0x%x port_map 0x%x n_ports %d\n",
@@ -169,6 +192,8 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
probe_ent->n_ports = CONFIG_SYS_SCSI_MAX_SCSI_ID;
for (i = 0; i < probe_ent->n_ports; i++) {
+ if (!(port_map & (1 << i)))
+ continue;
probe_ent->port[i].port_mmio = ahci_port_base((u32) mmio, i);
port_mmio = (u8 *) probe_ent->port[i].port_mmio;
ahci_setup_port(&probe_ent->port[i], (unsigned long)mmio, i);
@@ -196,19 +221,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
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 < WAIT_MS_LINKUP) {
- tmp = readl(port_mmio + PORT_SCR_STAT);
- if ((tmp & 0xf) == 0x3)
- break;
- udelay(1000);
- j++;
- }
- if (j == WAIT_MS_LINKUP) {
+ /* Bring up SATA link. */
+ ret = ahci_link_up(probe_ent, i);
+ if (ret) {
printf("SATA link %d timeout.\n", i);
continue;
} else {
@@ -225,11 +240,23 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
j = 0;
while (j < WAIT_MS_SPINUP) {
tmp = readl(port_mmio + PORT_TFDATA);
- if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ)))
+ if (!(tmp & (ATA_BUSY | ATA_DRQ)))
break;
udelay(1000);
+ tmp = readl(port_mmio + PORT_SCR_STAT);
+ tmp &= PORT_SCR_STAT_DET_MASK;
+ if (tmp == PORT_SCR_STAT_DET_PHYRDY)
+ break;
j++;
}
+
+ tmp = readl(port_mmio + PORT_SCR_STAT) & PORT_SCR_STAT_DET_MASK;
+ if (tmp == PORT_SCR_STAT_DET_COMINIT) {
+ debug("SATA link %d down (COMINIT received), retrying...\n", i);
+ i--;
+ continue;
+ }
+
printf("Target spinup took %d ms.\n", j);
if (j == WAIT_MS_SPINUP)
debug("timeout.\n");
@@ -254,7 +281,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
/* register linkup ports */
tmp = readl(port_mmio + PORT_SCR_STAT);
debug("SATA port %d status: 0x%x\n", i, tmp);
- if ((tmp & 0xf) == 0x03)
+ if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY)
probe_ent->link_port_map |= (0x01 << i);
}
@@ -351,8 +378,6 @@ static int ahci_init_one(pci_dev_t pdev)
u16 vendor;
int rc;
- memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
-
probe_ent = malloc(sizeof(struct ahci_probe_ent));
memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
probe_ent->dev = pdev;
@@ -442,7 +467,7 @@ static void ahci_set_feature(u8 port)
memset(fis, 0, sizeof(fis));
fis[0] = 0x27;
fis[1] = 1 << 7;
- fis[2] = ATA_CMD_SETF;
+ fis[2] = ATA_CMD_SET_FEATURES;
fis[3] = SETFEATURES_XFER;
fis[12] = __ilog2(probe_ent->udma_mask + 1) + 0x40 - 0x01;
@@ -580,33 +605,12 @@ static char *ata_id_strcpy(u16 *target, u16 *src, int len)
return (char *)target;
}
-
-static void dump_ataid(hd_driveid_t *ataid)
-{
- debug("(49)ataid->capability = 0x%x\n", ataid->capability);
- debug("(53)ataid->field_valid =0x%x\n", ataid->field_valid);
- debug("(63)ataid->dma_mword = 0x%x\n", ataid->dma_mword);
- debug("(64)ataid->eide_pio_modes = 0x%x\n", ataid->eide_pio_modes);
- debug("(75)ataid->queue_depth = 0x%x\n", ataid->queue_depth);
- debug("(80)ataid->major_rev_num = 0x%x\n", ataid->major_rev_num);
- debug("(81)ataid->minor_rev_num = 0x%x\n", ataid->minor_rev_num);
- debug("(82)ataid->command_set_1 = 0x%x\n", ataid->command_set_1);
- debug("(83)ataid->command_set_2 = 0x%x\n", ataid->command_set_2);
- debug("(84)ataid->cfsse = 0x%x\n", ataid->cfsse);
- debug("(85)ataid->cfs_enable_1 = 0x%x\n", ataid->cfs_enable_1);
- debug("(86)ataid->cfs_enable_2 = 0x%x\n", ataid->cfs_enable_2);
- debug("(87)ataid->csf_default = 0x%x\n", ataid->csf_default);
- debug("(88)ataid->dma_ultra = 0x%x\n", ataid->dma_ultra);
- debug("(93)ataid->hw_config = 0x%x\n", ataid->hw_config);
-}
-
-
/*
* SCSI INQUIRY command operation.
*/
static int ata_scsiop_inquiry(ccb *pccb)
{
- u8 hdr[] = {
+ static const u8 hdr[] = {
0,
0,
0x5, /* claim SPC-3 version compatibility */
@@ -614,7 +618,7 @@ static int ata_scsiop_inquiry(ccb *pccb)
95 - 4,
};
u8 fis[20];
- u8 *tmpid;
+ u16 *tmpid;
u8 port;
/* Clean ccb data buffer */
@@ -629,28 +633,33 @@ static int ata_scsiop_inquiry(ccb *pccb)
/* Construct the FIS */
fis[0] = 0x27; /* Host to device FIS. */
fis[1] = 1 << 7; /* Command FIS. */
- fis[2] = ATA_CMD_IDENT; /* Command byte. */
+ fis[2] = ATA_CMD_ID_ATA; /* Command byte. */
/* Read id from sata */
port = pccb->target;
- if (!(tmpid = malloc(sizeof(hd_driveid_t))))
+ tmpid = malloc(ATA_ID_WORDS * 2);
+ if (!tmpid)
return -ENOMEM;
- if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), tmpid,
- sizeof(hd_driveid_t), 0)) {
+ if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), (u8 *)tmpid,
+ ATA_ID_WORDS * 2, 0)) {
debug("scsi_ahci: SCSI inquiry command failure.\n");
+ free(tmpid);
return -EIO;
}
if (ataid[port])
free(ataid[port]);
- ataid[port] = (hd_driveid_t *) tmpid;
+ ataid[port] = tmpid;
+ ata_swap_buf_le16(tmpid, ATA_ID_WORDS);
memcpy(&pccb->pdata[8], "ATA ", 8);
- ata_id_strcpy((u16 *) &pccb->pdata[16], (u16 *)ataid[port]->model, 16);
- ata_id_strcpy((u16 *) &pccb->pdata[32], (u16 *)ataid[port]->fw_rev, 4);
+ ata_id_strcpy((u16 *) &pccb->pdata[16], &tmpid[ATA_ID_PROD], 16);
+ ata_id_strcpy((u16 *) &pccb->pdata[32], &tmpid[ATA_ID_FW_REV], 4);
- dump_ataid(ataid[port]);
+#ifdef DEBUG
+ ata_dump_id(tmpid);
+#endif
return 0;
}
@@ -698,7 +707,7 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
now_blocks = min(MAX_SATA_BLOCKS_READ_WRITE, blocks);
- transfer_size = ATA_BLOCKSIZE * now_blocks;
+ transfer_size = ATA_SECT_SIZE * now_blocks;
if (transfer_size > user_buffer_size) {
printf("scsi_ahci: Error: buffer too small.\n");
return -EIO;
@@ -753,6 +762,7 @@ static int ata_scsiop_read_write(ccb *pccb, u8 is_write)
static int ata_scsiop_read_capacity10(ccb *pccb)
{
u32 cap;
+ u64 cap64;
u32 block_size;
if (!ataid[pccb->target]) {
@@ -762,18 +772,11 @@ static int ata_scsiop_read_capacity10(ccb *pccb)
return -EPERM;
}
- 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]));
- }
- }
+ cap64 = ata_id_n_sectors(ataid[pccb->target]);
+ if (cap64 > 0x100000000ULL)
+ cap64 = 0xffffffff;
- cap = cpu_to_be32(cap);
+ cap = cpu_to_be32(cap64);
memcpy(pccb->pdata, &cap, sizeof(cap));
block_size = cpu_to_be32((u32)512);
@@ -798,12 +801,7 @@ static int ata_scsiop_read_capacity16(ccb *pccb)
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 = ata_id_n_sectors(ataid[pccb->target]);
cap = cpu_to_be64(cap);
memcpy(pccb->pdata, &cap, sizeof(cap));
@@ -890,8 +888,6 @@ 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));
diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index 2a01cc1..0ec12cf 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -136,11 +136,43 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
return ret;
}
+static int dfu_flush_medium_nand(struct dfu_entity *dfu)
+{
+ int ret = 0;
+
+ /* in case of ubi partition, erase rest of the partition */
+ if (dfu->data.nand.ubi) {
+ nand_info_t *nand;
+ nand_erase_options_t opts;
+
+ if (nand_curr_device < 0 ||
+ nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+ !nand_info[nand_curr_device].name) {
+ printf("%s: invalid nand device\n", __func__);
+ return -1;
+ }
+
+ nand = &nand_info[nand_curr_device];
+
+ memset(&opts, 0, sizeof(opts));
+ opts.offset = dfu->data.nand.start + dfu->offset +
+ dfu->bad_skip;
+ opts.length = dfu->data.nand.start +
+ dfu->data.nand.size - opts.offset;
+ ret = nand_erase_opts(nand, &opts);
+ if (ret != 0)
+ printf("Failure erase: %d\n", ret);
+ }
+
+ return ret;
+}
+
int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
{
char *st;
int ret, dev, part;
+ dfu->data.nand.ubi = 0;
dfu->dev_type = DFU_DEV_NAND;
st = strsep(&s, " ");
if (!strcmp(st, "raw")) {
@@ -148,7 +180,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
dfu->data.nand.start = simple_strtoul(s, &s, 16);
s++;
dfu->data.nand.size = simple_strtoul(s, &s, 16);
- } else if (!strcmp(st, "part")) {
+ } else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) {
char mtd_id[32];
struct mtd_device *mtd_dev;
u8 part_num;
@@ -173,7 +205,8 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
dfu->data.nand.start = pi->offset;
dfu->data.nand.size = pi->size;
-
+ if (!strcmp(st, "partubi"))
+ dfu->data.nand.ubi = 1;
} else {
printf("%s: Memory layout (%s) not supported!\n", __func__, st);
return -1;
@@ -181,6 +214,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
dfu->read_medium = dfu_read_medium_nand;
dfu->write_medium = dfu_write_medium_nand;
+ dfu->flush_medium = dfu_flush_medium_nand;
/* initial state */
dfu->inited = 0;
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 2322914..af09786 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -1,5 +1,5 @@
/*
- * Memory Setup stuff - taken from blob memsetup.S
+ * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
*
* Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
*
@@ -8,16 +8,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
-/*
- * WARNING:
- *
- * As the code is right now, it expects all PIO ports A,B,C,...
- * to be evenly spaced in the memory map:
- * ATMEL_BASE_PIOA + port * sizeof at91pio_t
- * This might not necessaryly be true in future Atmel SoCs.
- * This code should be fixed to use a pointer array to the ports.
- */
-
#include <config.h>
#include <common.h>
#include <asm/io.h>
@@ -25,19 +15,42 @@
#include <asm/arch/hardware.h>
#include <asm/arch/at91_pio.h>
+static struct at91_port *at91_pio_get_port(unsigned port)
+{
+ switch (port) {
+ case AT91_PIO_PORTA:
+ return (struct at91_port *)ATMEL_BASE_PIOA;
+ case AT91_PIO_PORTB:
+ return (struct at91_port *)ATMEL_BASE_PIOB;
+ case AT91_PIO_PORTC:
+ return (struct at91_port *)ATMEL_BASE_PIOC;
+#if (ATMEL_PIO_PORTS > 3)
+ case AT91_PIO_PORTD:
+ return (struct at91_port *)ATMEL_BASE_PIOD;
+#if (ATMEL_PIO_PORTS > 4)
+ case AT91_PIO_PORTE:
+ return (struct at91_port *)ATMEL_BASE_PIOE;
+#endif
+#endif
+ default:
+ return NULL;
+ }
+}
+
int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
if (use_pullup)
- writel(1 << pin, &pio->port[port].puer);
+ writel(1 << pin, &at91_port->puer);
else
- writel(1 << pin, &pio->port[port].pudr);
- writel(mask, &pio->port[port].per);
+ writel(1 << pin, &at91_port->pudr);
+ writel(mask, &at91_port->per);
}
+
return 0;
}
@@ -46,15 +59,16 @@ int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
- writel(mask, &pio->port[port].per);
+ writel(mask, &at91_port->per);
}
+
return 0;
}
@@ -63,23 +77,24 @@ int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
#if defined(CPU_HAS_PIO3)
- writel(readl(&pio->port[port].abcdsr1) & ~mask,
- &pio->port[port].abcdsr1);
- writel(readl(&pio->port[port].abcdsr2) & ~mask,
- &pio->port[port].abcdsr2);
+ writel(readl(&at91_port->abcdsr1) & ~mask,
+ &at91_port->abcdsr1);
+ writel(readl(&at91_port->abcdsr2) & ~mask,
+ &at91_port->abcdsr2);
#else
- writel(mask, &pio->port[port].asr);
+ writel(mask, &at91_port->asr);
#endif
- writel(mask, &pio->port[port].pdr);
+ writel(mask, &at91_port->pdr);
}
+
return 0;
}
@@ -88,23 +103,24 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
#if defined(CPU_HAS_PIO3)
- writel(readl(&pio->port[port].abcdsr1) | mask,
- &pio->port[port].abcdsr1);
- writel(readl(&pio->port[port].abcdsr2) & ~mask,
- &pio->port[port].abcdsr2);
+ writel(readl(&at91_port->abcdsr1) | mask,
+ &at91_port->abcdsr1);
+ writel(readl(&at91_port->abcdsr2) & ~mask,
+ &at91_port->abcdsr2);
#else
- writel(mask, &pio->port[port].bsr);
+ writel(mask, &at91_port->bsr);
#endif
- writel(mask, &pio->port[port].pdr);
+ writel(mask, &at91_port->pdr);
}
+
return 0;
}
@@ -114,19 +130,20 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
- writel(readl(&pio->port[port].abcdsr1) & ~mask,
- &pio->port[port].abcdsr1);
- writel(readl(&pio->port[port].abcdsr2) | mask,
- &pio->port[port].abcdsr2);
- writel(mask, &pio->port[port].pdr);
+ writel(readl(&at91_port->abcdsr1) & ~mask,
+ &at91_port->abcdsr1);
+ writel(readl(&at91_port->abcdsr2) | mask,
+ &at91_port->abcdsr2);
+ writel(mask, &at91_port->pdr);
}
+
return 0;
}
@@ -135,19 +152,20 @@ int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
- writel(readl(&pio->port[port].abcdsr1) | mask,
- &pio->port[port].abcdsr1);
- writel(readl(&pio->port[port].abcdsr2) | mask,
- &pio->port[port].abcdsr2);
- writel(mask, &pio->port[port].pdr);
+ writel(readl(&at91_port->abcdsr1) | mask,
+ &at91_port->abcdsr1);
+ writel(readl(&at91_port->abcdsr2) | mask,
+ &at91_port->abcdsr2);
+ writel(mask, &at91_port->pdr);
}
+
return 0;
}
#endif
@@ -158,16 +176,17 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
*/
int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
+ writel(mask, &at91_port->idr);
at91_set_pio_pullup(port, pin, use_pullup);
- writel(mask, &pio->port[port].odr);
- writel(mask, &pio->port[port].per);
+ writel(mask, &at91_port->odr);
+ writel(mask, &at91_port->per);
}
+
return 0;
}
@@ -177,20 +196,21 @@ int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
*/
int at91_set_pio_output(unsigned port, u32 pin, int value)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].idr);
- writel(mask, &pio->port[port].pudr);
+ writel(mask, &at91_port->idr);
+ writel(mask, &at91_port->pudr);
if (value)
- writel(mask, &pio->port[port].sodr);
+ writel(mask, &at91_port->sodr);
else
- writel(mask, &pio->port[port].codr);
- writel(mask, &pio->port[port].oer);
- writel(mask, &pio->port[port].per);
+ writel(mask, &at91_port->codr);
+ writel(mask, &at91_port->oer);
+ writel(mask, &at91_port->per);
}
+
return 0;
}
@@ -199,20 +219,21 @@ int at91_set_pio_output(unsigned port, u32 pin, int value)
*/
int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
if (is_on) {
#if defined(CPU_HAS_PIO3)
- writel(mask, &pio->port[port].ifscdr);
+ writel(mask, &at91_port->ifscdr);
#endif
- writel(mask, &pio->port[port].ifer);
+ writel(mask, &at91_port->ifer);
} else {
- writel(mask, &pio->port[port].ifdr);
+ writel(mask, &at91_port->ifdr);
}
}
+
return 0;
}
@@ -222,19 +243,20 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
*/
int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
if (is_on) {
- writel(mask, &pio->port[port].ifscer);
- writel(div & PIO_SCDR_DIV, &pio->port[port].scdr);
- writel(mask, &pio->port[port].ifer);
+ writel(mask, &at91_port->ifscer);
+ writel(div & PIO_SCDR_DIV, &at91_port->scdr);
+ writel(mask, &at91_port->ifer);
} else {
- writel(mask, &pio->port[port].ifdr);
+ writel(mask, &at91_port->ifdr);
}
}
+
return 0;
}
@@ -244,17 +266,18 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
*/
int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(mask, &pio->port[port].pudr);
+ writel(mask, &at91_port->pudr);
if (is_on)
- writel(mask, &pio->port[port].ppder);
+ writel(mask, &at91_port->ppder);
else
- writel(mask, &pio->port[port].ppddr);
+ writel(mask, &at91_port->ppddr);
}
+
return 0;
}
@@ -263,14 +286,15 @@ int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
*/
int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- writel(readl(&pio->port[port].schmitt) | mask,
- &pio->port[port].schmitt);
+ writel(readl(&at91_port->schmitt) | mask,
+ &at91_port->schmitt);
}
+
return 0;
}
#endif
@@ -281,16 +305,17 @@ int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
*/
int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
if (is_on)
- writel(mask, &pio->port[port].mder);
+ writel(mask, &at91_port->mder);
else
- writel(mask, &pio->port[port].mddr);
+ writel(mask, &at91_port->mddr);
}
+
return 0;
}
@@ -299,16 +324,17 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
*/
int at91_set_pio_value(unsigned port, unsigned pin, int value)
{
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
if (value)
- writel(mask, &pio->port[port].sodr);
+ writel(mask, &at91_port->sodr);
else
- writel(mask, &pio->port[port].codr);
+ writel(mask, &at91_port->codr);
}
+
return 0;
}
@@ -317,13 +343,56 @@ int at91_set_pio_value(unsigned port, unsigned pin, int value)
*/
int at91_get_pio_value(unsigned port, unsigned pin)
{
- u32 pdsr = 0;
- at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
- u32 mask;
+ struct at91_port *at91_port = at91_pio_get_port(port);
+ u32 pdsr = 0, mask;
- if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+ if (at91_port && (pin < 32)) {
mask = 1 << pin;
- pdsr = readl(&pio->port[port].pdsr) & mask;
+ pdsr = readl(&at91_port->pdsr) & mask;
}
+
return pdsr != 0;
}
+
+/* Common GPIO API */
+
+#define at91_gpio_to_port(gpio) (gpio / 32)
+#define at91_gpio_to_pin(gpio) (gpio % 32)
+
+int gpio_request(unsigned gpio, const char *label)
+{
+ return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+ return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ at91_set_pio_input(at91_gpio_to_port(gpio),
+ at91_gpio_to_pin(gpio), 0);
+ return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ at91_set_pio_output(at91_gpio_to_port(gpio),
+ at91_gpio_to_pin(gpio), value);
+ return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ return at91_get_pio_value(at91_gpio_to_port(gpio),
+ at91_gpio_to_pin(gpio));
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+ at91_set_pio_value(at91_gpio_to_port(gpio),
+ at91_gpio_to_pin(gpio), value);
+
+ return 0;
+}
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c
index e5a5d75..245f9d0 100644
--- a/drivers/mmc/mxsmmc.c
+++ b/drivers/mmc/mxsmmc.c
@@ -410,7 +410,8 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
- MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ MMC_MODE_HS_52MHz | MMC_MODE_HS |
+ MMC_MODE_HC;
/*
* SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index f844990..da83f06 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -16,6 +16,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/at91_pio.h>
+#include <malloc.h>
#include <nand.h>
#include <watchdog.h>
@@ -50,13 +51,13 @@ struct atmel_nand_host {
void __iomem *pmecc_index_of;
/* data for pmecc computation */
- int16_t pmecc_smu[(CONFIG_PMECC_CAP + 2) * (2 * CONFIG_PMECC_CAP + 1)];
- int16_t pmecc_partial_syn[2 * CONFIG_PMECC_CAP + 1];
- int16_t pmecc_si[2 * CONFIG_PMECC_CAP + 1];
- int16_t pmecc_lmu[CONFIG_PMECC_CAP + 1]; /* polynomal order */
- int pmecc_mu[CONFIG_PMECC_CAP + 1];
- int pmecc_dmu[CONFIG_PMECC_CAP + 1];
- int pmecc_delta[CONFIG_PMECC_CAP + 1];
+ int16_t *pmecc_smu;
+ int16_t *pmecc_partial_syn;
+ int16_t *pmecc_si;
+ int16_t *pmecc_lmu; /* polynomal order */
+ int *pmecc_mu;
+ int *pmecc_dmu;
+ int *pmecc_delta;
};
static struct atmel_nand_host pmecc_host;
@@ -109,6 +110,48 @@ static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
table_size * sizeof(int16_t);
}
+static void pmecc_data_free(struct atmel_nand_host *host)
+{
+ free(host->pmecc_partial_syn);
+ free(host->pmecc_si);
+ free(host->pmecc_lmu);
+ free(host->pmecc_smu);
+ free(host->pmecc_mu);
+ free(host->pmecc_dmu);
+ free(host->pmecc_delta);
+}
+
+static int pmecc_data_alloc(struct atmel_nand_host *host)
+{
+ const int cap = host->pmecc_corr_cap;
+ int size;
+
+ size = (2 * cap + 1) * sizeof(int16_t);
+ host->pmecc_partial_syn = malloc(size);
+ host->pmecc_si = malloc(size);
+ host->pmecc_lmu = malloc((cap + 1) * sizeof(int16_t));
+ host->pmecc_smu = malloc((cap + 2) * size);
+
+ size = (cap + 1) * sizeof(int);
+ host->pmecc_mu = malloc(size);
+ host->pmecc_dmu = malloc(size);
+ host->pmecc_delta = malloc(size);
+
+ if (host->pmecc_partial_syn &&
+ host->pmecc_si &&
+ host->pmecc_lmu &&
+ host->pmecc_smu &&
+ host->pmecc_mu &&
+ host->pmecc_dmu &&
+ host->pmecc_delta)
+ return 0;
+
+ /* error happened */
+ pmecc_data_free(host);
+ return -ENOMEM;
+
+}
+
static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
{
struct nand_chip *nand_chip = mtd->priv;
@@ -622,6 +665,99 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
pmecc_writel(host->pmecc, ctrl, PMECC_CTRL_ENABLE);
}
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+/*
+ * get_onfi_ecc_param - Get ECC requirement from ONFI parameters
+ * @ecc_bits: store the ONFI ECC correct bits capbility
+ * @sector_size: in how many bytes that ONFI require to correct @ecc_bits
+ *
+ * Returns -1 if ONFI parameters is not supported. In this case @ecc_bits,
+ * @sector_size are initialize to 0.
+ * Return 0 if success to get the ECC requirement.
+ */
+static int get_onfi_ecc_param(struct nand_chip *chip,
+ int *ecc_bits, int *sector_size)
+{
+ *ecc_bits = *sector_size = 0;
+
+ if (chip->onfi_params.ecc_bits == 0xff)
+ /* TODO: the sector_size and ecc_bits need to be find in
+ * extended ecc parameter, currently we don't support it.
+ */
+ return -1;
+
+ *ecc_bits = chip->onfi_params.ecc_bits;
+
+ /* The default sector size (ecc codeword size) is 512 */
+ *sector_size = 512;
+
+ return 0;
+}
+
+/*
+ * pmecc_choose_ecc - Get ecc requirement from ONFI parameters. If
+ * pmecc_corr_cap or pmecc_sector_size is 0, then set it as
+ * ONFI ECC parameters.
+ * @host: point to an atmel_nand_host structure.
+ * if host->pmecc_corr_cap is 0 then set it as the ONFI ecc_bits.
+ * if host->pmecc_sector_size is 0 then set it as the ONFI sector_size.
+ * @chip: point to an nand_chip structure.
+ * @cap: store the ONFI ECC correct bits capbility
+ * @sector_size: in how many bytes that ONFI require to correct @ecc_bits
+ *
+ * Return 0 if success. otherwise return the error code.
+ */
+static int pmecc_choose_ecc(struct atmel_nand_host *host,
+ struct nand_chip *chip,
+ int *cap, int *sector_size)
+{
+ /* Get ECC requirement from ONFI parameters */
+ *cap = *sector_size = 0;
+ if (chip->onfi_version) {
+ if (!get_onfi_ecc_param(chip, cap, sector_size)) {
+ MTDDEBUG(MTD_DEBUG_LEVEL1, "ONFI params, minimum required ECC: %d bits in %d bytes\n",
+ *cap, *sector_size);
+ } else {
+ dev_info(host->dev, "NAND chip ECC reqirement is in Extended ONFI parameter, we don't support yet.\n");
+ }
+ } else {
+ dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes");
+ }
+ if (*cap == 0 && *sector_size == 0) {
+ /* Non-ONFI compliant or use extended ONFI parameters */
+ *cap = 2;
+ *sector_size = 512;
+ }
+
+ /* If head file doesn't specify then use the one in ONFI parameters */
+ if (host->pmecc_corr_cap == 0) {
+ /* use the most fitable ecc bits (the near bigger one ) */
+ if (*cap <= 2)
+ host->pmecc_corr_cap = 2;
+ else if (*cap <= 4)
+ host->pmecc_corr_cap = 4;
+ else if (*cap <= 8)
+ host->pmecc_corr_cap = 8;
+ else if (*cap <= 12)
+ host->pmecc_corr_cap = 12;
+ else if (*cap <= 24)
+ host->pmecc_corr_cap = 24;
+ else
+ return -EINVAL;
+ }
+ if (host->pmecc_sector_size == 0) {
+ /* use the most fitable sector size (the near smaller one ) */
+ if (*sector_size >= 1024)
+ host->pmecc_sector_size = 1024;
+ else if (*sector_size >= 512)
+ host->pmecc_sector_size = 512;
+ else
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
struct mtd_info *mtd)
{
@@ -635,9 +771,45 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
nand->ecc.correct = NULL;
nand->ecc.hwctl = NULL;
- cap = host->pmecc_corr_cap = CONFIG_PMECC_CAP;
- sector_size = host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
- host->pmecc_index_table_offset = CONFIG_PMECC_INDEX_TABLE_OFFSET;
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+ host->pmecc_corr_cap = host->pmecc_sector_size = 0;
+
+#ifdef CONFIG_PMECC_CAP
+ host->pmecc_corr_cap = CONFIG_PMECC_CAP;
+#endif
+#ifdef CONFIG_PMECC_SECTOR_SIZE
+ host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
+#endif
+ /* Get ECC requirement of ONFI parameters. And if CONFIG_PMECC_CAP or
+ * CONFIG_PMECC_SECTOR_SIZE not defined, then use ecc_bits, sector_size
+ * from ONFI.
+ */
+ if (pmecc_choose_ecc(host, nand, &cap, &sector_size)) {
+ dev_err(host->dev, "The NAND flash's ECC requirement(ecc_bits: %d, sector_size: %d) are not support!",
+ cap, sector_size);
+ return -EINVAL;
+ }
+
+ if (cap > host->pmecc_corr_cap)
+ dev_info(host->dev, "WARNING: Using different ecc correct bits(%d bit) from Nand ONFI ECC reqirement (%d bit).\n",
+ host->pmecc_corr_cap, cap);
+ if (sector_size < host->pmecc_sector_size)
+ dev_info(host->dev, "WARNING: Using different ecc correct sector size (%d bytes) from Nand ONFI ECC reqirement (%d bytes).\n",
+ host->pmecc_sector_size, sector_size);
+#else /* CONFIG_SYS_NAND_ONFI_DETECTION */
+ host->pmecc_corr_cap = CONFIG_PMECC_CAP;
+ host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
+#endif
+
+ cap = host->pmecc_corr_cap;
+ sector_size = host->pmecc_sector_size;
+
+ /* TODO: need check whether cap & sector_size is validate */
+
+ if (host->pmecc_sector_size == 512)
+ host->pmecc_index_table_offset = ATMEL_PMECC_INDEX_OFFSET_512;
+ else
+ host->pmecc_index_table_offset = ATMEL_PMECC_INDEX_OFFSET_1024;
MTDDEBUG(MTD_DEBUG_LEVEL1,
"Initialize PMECC params, cap: %d, sector: %d\n",
@@ -655,7 +827,8 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
switch (mtd->writesize) {
case 2048:
case 4096:
- host->pmecc_degree = PMECC_GF_DIMENSION_13;
+ host->pmecc_degree = (sector_size == 512) ?
+ PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14;
host->pmecc_cw_len = (1 << host->pmecc_degree) - 1;
host->pmecc_sector_number = mtd->writesize / sector_size;
host->pmecc_bytes_per_sector = pmecc_get_ecc_bytes(
@@ -691,6 +864,12 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
return 0;
}
+ /* Allocate data for PMECC computation */
+ if (pmecc_data_alloc(host)) {
+ dev_err(host->dev, "Cannot allocate memory for PMECC computation!\n");
+ return -ENOMEM;
+ }
+
nand->ecc.read_page = atmel_nand_pmecc_read_page;
nand->ecc.write_page = atmel_nand_pmecc_write_page;
nand->ecc.strength = cap;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index e14a359..690e572 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -980,6 +980,8 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
memcpy(edev->enetaddr, ethaddr, 6);
+ if (!getenv("ethaddr"))
+ eth_setenv_enetaddr("ethaddr", ethaddr);
}
return ret;
err3:
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 1f7cc32..bf3983a 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -36,6 +36,7 @@
#include <asm/io.h>
#include <asm/dma-mapping.h>
#include <asm/arch/clk.h>
+#include <asm-generic/errno.h>
#include "macb.h"
@@ -397,9 +398,14 @@ static int macb_phy_init(struct macb_device *macb)
}
#ifdef CONFIG_PHYLIB
- phydev->bus = macb->bus;
- phydev->dev = netdev;
- phydev->addr = macb->phy_addr;
+ /* need to consider other phy interface mode */
+ phydev = phy_connect(macb->bus, macb->phy_addr, netdev,
+ PHY_INTERFACE_MODE_RGMII);
+ if (!phydev) {
+ printf("phy_connect failed\n");
+ return -ENODEV;
+ }
+
phy_config(phydev);
#endif
diff --git a/drivers/power/pmic/pmic_max77686.c b/drivers/power/pmic/pmic_max77686.c
index 7208e5b..d4c430e 100644
--- a/drivers/power/pmic/pmic_max77686.c
+++ b/drivers/power/pmic/pmic_max77686.c
@@ -14,6 +14,198 @@
DECLARE_GLOBAL_DATA_PTR;
+static const char max77686_buck_addr[] = {
+ 0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
+};
+
+static unsigned int max77686_ldo_volt2hex(int ldo, ulong uV)
+{
+ unsigned int hex = 0;
+
+ switch (ldo) {
+ case 1:
+ case 2:
+ case 6:
+ case 7:
+ case 8:
+ case 15:
+ hex = (uV - 800000) / 25000;
+ break;
+ default:
+ hex = (uV - 800000) / 50000;
+ }
+
+ if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
+ return hex;
+
+ debug("%s: %ld is wrong voltage value for LDO%d\n", __func__, uV, ldo);
+ return 0;
+}
+
+int max77686_set_ldo_voltage(struct pmic *p, int ldo, ulong uV)
+{
+ unsigned int val, ret, hex, adr;
+
+ if (ldo < 1 && ldo > 26) {
+ printf("%s: %d is wrong ldo number\n", __func__, ldo);
+ return -1;
+ }
+
+ adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
+ hex = max77686_ldo_volt2hex(ldo, uV);
+
+ if (!hex)
+ return -1;
+
+ ret = pmic_reg_read(p, adr, &val);
+ if (ret)
+ return ret;
+
+ val &= ~MAX77686_LDO_VOLT_MASK;
+ val |= hex;
+ ret |= pmic_reg_write(p, adr, val);
+
+ return ret;
+}
+
+int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode)
+{
+ unsigned int val, ret, adr, mode;
+
+ if (ldo < 1 && 26 < ldo) {
+ printf("%s: %d is wrong ldo number\n", __func__, ldo);
+ return -1;
+ }
+
+ adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
+
+ /* mode */
+ switch (opmode) {
+ case OPMODE_OFF:
+ mode = MAX77686_LDO_MODE_OFF;
+ break;
+ case OPMODE_STANDBY:
+ switch (ldo) {
+ case 2:
+ case 6:
+ case 7:
+ case 8:
+ case 10:
+ case 11:
+ case 12:
+ case 14:
+ case 15:
+ case 16:
+ mode = MAX77686_LDO_MODE_STANDBY;
+ break;
+ default:
+ mode = 0xff;
+ }
+ break;
+ case OPMODE_LPM:
+ mode = MAX77686_LDO_MODE_LPM;
+ break;
+ case OPMODE_ON:
+ mode = MAX77686_LDO_MODE_ON;
+ break;
+ default:
+ mode = 0xff;
+ }
+
+ if (mode == 0xff) {
+ printf("%s: %d is not supported on LDO%d\n",
+ __func__, opmode, ldo);
+ return -1;
+ }
+
+ ret = pmic_reg_read(p, adr, &val);
+ if (ret)
+ return ret;
+
+ val &= ~MAX77686_LDO_MODE_MASK;
+ val |= mode;
+ ret |= pmic_reg_write(p, adr, val);
+
+ return ret;
+}
+
+int max77686_set_buck_mode(struct pmic *p, int buck, char opmode)
+{
+ unsigned int val, ret, mask, adr, size, mode, mode_shift;
+
+ size = ARRAY_SIZE(max77686_buck_addr);
+ if (buck >= size) {
+ printf("%s: %d is wrong buck number\n", __func__, buck);
+ return -1;
+ }
+
+ adr = max77686_buck_addr[buck];
+
+ /* mask */
+ switch (buck) {
+ case 2:
+ case 3:
+ case 4:
+ mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
+ break;
+ default:
+ mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
+ }
+
+ mask = MAX77686_BUCK_MODE_MASK << mode_shift;
+
+ /* mode */
+ switch (opmode) {
+ case OPMODE_OFF:
+ mode = MAX77686_BUCK_MODE_OFF;
+ break;
+ case OPMODE_STANDBY:
+ switch (buck) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
+ break;
+ default:
+ mode = 0xff;
+ }
+ break;
+ case OPMODE_LPM:
+ switch (buck) {
+ case 2:
+ case 3:
+ case 4:
+ mode = MAX77686_BUCK_MODE_LPM << mode_shift;
+ break;
+ default:
+ mode = 0xff;
+ }
+ break;
+ case OPMODE_ON:
+ mode = MAX77686_BUCK_MODE_ON << mode_shift;
+ break;
+ default:
+ mode = 0xff;
+ }
+
+ if (mode == 0xff) {
+ printf("%s: %d is not supported on BUCK%d\n",
+ __func__, opmode, buck);
+ return -1;
+ }
+
+ ret = pmic_reg_read(p, adr, &val);
+ if (ret)
+ return ret;
+
+ val &= ~mask;
+ val |= mode;
+ ret |= pmic_reg_write(p, adr, val);
+
+ return ret;
+}
+
int pmic_init(unsigned char bus)
{
static const char name[] = "MAX77686_PMIC";
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 697f2bb..4c45bfa 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
COBJS-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
COBJS-$(CONFIG_FSL_LPUART) += serial_lpuart.o
+COBJS-$(CONFIG_MXS_AUART) += mxs_auart.o
ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/mxs_auart.c b/drivers/serial/mxs_auart.c
new file mode 100644
index 0000000..7cfe5bc
--- /dev/null
+++ b/drivers/serial/mxs_auart.c
@@ -0,0 +1,151 @@
+/*
+ * Freescale i.MX23/i.MX28 AUART driver
+ *
+ * Copyright (C) 2013 Andreas Wass <andreas.wass@dalelven.com>
+ *
+ * Based on the MXC serial driver:
+ *
+ * (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Further based on the Linux mxs-auart.c driver:
+ *
+ * Freescale STMP37XX/STMP38X Application UART drkiver
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <serial.h>
+#include <linux/compiler.h>
+#include <asm/arch/regs-base.h>
+#include <asm/arch/regs-uartapp.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_MXS_AUART_BASE
+#error "CONFIG_MXS_AUART_BASE must be set to the base UART to use"
+#endif
+
+/* AUART clock always supplied by XTAL and always 24MHz */
+#define MXS_AUART_CLK 24000000
+
+static struct mxs_uartapp_regs *get_uartapp_registers(void)
+{
+ return (struct mxs_uartapp_regs *)CONFIG_MXS_AUART_BASE;
+}
+
+/**
+ * Sets the baud rate and settings.
+ * The settings are: 8 data bits, no parit and 1 stop bit.
+ */
+void mxs_auart_setbrg(void)
+{
+ u32 div;
+ u32 linectrl = 0;
+ struct mxs_uartapp_regs *regs = get_uartapp_registers();
+
+ if (!gd->baudrate)
+ gd->baudrate = CONFIG_BAUDRATE;
+
+ /*
+ * From i.MX28 datasheet:
+ * div is calculated by calculating UARTCLK*32/baudrate, rounded to int
+ * div must be between 0xEC and 0x003FFFC0 inclusive
+ * Lowest 6 bits of div goes in BAUD_DIVFRAC part of LINECTRL register
+ * Next 16 bits goes in BAUD_DIVINT part of LINECTRL register
+ */
+ div = (MXS_AUART_CLK * 32) / gd->baudrate;
+ if (div < 0xEC || div > 0x003FFFC0)
+ return;
+
+ linectrl |= ((div & UARTAPP_LINECTRL_EXTRACT_BAUD_DIVFRAC_MASK) <<
+ UARTAPP_LINECTRL_BAUD_DIVFRAC_OFFSET) &
+ UARTAPP_LINECTRL_BAUD_DIVFRAC_MASK;
+ linectrl |= ((div >> UARTAPP_LINECTRL_EXTRACT_BAUD_DIVINT_OFFSET) <<
+ UARTAPP_LINECTRL_BAUD_DIVINT_OFFSET) &
+ UARTAPP_LINECTRL_BAUD_DIVINT_MASK;
+
+ /* Word length: 8 bits */
+ linectrl |= UARTAPP_LINECTRL_WLEN_8BITS;
+
+ /* Enable FIFOs. */
+ linectrl |= UARTAPP_LINECTRL_FEN_MASK;
+
+ /* Write above settings, no parity, 1 stop bit */
+ writel(linectrl, &regs->hw_uartapp_linectrl);
+}
+
+int mxs_auart_init(void)
+{
+ struct mxs_uartapp_regs *regs = get_uartapp_registers();
+ /* Reset everything */
+ mxs_reset_block(&regs->hw_uartapp_ctrl0_reg);
+ /* Disable interrupts */
+ writel(0, &regs->hw_uartapp_intr);
+ /* Set baud rate and settings */
+ serial_setbrg();
+ /* Disable RTS and CTS, ignore LINECTRL2 register */
+ writel(UARTAPP_CTRL2_RTSEN_MASK |
+ UARTAPP_CTRL2_CTSEN_MASK |
+ UARTAPP_CTRL2_USE_LCR2_MASK,
+ &regs->hw_uartapp_ctrl2_clr);
+ /* Enable receiver, transmitter and UART */
+ writel(UARTAPP_CTRL2_RXE_MASK |
+ UARTAPP_CTRL2_TXE_MASK |
+ UARTAPP_CTRL2_UARTEN_MASK,
+ &regs->hw_uartapp_ctrl2_set);
+ return 0;
+}
+
+void mxs_auart_putc(const char c)
+{
+ struct mxs_uartapp_regs *regs = get_uartapp_registers();
+ /* Wait in loop while the transmit FIFO is full */
+ while (readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_TXFF_MASK)
+ ;
+
+ writel(c, &regs->hw_uartapp_data);
+
+ if (c == '\n')
+ mxs_auart_putc('\r');
+}
+
+int mxs_auart_tstc(void)
+{
+ struct mxs_uartapp_regs *regs = get_uartapp_registers();
+ /* Checks if receive FIFO is empty */
+ return !(readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_RXFE_MASK);
+}
+
+int mxs_auart_getc(void)
+{
+ struct mxs_uartapp_regs *regs = get_uartapp_registers();
+ /* Wait until a character is available to read */
+ while (!mxs_auart_tstc())
+ ;
+ /* Read the character from the data register */
+ return readl(&regs->hw_uartapp_data) & 0xFF;
+}
+
+static struct serial_device mxs_auart_drv = {
+ .name = "mxs_auart_serial",
+ .start = mxs_auart_init,
+ .stop = NULL,
+ .setbrg = mxs_auart_setbrg,
+ .putc = mxs_auart_putc,
+ .puts = default_serial_puts,
+ .getc = mxs_auart_getc,
+ .tstc = mxs_auart_tstc,
+};
+
+void mxs_auart_initialize(void)
+{
+ serial_register(&mxs_auart_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &mxs_auart_drv;
+}
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 118fbc3..35dc61e 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -160,6 +160,7 @@ serial_initfunc(s3c44b0_serial_initialize);
serial_initfunc(sa1100_serial_initialize);
serial_initfunc(sh_serial_initialize);
serial_initfunc(arm_dcc_initialize);
+serial_initfunc(mxs_auart_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@@ -253,6 +254,7 @@ void serial_initialize(void)
sa1100_serial_initialize();
sh_serial_initialize();
arm_dcc_initialize();
+ mxs_auart_initialize();
serial_assign(default_serial_console()->name);
}
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
index cbfcb2d..a3e05a8 100644
--- a/drivers/usb/gadget/g_dnl.c
+++ b/drivers/usb/gadget/g_dnl.c
@@ -31,8 +31,10 @@
#define STRING_MANUFACTURER 25
#define STRING_PRODUCT 2
+/* Index of String Descriptor describing this configuration */
#define STRING_USBDOWN 2
-#define CONFIG_USBDOWNLOADER 2
+/* Number of supported configurations */
+#define CONFIGURATION_NUMBER 1
#define DRIVER_VERSION "usb_dnl 2.0"
@@ -54,11 +56,14 @@ static struct usb_device_descriptor device_desc = {
.bNumConfigurations = 1,
};
-/* static strings, in UTF-8 */
+/*
+ * static strings, in UTF-8
+ * IDs for those strings are assigned dynamically at g_dnl_bind()
+ */
static struct usb_string g_dnl_string_defs[] = {
- { 0, manufacturer, },
- { 1, product, },
- { } /* end of list */
+ {.s = manufacturer},
+ {.s = product},
+ { } /* end of list */
};
static struct usb_gadget_strings g_dnl_string_tab = {
@@ -104,7 +109,7 @@ static int g_dnl_config_register(struct usb_composite_dev *cdev)
static struct usb_configuration config = {
.label = "usb_dnload",
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bConfigurationValue = CONFIG_USBDOWNLOADER,
+ .bConfigurationValue = CONFIGURATION_NUMBER,
.iConfiguration = STRING_USBDOWN,
.bind = g_dnl_do_config,
diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c
index 3548620..dd11f53 100644
--- a/drivers/usb/host/ehci-mx5.c
+++ b/drivers/usb/host/ehci-mx5.c
@@ -221,21 +221,12 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
struct usb_ehci *ehci;
-#ifdef CONFIG_MX53
- struct clkctl *sc_regs = (struct clkctl *)CCM_BASE_ADDR;
- u32 reg;
-
- reg = __raw_readl(&sc_regs->cscmr1) & ~(1 << 26);
- /* derive USB PHY clock multiplexer from PLL3 */
- reg |= 1 << 26;
- __raw_writel(reg, &sc_regs->cscmr1);
-#endif
set_usboh3_clk();
- enable_usboh3_clk(1);
+ enable_usboh3_clk(true);
set_usb_phy_clk();
- enable_usb_phy1_clk(1);
- enable_usb_phy2_clk(1);
+ enable_usb_phy1_clk(true);
+ enable_usb_phy2_clk(true);
mdelay(1);
/* Do board specific initialization */
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 032d5e5..3c58f9e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -79,6 +79,7 @@ static void omap_usbhs_hsic_init(int port)
writel(reg, &usbtll->channel_conf + port);
}
+#ifdef CONFIG_USB_ULPI
static void omap_ehci_soft_phy_reset(int port)
{
struct ulpi_viewport ulpi_vp;
@@ -88,6 +89,12 @@ static void omap_ehci_soft_phy_reset(int port)
ulpi_reset(&ulpi_vp);
}
+#else
+static void omap_ehci_soft_phy_reset(int port)
+{
+ return;
+}
+#endif
inline int __board_usb_init(void)
{
@@ -96,7 +103,8 @@ inline int __board_usb_init(void)
int board_usb_init(void) __attribute__((weak, alias("__board_usb_init")));
#if defined(CONFIG_OMAP_EHCI_PHY1_RESET_GPIO) || \
- defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO)
+ defined(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO) || \
+ defined(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO)
/* controls PHY(s) reset signal(s) */
static inline void omap_ehci_phy_reset(int on, int delay)
{
@@ -115,6 +123,10 @@ static inline void omap_ehci_phy_reset(int on, int delay)
gpio_request(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, "USB PHY2 reset");
gpio_direction_output(CONFIG_OMAP_EHCI_PHY2_RESET_GPIO, !on);
#endif
+#ifdef CONFIG_OMAP_EHCI_PHY3_RESET_GPIO
+ gpio_request(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, "USB PHY3 reset");
+ gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, !on);
+#endif
/* Hold the PHY in RESET for enough time till DIR is high */
/* Refer: ISSUE1 */
@@ -198,10 +210,27 @@ int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata,
else
setbits_le32(&reg, OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS);
} else if (rev == OMAP_USBHS_REV2) {
+
clrsetbits_le32(&reg, (OMAP_P1_MODE_CLEAR | OMAP_P2_MODE_CLEAR),
OMAP4_UHH_HOSTCONFIG_APP_START_CLK);
- /* Clear port mode fields for PHY mode*/
+ /* Clear port mode fields for PHY mode */
+
+ if (is_ehci_hsic_mode(usbhs_pdata->port_mode[0]))
+ setbits_le32(&reg, OMAP_P1_MODE_HSIC);
+
+ if (is_ehci_hsic_mode(usbhs_pdata->port_mode[1]))
+ setbits_le32(&reg, OMAP_P2_MODE_HSIC);
+
+ } else if (rev == OMAP_USBHS_REV2_1) {
+
+ clrsetbits_le32(&reg,
+ (OMAP_P1_MODE_CLEAR |
+ OMAP_P2_MODE_CLEAR |
+ OMAP_P3_MODE_CLEAR),
+ OMAP4_UHH_HOSTCONFIG_APP_START_CLK);
+
+ /* Clear port mode fields for PHY mode */
if (is_ehci_hsic_mode(usbhs_pdata->port_mode[0]))
setbits_le32(&reg, OMAP_P1_MODE_HSIC);
diff --git a/drivers/usb/musb-new/linux-compat.h b/drivers/usb/musb-new/linux-compat.h
index 72c8c2b..d7a5663 100644
--- a/drivers/usb/musb-new/linux-compat.h
+++ b/drivers/usb/musb-new/linux-compat.h
@@ -39,15 +39,6 @@ typedef unsigned long dmaaddr_t;
#define cpu_relax() do {} while (0)
#define pr_debug(fmt, args...) debug(fmt, ##args)
-#define dev_dbg(dev, fmt, args...) \
- debug(fmt, ##args)
-#define dev_vdbg(dev, fmt, args...) \
- debug(fmt, ##args)
-#define dev_info(dev, fmt, args...) \
- printf(fmt, ##args)
-#define dev_err(dev, fmt, args...) \
- printf(fmt, ##args)
-#define printk printf
#define WARN(condition, fmt, args...) ({ \
int ret_warn = !!condition; \
@@ -55,13 +46,6 @@ typedef unsigned long dmaaddr_t;
printf(fmt, ##args); \
ret_warn; })
-#define KERN_DEBUG
-#define KERN_NOTICE
-#define KERN_WARNING
-#define KERN_ERR
-
-#define kfree(ptr) free(ptr)
-
#define pm_runtime_get_sync(dev) do {} while (0)
#define pm_runtime_put(dev) do {} while (0)
#define pm_runtime_put_sync(dev) do {} while (0)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 6dee1e9..6c208c5 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -41,6 +41,7 @@ COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
COBJS-$(CONFIG_VIDEO_TEGRA) += tegra.o
COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
+COBJS-$(CONFIG_FORMIKE) += formike.o
COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/video/formike.c b/drivers/video/formike.c
new file mode 100644
index 0000000..b9b6822
--- /dev/null
+++ b/drivers/video/formike.c
@@ -0,0 +1,511 @@
+/*
+ * LCD: Formike, TFT 4.3", 480x800, RGB24, KWH043ST20-F01, DriverIC NT35510-16
+ * LCD initialization via SPI
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ * Based on:
+ *
+ */
+#include <common.h>
+#include <errno.h>
+#include <spi.h>
+
+#define TAG_READ 0x80
+#define TAG_WRITE 0x00
+
+#define TAG_DATA 0x40
+#define TAG_COMMAND 0x00
+
+#define TAG_ADDR_H 0x20
+#define TAG_ADDR_L 0x00
+
+static int spi_write_tag_val(struct spi_slave *spi, unsigned char tag,
+ unsigned char val)
+{
+ unsigned long flags = SPI_XFER_BEGIN;
+ u8 buf[2];
+ int ret;
+
+ buf[0] = tag;
+ buf[1] = val;
+ flags |= SPI_XFER_END;
+
+ ret = spi_xfer(spi, 16, buf, NULL, flags);
+#ifdef KWH043ST20_F01_SPI_DEBUG
+ printf("spi_write_tag_val: tag=%02X, val=%02X ret: %d\n",
+ tag, val, ret);
+#endif /* KWH043ST20_F01_SPI_DEBUG */
+ if (ret)
+ debug("%s: Failed to send: %d\n", __func__, ret);
+
+ return ret;
+}
+
+static void spi_write_dat(struct spi_slave *spi, unsigned int val)
+{
+ spi_write_tag_val(spi, TAG_WRITE|TAG_DATA, val);
+}
+
+static void spi_write_com(struct spi_slave *spi, unsigned int addr)
+{
+ spi_write_tag_val(spi, TAG_WRITE|TAG_COMMAND|TAG_ADDR_H,
+ (addr & 0xff00) >> 8);
+ spi_write_tag_val(spi, TAG_WRITE|TAG_COMMAND|TAG_ADDR_L,
+ (addr & 0x00ff) >> 0);
+}
+
+int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int spi_mode)
+{
+ struct spi_slave *spi;
+ int ret;
+
+ spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+ if (!spi) {
+ debug("%s: Failed to set up slave\n", __func__);
+ return -1;
+ }
+
+ ret = spi_claim_bus(spi);
+ if (ret) {
+ debug("%s: Failed to claim SPI bus: %d\n", __func__, ret);
+ goto err_claim_bus;
+ }
+
+
+ /* LV2 Page 1 enable */
+ spi_write_com(spi, 0xF000); spi_write_dat(spi, 0x55);
+ spi_write_com(spi, 0xF001); spi_write_dat(spi, 0xAA);
+ spi_write_com(spi, 0xF002); spi_write_dat(spi, 0x52);
+ spi_write_com(spi, 0xF003); spi_write_dat(spi, 0x08);
+ spi_write_com(spi, 0xF004); spi_write_dat(spi, 0x01);
+
+ /* AVDD Set AVDD 5.2V */
+ spi_write_com(spi, 0xB000); spi_write_dat(spi, 0x0D);
+ spi_write_com(spi, 0xB001); spi_write_dat(spi, 0x0D);
+ spi_write_com(spi, 0xB002); spi_write_dat(spi, 0x0D);
+
+ /* AVDD ratio */
+ spi_write_com(spi, 0xB600); spi_write_dat(spi, 0x34);
+ spi_write_com(spi, 0xB601); spi_write_dat(spi, 0x34);
+ spi_write_com(spi, 0xB602); spi_write_dat(spi, 0x34);
+
+ /* AVEE -5.2V */
+ spi_write_com(spi, 0xB100); spi_write_dat(spi, 0x0D);
+ spi_write_com(spi, 0xB101); spi_write_dat(spi, 0x0D);
+ spi_write_com(spi, 0xB102); spi_write_dat(spi, 0x0D);
+
+ /* AVEE ratio */
+ spi_write_com(spi, 0xB700); spi_write_dat(spi, 0x35);
+ spi_write_com(spi, 0xB701); spi_write_dat(spi, 0x35);
+ spi_write_com(spi, 0xB702); spi_write_dat(spi, 0x35);
+
+ /* VCL -2.5V */
+ spi_write_com(spi, 0xB200); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xB201); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xB202); spi_write_dat(spi, 0x00);
+
+ /* VCL ratio */
+ spi_write_com(spi, 0xB800); spi_write_dat(spi, 0x24);
+ spi_write_com(spi, 0xB801); spi_write_dat(spi, 0x24);
+ spi_write_com(spi, 0xB802); spi_write_dat(spi, 0x24);
+
+ /* VGH 15V */
+ spi_write_com(spi, 0xBF00); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xB300); spi_write_dat(spi, 0x08);
+ spi_write_com(spi, 0xB301); spi_write_dat(spi, 0x08);
+ spi_write_com(spi, 0xB302); spi_write_dat(spi, 0x08);
+
+ /* VGH ratio */
+ spi_write_com(spi, 0xB900); spi_write_dat(spi, 0x34);
+ spi_write_com(spi, 0xB901); spi_write_dat(spi, 0x34);
+ spi_write_com(spi, 0xB902); spi_write_dat(spi, 0x34);
+
+ /* VGLX ratio */
+ spi_write_com(spi, 0xBA00); spi_write_dat(spi, 0x24);
+ spi_write_com(spi, 0xBA01); spi_write_dat(spi, 0x24);
+ spi_write_com(spi, 0xBA02); spi_write_dat(spi, 0x24);
+
+ /* VGMP/VGSP 4.7V/0V */
+ spi_write_com(spi, 0xBC00); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xBC01); spi_write_dat(spi, 0x88);
+ spi_write_com(spi, 0xBC02); spi_write_dat(spi, 0x00);
+
+ /* VGMN/VGSN -4.7V/0V */
+ spi_write_com(spi, 0xBD00); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xBD01); spi_write_dat(spi, 0x88);
+ spi_write_com(spi, 0xBD02); spi_write_dat(spi, 0x00);
+
+ /* VCOM 1.525V */
+ spi_write_com(spi, 0xBE00); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xBE01); spi_write_dat(spi, 0x7A);
+
+ /* Gamma Setting */
+ spi_write_com(spi, 0xD100); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD101); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD102); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD103); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD104); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD105); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD106); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD107); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD108); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD109); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD10A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD10B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD10C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD10D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD10E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD10F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD110); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD111); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD112); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD113); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD114); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD115); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD116); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD117); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD118); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD119); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD11A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD11B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD11C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD11D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD11E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD11F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD120); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD121); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD122); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD123); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD124); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD125); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD126); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD127); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD128); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD129); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD12A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD12B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD12C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD12D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD12E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD12F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD130); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD131); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD132); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD133); spi_write_dat(spi, 0xFF);
+
+ spi_write_com(spi, 0xD200); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD201); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD202); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD203); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD204); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD205); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD206); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD207); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD208); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD209); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD20A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD20B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD20C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD20D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD20E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD20F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD210); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD211); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD212); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD213); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD214); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD215); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD216); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD217); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD218); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD219); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD21A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD21B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD21C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD21D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD21E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD21F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD220); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD221); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD222); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD223); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD224); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD225); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD226); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD227); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD228); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD229); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD22A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD22B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD22C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD22D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD22E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD22F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD230); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD231); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD232); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD233); spi_write_dat(spi, 0xFF);
+
+ spi_write_com(spi, 0xD300); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD301); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD302); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD303); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD304); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD305); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD306); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD307); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD308); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD309); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD30A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD30B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD30C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD30D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD30E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD30F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD310); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD311); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD312); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD313); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD314); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD315); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD316); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD317); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD318); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD319); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD31A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD31B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD31C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD31D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD31E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD31F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD320); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD321); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD322); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD323); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD324); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD325); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD326); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD327); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD328); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD329); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD32A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD32B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD32C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD32D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD32E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD32F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD330); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD331); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD332); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD333); spi_write_dat(spi, 0xFF);
+
+ spi_write_com(spi, 0xD400); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD401); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD402); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD403); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD404); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD405); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD406); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD407); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD408); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD409); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD40A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD40B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD40C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD40D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD40E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD40F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD410); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD411); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD412); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD413); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD414); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD415); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD416); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD417); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD418); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD419); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD41A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD41B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD41C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD41D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD41E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD41F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD420); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD421); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD422); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD423); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD424); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD425); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD426); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD427); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD428); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD429); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD42A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD42B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD42C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD42D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD42E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD42F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD430); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD431); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD432); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD433); spi_write_dat(spi, 0xFF);
+
+ spi_write_com(spi, 0xD500); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD501); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD502); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD503); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD504); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD505); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD506); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD507); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD508); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD509); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD50A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD50B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD50C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD50D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD50E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD50F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD510); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD511); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD512); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD513); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD514); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD515); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD516); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD517); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD518); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD519); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD51A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD51B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD51C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD51D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD51E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD51F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD520); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD521); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD522); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD523); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD524); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD525); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD526); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD527); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD528); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD529); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD52A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD52B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD52C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD52D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD52E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD52F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD530); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD531); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD532); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD533); spi_write_dat(spi, 0xFF);
+
+ spi_write_com(spi, 0xD600); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD601); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xD602); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD603); spi_write_dat(spi, 0x15);
+ spi_write_com(spi, 0xD604); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD605); spi_write_dat(spi, 0x30);
+ spi_write_com(spi, 0xD606); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD607); spi_write_dat(spi, 0x47);
+ spi_write_com(spi, 0xD608); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD609); spi_write_dat(spi, 0x5B);
+ spi_write_com(spi, 0xD60A); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD60B); spi_write_dat(spi, 0x7D);
+ spi_write_com(spi, 0xD60C); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD60D); spi_write_dat(spi, 0x9D);
+ spi_write_com(spi, 0xD60E); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD60F); spi_write_dat(spi, 0xCC);
+ spi_write_com(spi, 0xD610); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xD611); spi_write_dat(spi, 0xF3);
+ spi_write_com(spi, 0xD612); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD613); spi_write_dat(spi, 0x32);
+ spi_write_com(spi, 0xD614); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD615); spi_write_dat(spi, 0x63);
+ spi_write_com(spi, 0xD616); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD617); spi_write_dat(spi, 0xB1);
+ spi_write_com(spi, 0xD618); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD619); spi_write_dat(spi, 0xF0);
+ spi_write_com(spi, 0xD61A); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xD61B); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD61C); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD61D); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD61E); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD61F); spi_write_dat(spi, 0x67);
+ spi_write_com(spi, 0xD620); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD621); spi_write_dat(spi, 0x90);
+ spi_write_com(spi, 0xD622); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD623); spi_write_dat(spi, 0xCB);
+ spi_write_com(spi, 0xD624); spi_write_dat(spi, 0x02);
+ spi_write_com(spi, 0xD625); spi_write_dat(spi, 0xF2);
+ spi_write_com(spi, 0xD626); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD627); spi_write_dat(spi, 0x2A);
+ spi_write_com(spi, 0xD628); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD629); spi_write_dat(spi, 0x51);
+ spi_write_com(spi, 0xD62A); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD62B); spi_write_dat(spi, 0x80);
+ spi_write_com(spi, 0xD62C); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD62D); spi_write_dat(spi, 0x9F);
+ spi_write_com(spi, 0xD62E); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD62F); spi_write_dat(spi, 0xBE);
+ spi_write_com(spi, 0xD630); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD631); spi_write_dat(spi, 0xF9);
+ spi_write_com(spi, 0xD632); spi_write_dat(spi, 0x03);
+ spi_write_com(spi, 0xD633); spi_write_dat(spi, 0xFF);
+
+ /* LV2 Page 0 enable */
+ spi_write_com(spi, 0xF000); spi_write_dat(spi, 0x55);
+ spi_write_com(spi, 0xF001); spi_write_dat(spi, 0xAA);
+ spi_write_com(spi, 0xF002); spi_write_dat(spi, 0x52);
+ spi_write_com(spi, 0xF003); spi_write_dat(spi, 0x08);
+ spi_write_com(spi, 0xF004); spi_write_dat(spi, 0x00);
+
+ /* Display control */
+ spi_write_com(spi, 0xB100); spi_write_dat(spi, 0xFC);
+ spi_write_com(spi, 0xB101); spi_write_dat(spi, 0x00);
+
+ /* Source hold time */
+ spi_write_com(spi, 0xB600); spi_write_dat(spi, 0x05);
+
+ /* Gate EQ control */
+ spi_write_com(spi, 0xB700); spi_write_dat(spi, 0x70);
+ spi_write_com(spi, 0xB701); spi_write_dat(spi, 0x70);
+
+ /* Source EQ control (Mode 2) */
+ spi_write_com(spi, 0xB800); spi_write_dat(spi, 0x01);
+ spi_write_com(spi, 0xB801); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xB802); spi_write_dat(spi, 0x05);
+ spi_write_com(spi, 0xB803); spi_write_dat(spi, 0x05);
+
+ /* Inversion mode (Column) */
+ spi_write_com(spi, 0xBC00); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xBC01); spi_write_dat(spi, 0x00);
+ spi_write_com(spi, 0xBC02); spi_write_dat(spi, 0x00);
+
+ /* Timing control 8phase dual side/4H/4delay/RST_EN */
+ spi_write_com(spi, 0xC900); spi_write_dat(spi, 0xD0);
+ spi_write_com(spi, 0xC901); spi_write_dat(spi, 0x82);
+ spi_write_com(spi, 0xC902); spi_write_dat(spi, 0x50);
+ spi_write_com(spi, 0xC903); spi_write_dat(spi, 0x50);
+ spi_write_com(spi, 0xC904); spi_write_dat(spi, 0x50);
+
+ spi_write_com(spi, 0x3A00); spi_write_dat(spi, 0x55);
+ mdelay(120);
+ spi_write_com(spi, 0x1100);
+ mdelay(120);
+ spi_write_com(spi, 0x2900);
+ mdelay(120);
+ /* spi_write_com(spi, 0x2100); spi_write_dat(spi, 0x00); */
+ spi_write_com(spi, 0x2C00);
+
+ return 0;
+err_claim_bus:
+ spi_free_slave(spi);
+ return -1;
+}
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 7e255ce..3ade624 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -18,6 +18,7 @@ COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
COBJS-$(CONFIG_S5P) += s5p_wdt.o
COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
COBJS-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o
+COBJS-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
new file mode 100644
index 0000000..7ea4b60
--- /dev/null
+++ b/drivers/watchdog/omap_wdt.c
@@ -0,0 +1,121 @@
+/*
+ * omap_wdt.c
+ *
+ * (C) Copyright 2013
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Based on:
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
+ *
+ * commit 2d991a164a61858012651e13c59521975504e260
+ * Author: Bill Pemberton <wfp5p@virginia.edu>
+ * Date: Mon Nov 19 13:21:41 2012 -0500
+ *
+ * watchdog: remove use of __devinit
+ *
+ * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
+ * needed.
+ *
+ * Author: MontaVista Software, Inc.
+ * <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ * Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ * Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ * 1. Modified to support OMAP1610 32-KHz watchdog timer
+ * 2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ * Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/cpu.h>
+
+/* Hardware timeout in seconds */
+#define WDT_HW_TIMEOUT 60
+
+static unsigned int wdt_trgr_pattern = 0x1234;
+
+void hw_watchdog_reset(void)
+{
+ struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+ /* wait for posted write to complete */
+ while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+ ;
+
+ wdt_trgr_pattern = ~wdt_trgr_pattern;
+ writel(wdt_trgr_pattern, &wdt->wdtwtgr);
+
+ /* wait for posted write to complete */
+ while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
+ ;
+}
+
+static int omap_wdt_set_timeout(unsigned int timeout)
+{
+ struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+ u32 pre_margin = GET_WLDR_VAL(timeout);
+
+ /* just count up at 32 KHz */
+ while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+ ;
+
+ writel(pre_margin, &wdt->wdtwldr);
+ while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+ ;
+
+ return 0;
+}
+
+void hw_watchdog_init(void)
+{
+ struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+ /* initialize prescaler */
+ while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+ ;
+
+ writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
+ while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+ ;
+
+ omap_wdt_set_timeout(WDT_HW_TIMEOUT);
+
+ /* Sequence to enable the watchdog */
+ writel(0xBBBB, &wdt->wdtwspr);
+ while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+ ;
+
+ writel(0x4444, &wdt->wdtwspr);
+ while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+ ;
+}
+
+void hw_watchdog_disable(void)
+{
+ struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+ /*
+ * Disable watchdog
+ */
+ writel(0xAAAA, &wdt->wdtwspr);
+ while (readl(&wdt->wdtwwps) != 0x0)
+ ;
+ writel(0x5555, &wdt->wdtwspr);
+ while (readl(&wdt->wdtwwps) != 0x0)
+ ;
+}