summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/Makefile7
-rw-r--r--drivers/block/mvsata_ide.c140
-rw-r--r--drivers/dma/fsl_dma.c8
-rw-r--r--drivers/i2c/Makefile2
-rw-r--r--drivers/i2c/kirkwood_i2c.c496
-rw-r--r--drivers/i2c/mvtwsi.c428
-rw-r--r--drivers/i2c/omap24xx_i2c.c31
-rw-r--r--drivers/i2c/omap24xx_i2c.h8
-rw-r--r--drivers/mmc/omap3_mmc.c68
-rw-r--r--drivers/mmc/omap3_mmc.h9
-rw-r--r--drivers/mtd/cfi_flash.c97
-rw-r--r--drivers/net/4xx_enet.c4
-rw-r--r--drivers/net/altera_tse.c4
-rw-r--r--drivers/net/at91_emac.c6
-rw-r--r--drivers/net/bfin_mac.c4
-rw-r--r--drivers/net/davinci_emac.c4
-rw-r--r--drivers/net/designware.c4
-rw-r--r--drivers/net/eepro100.c7
-rw-r--r--drivers/net/ep93xx_eth.c8
-rw-r--r--drivers/net/fec_mxc.c6
-rw-r--r--drivers/net/macb.c4
-rw-r--r--drivers/net/mcfmii.c4
-rw-r--r--drivers/net/mpc512x_fec.c10
-rw-r--r--drivers/net/mpc5xxx_fec.c10
-rw-r--r--drivers/net/mvgbe.c4
-rw-r--r--drivers/net/ns7520_eth.c4
-rw-r--r--drivers/net/phy/miiphybb.c6
-rw-r--r--drivers/net/tsec.c8
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/twl6030.c78
-rw-r--r--drivers/qe/uec.c8
-rw-r--r--drivers/qe/uec_phy.c6
-rw-r--r--drivers/usb/musb/Makefile1
-rw-r--r--drivers/usb/musb/am35x.c150
-rw-r--r--drivers/usb/musb/am35x.h94
-rw-r--r--drivers/usb/musb/musb_core.c6
-rw-r--r--drivers/usb/musb/musb_udc.c2
-rw-r--r--drivers/usb/musb/omap3.c16
-rw-r--r--drivers/usb/musb/omap3.h3
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/mb86r0xgdc.c186
41 files changed, 1292 insertions, 651 deletions
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 3f6ad5c..64dcf4e 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -25,15 +25,16 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libblock.a
+COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
COBJS-$(CONFIG_ATA_PIIX) += ata_piix.o
-COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o
COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o
-COBJS-$(CONFIG_IDE_SIL680) += sil680.o
COBJS-$(CONFIG_LIBATA) += libata.o
+COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o
+COBJS-$(CONFIG_MVSATA_IDE) += mvsata_ide.o
COBJS-$(CONFIG_PATA_BFIN) += pata_bfin.o
COBJS-$(CONFIG_SATA_DWC) += sata_dwc.o
COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
-COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
+COBJS-$(CONFIG_IDE_SIL680) += sil680.o
COBJS-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
COBJS-$(CONFIG_SYSTEMACE) += systemace.o
diff --git a/drivers/block/mvsata_ide.c b/drivers/block/mvsata_ide.c
new file mode 100644
index 0000000..077b278
--- /dev/null
+++ b/drivers/block/mvsata_ide.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 Albert ARIBAUD <albert.aribaud@free.fr>
+ *
+ * Written-by: Albert ARIBAUD <albert.aribaud@free.fr>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_ORION5X)
+#include <asm/arch/orion5x.h>
+#elif defined(CONFIG_KIRKWOOD)
+#include <asm/arch/kirkwood.h>
+#endif
+
+/* SATA port registers */
+struct mvsata_port_registers {
+ u32 reserved1[192];
+ /* offset 0x300 : ATA Interface registers */
+ u32 sstatus;
+ u32 serror;
+ u32 scontrol;
+ u32 ltmode;
+ u32 phymode3;
+ u32 phymode4;
+ u32 reserved2[5];
+ u32 phymode1;
+ u32 phymode2;
+ u32 bist_cr;
+ u32 bist_dw1;
+ u32 bist_dw2;
+ u32 serrorintrmask;
+};
+
+/*
+ * Sanity checks:
+ * - to compile at all, we need CONFIG_SYS_ATA_BASE_ADDR.
+ * - for ide_preinit to make sense, we need at least one of
+ * CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE0_OFFSET;
+ * - for inde_preinit to be called, we need CONFIG_IDE_PREINIT.
+ * Fail with an explanation message if these conditions are not met.
+ * This is particularly important for CONFIG_IDE_PREINIT, because
+ * its lack would not cause a build error.
+ */
+
+#if !defined(CONFIG_SYS_ATA_BASE_ADDR)
+#error CONFIG_SYS_ATA_BASE_ADDR must be defined
+#elif !defined(CONFIG_SYS_ATA_IDE0_OFFSET) \
+ && !defined(CONFIG_SYS_ATA_IDE1_OFFSET)
+#error CONFIG_SYS_ATA_IDE0_OFFSET or CONFIG_SYS_ATA_IDE1_OFFSET \
+ must be defined
+#elif !defined(CONFIG_IDE_PREINIT)
+#error CONFIG_IDE_PREINIT must be defined
+#endif
+
+/*
+ * Masks and values for SControl DETection and Interface Power Management,
+ * and for SStatus DETection.
+ */
+
+#define MVSATA_SCONTROL_DET_MASK 0x0000000F
+#define MVSATA_SCONTROL_DET_NONE 0x00000000
+#define MVSATA_SCONTROL_DET_INIT 0x00000001
+#define MVSATA_SCONTROL_IPM_MASK 0x00000F00
+#define MVSATA_SCONTROL_IPM_NO_LP_ALLOWED 0x00000300
+#define MVSATA_SCONTROL_MASK \
+ (MVSATA_SCONTROL_DET_MASK|MVSATA_SCONTROL_IPM_MASK)
+#define MVSATA_PORT_INIT \
+ (MVSATA_SCONTROL_DET_INIT|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
+#define MVSATA_PORT_USE \
+ (MVSATA_SCONTROL_DET_NONE|MVSATA_SCONTROL_IPM_NO_LP_ALLOWED)
+#define MVSATA_SSTATUS_DET_MASK 0x0000000F
+#define MVSATA_SSTATUS_DET_DEVCOMM 0x00000003
+
+/*
+ * Initialize one MVSATAHC port: set SControl's IPM to "always active"
+ * and DET to "reset", then wait for SStatus's DET to become "device and
+ * comm ok" (or time out after 50 us if no device), then set SControl's
+ * DET back to "no action".
+ */
+
+static void mvsata_ide_initialize_port(struct mvsata_port_registers *port)
+{
+ u32 control;
+ u32 status;
+ u32 tout = 50; /* wait at most 50 us for SATA reset to complete */
+
+ control = readl(&port->scontrol);
+ control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT;
+ writel(control, &port->scontrol);
+ while (--tout) {
+ status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK;
+ if (status == MVSATA_SSTATUS_DET_DEVCOMM)
+ break;
+ udelay(1);
+ }
+ control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE;
+ writel(control, &port->scontrol);
+}
+
+/*
+ * ide_preinit() will be called by ide_init in cmd_ide.c and will
+ * reset the MVSTATHC ports needed by the board.
+ */
+
+int ide_preinit(void)
+{
+ /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */
+#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
+ mvsata_ide_initialize_port(
+ (struct mvsata_port_registers *)
+ (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET));
+#endif
+ /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */
+#if defined(CONFIG_SYS_ATA_IDE1_OFFSET)
+ mvsata_ide_initialize_port(
+ (struct mvsata_port_registers *)
+ (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET));
+#endif
+ /* return 0 as we always succeed */
+ return 0;
+}
diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c
index df33e7a..09c18c1 100644
--- a/drivers/dma/fsl_dma.c
+++ b/drivers/dma/fsl_dma.c
@@ -114,8 +114,12 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
while (count) {
xfer_size = MIN(FSL_DMA_MAX_SIZE, count);
- out_dma32(&dma->dar, (uint) dest);
- out_dma32(&dma->sar, (uint) src);
+ out_dma32(&dma->dar, (u32) (dest & 0xFFFFFFFF));
+ out_dma32(&dma->sar, (u32) (src & 0xFFFFFFFF));
+ out_dma32(&dma->satr,
+ in_dma32(&dma->satr) | (u32)((u64)src >> 32));
+ out_dma32(&dma->datr,
+ in_dma32(&dma->datr) | (u32)((u64)dest >> 32));
out_dma32(&dma->bcr, xfer_size);
dma_sync();
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index d2c2515..8921ff9 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -28,7 +28,7 @@ LIB := $(obj)libi2c.a
COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
-COBJS-$(CONFIG_I2C_KIRKWOOD) += kirkwood_i2c.o
+COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/kirkwood_i2c.c b/drivers/i2c/kirkwood_i2c.c
deleted file mode 100644
index a4409be..0000000
--- a/drivers/i2c/kirkwood_i2c.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Driver for the i2c controller on the Marvell line of host bridges
- * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, Orion SoC family),
- * and Kirkwood family.
- *
- * Based on:
- * Author: Mark A. Greer <mgreer@mvista.com>
- * 2005 (c) MontaVista, Software, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * ported from Linux to u-boot
- * (C) Copyright 2009
- * Heiko Schocher, DENX Software Engineering, hs@denx.de.
- */
-#include <common.h>
-#include <i2c.h>
-#include <asm/arch/kirkwood.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
-#if defined(CONFIG_I2C_MUX)
-static unsigned int i2c_bus_num_mux __attribute__ ((section ("data"))) = 0;
-#endif
-
-/* Register defines */
-#define KW_I2C_REG_SLAVE_ADDR 0x00
-#define KW_I2C_REG_DATA 0x04
-#define KW_I2C_REG_CONTROL 0x08
-#define KW_I2C_REG_STATUS 0x0c
-#define KW_I2C_REG_BAUD 0x0c
-#define KW_I2C_REG_EXT_SLAVE_ADDR 0x10
-#define KW_I2C_REG_SOFT_RESET 0x1c
-
-#define KW_I2C_REG_CONTROL_ACK 0x00000004
-#define KW_I2C_REG_CONTROL_IFLG 0x00000008
-#define KW_I2C_REG_CONTROL_STOP 0x00000010
-#define KW_I2C_REG_CONTROL_START 0x00000020
-#define KW_I2C_REG_CONTROL_TWSIEN 0x00000040
-#define KW_I2C_REG_CONTROL_INTEN 0x00000080
-
-/* Ctlr status values */
-#define KW_I2C_STATUS_BUS_ERR 0x00
-#define KW_I2C_STATUS_MAST_START 0x08
-#define KW_I2C_STATUS_MAST_REPEAT_START 0x10
-#define KW_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
-#define KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
-#define KW_I2C_STATUS_MAST_WR_ACK 0x28
-#define KW_I2C_STATUS_MAST_WR_NO_ACK 0x30
-#define KW_I2C_STATUS_MAST_LOST_ARB 0x38
-#define KW_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
-#define KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
-#define KW_I2C_STATUS_MAST_RD_DATA_ACK 0x50
-#define KW_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
-#define KW_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
-#define KW_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
-#define KW_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
-#define KW_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
-#define KW_I2C_STATUS_NO_STATUS 0xf8
-
-/* Driver states */
-enum {
- KW_I2C_STATE_INVALID,
- KW_I2C_STATE_IDLE,
- KW_I2C_STATE_WAITING_FOR_START_COND,
- KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
- KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
- KW_I2C_STATE_WAITING_FOR_SLAVE_ACK,
- KW_I2C_STATE_WAITING_FOR_SLAVE_DATA,
-};
-
-/* Driver actions */
-enum {
- KW_I2C_ACTION_INVALID,
- KW_I2C_ACTION_CONTINUE,
- KW_I2C_ACTION_SEND_START,
- KW_I2C_ACTION_SEND_ADDR_1,
- KW_I2C_ACTION_SEND_ADDR_2,
- KW_I2C_ACTION_SEND_DATA,
- KW_I2C_ACTION_RCV_DATA,
- KW_I2C_ACTION_RCV_DATA_STOP,
- KW_I2C_ACTION_SEND_STOP,
-};
-
-/* defines to get compatible with Linux driver */
-#define IRQ_NONE 0x0
-#define IRQ_HANDLED 0x01
-
-#define I2C_M_TEN 0x01
-#define I2C_M_RD 0x02
-#define I2C_M_REV_DIR_ADDR 0x04;
-
-struct i2c_msg {
- u32 addr;
- u32 flags;
- u8 *buf;
- u32 len;
-};
-
-struct kirkwood_i2c_data {
- int irq;
- u32 state;
- u32 action;
- u32 aborting;
- u32 cntl_bits;
- void *reg_base;
- u32 reg_base_p;
- u32 reg_size;
- u32 addr1;
- u32 addr2;
- u32 bytes_left;
- u32 byte_posn;
- u32 block;
- int rc;
- u32 freq_m;
- u32 freq_n;
- struct i2c_msg *msg;
-};
-
-static struct kirkwood_i2c_data __drv_data __attribute__ ((section (".data")));
-static struct kirkwood_i2c_data *drv_data = &__drv_data;
-static struct i2c_msg __i2c_msg __attribute__ ((section (".data")));
-static struct i2c_msg *kirkwood_i2c_msg = &__i2c_msg;
-
-/*
- *****************************************************************************
- *
- * Finite State Machine & Interrupt Routines
- *
- *****************************************************************************
- */
-
-static inline int abs(int n)
-{
- if(n >= 0)
- return n;
- else
- return n * -1;
-}
-
-static void kirkwood_calculate_speed(int speed)
-{
- int calcspeed;
- int diff;
- int best_diff = CONFIG_SYS_TCLK;
- int best_speed = 0;
- int m, n;
- int tmp[8] = {2, 4, 8, 16, 32, 64, 128, 256};
-
- for (n = 0; n < 8; n++) {
- for (m = 0; m < 16; m++) {
- calcspeed = CONFIG_SYS_TCLK / (10 * (m + 1) * tmp[n]);
- diff = abs((speed - calcspeed));
- if ( diff < best_diff) {
- best_diff = diff;
- best_speed = calcspeed;
- drv_data->freq_m = m;
- drv_data->freq_n = n;
- }
- }
- }
-}
-
-/* Reset hardware and initialize FSM */
-static void
-kirkwood_i2c_hw_init(int speed, int slaveadd)
-{
- drv_data->state = KW_I2C_STATE_IDLE;
-
- kirkwood_calculate_speed(speed);
- writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SOFT_RESET);
- writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_BAUD);
- writel(slaveadd, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SLAVE_ADDR);
- writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_EXT_SLAVE_ADDR);
- writel(KW_I2C_REG_CONTROL_TWSIEN | KW_I2C_REG_CONTROL_STOP,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
-}
-
-static void
-kirkwood_i2c_fsm(u32 status)
-{
- /*
- * If state is idle, then this is likely the remnants of an old
- * operation that driver has given up on or the user has killed.
- * If so, issue the stop condition and go to idle.
- */
- if (drv_data->state == KW_I2C_STATE_IDLE) {
- drv_data->action = KW_I2C_ACTION_SEND_STOP;
- return;
- }
-
- /* The status from the ctlr [mostly] tells us what to do next */
- switch (status) {
- /* Start condition interrupt */
- case KW_I2C_STATUS_MAST_START: /* 0x08 */
- case KW_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */
- drv_data->action = KW_I2C_ACTION_SEND_ADDR_1;
- drv_data->state = KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
- break;
-
- /* Performing a write */
- case KW_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */
- if (drv_data->msg->flags & I2C_M_TEN) {
- drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
- drv_data->state =
- KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
- break;
- }
- /* FALLTHRU */
- case KW_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
- case KW_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
- if ((drv_data->bytes_left == 0)
- || (drv_data->aborting
- && (drv_data->byte_posn != 0))) {
- drv_data->action = KW_I2C_ACTION_SEND_STOP;
- drv_data->state = KW_I2C_STATE_IDLE;
- } else {
- drv_data->action = KW_I2C_ACTION_SEND_DATA;
- drv_data->state =
- KW_I2C_STATE_WAITING_FOR_SLAVE_ACK;
- drv_data->bytes_left--;
- }
- break;
-
- /* Performing a read */
- case KW_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */
- if (drv_data->msg->flags & I2C_M_TEN) {
- drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
- drv_data->state =
- KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
- break;
- }
- /* FALLTHRU */
- case KW_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
- if (drv_data->bytes_left == 0) {
- drv_data->action = KW_I2C_ACTION_SEND_STOP;
- drv_data->state = KW_I2C_STATE_IDLE;
- break;
- }
- /* FALLTHRU */
- case KW_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
- if (status != KW_I2C_STATUS_MAST_RD_DATA_ACK)
- drv_data->action = KW_I2C_ACTION_CONTINUE;
- else {
- drv_data->action = KW_I2C_ACTION_RCV_DATA;
- drv_data->bytes_left--;
- }
- drv_data->state = KW_I2C_STATE_WAITING_FOR_SLAVE_DATA;
-
- if ((drv_data->bytes_left == 1) || drv_data->aborting)
- drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_ACK;
- break;
-
- case KW_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */
- drv_data->action = KW_I2C_ACTION_RCV_DATA_STOP;
- drv_data->state = KW_I2C_STATE_IDLE;
- break;
-
- case KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */
- case KW_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */
- case KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */
- /* Doesn't seem to be a device at other end */
- drv_data->action = KW_I2C_ACTION_SEND_STOP;
- drv_data->state = KW_I2C_STATE_IDLE;
- drv_data->rc = -ENODEV;
- break;
-
- default:
- printf("kirkwood_i2c_fsm: Ctlr Error -- state: 0x%x, "
- "status: 0x%x, addr: 0x%x, flags: 0x%x\n",
- drv_data->state, status, drv_data->msg->addr,
- drv_data->msg->flags);
- drv_data->action = KW_I2C_ACTION_SEND_STOP;
- kirkwood_i2c_hw_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
- drv_data->rc = -EIO;
- }
-}
-
-static void
-kirkwood_i2c_do_action(void)
-{
- switch(drv_data->action) {
- case KW_I2C_ACTION_CONTINUE:
- writel(drv_data->cntl_bits,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_SEND_START:
- writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_START,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_SEND_ADDR_1:
- writel(drv_data->addr1,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_SEND_ADDR_2:
- writel(drv_data->addr2,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_SEND_DATA:
- writel(drv_data->msg->buf[drv_data->byte_posn++],
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_RCV_DATA:
- drv_data->msg->buf[drv_data->byte_posn++] =
- readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
- writel(drv_data->cntl_bits,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- break;
-
- case KW_I2C_ACTION_RCV_DATA_STOP:
- drv_data->msg->buf[drv_data->byte_posn++] =
- readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
- drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
- writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- drv_data->block = 0;
- break;
-
- case KW_I2C_ACTION_INVALID:
- default:
- printf("kirkwood_i2c_do_action: Invalid action: %d\n",
- drv_data->action);
- drv_data->rc = -EIO;
- /* FALLTHRU */
- case KW_I2C_ACTION_SEND_STOP:
- drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
- writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
- CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- drv_data->block = 0;
- break;
- }
-}
-
-static int
-kirkwood_i2c_intr(void)
-{
- u32 status;
- u32 ctrl;
- int rc = IRQ_NONE;
-
- ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- while ((ctrl & KW_I2C_REG_CONTROL_IFLG) &&
- (drv_data->rc == 0)) {
- status = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_STATUS);
- kirkwood_i2c_fsm(status);
- kirkwood_i2c_do_action();
- rc = IRQ_HANDLED;
- ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
- udelay(1000);
- }
- return rc;
-}
-
-static void
-kirkwood_i2c_doio(struct i2c_msg *msg)
-{
- int ret;
-
- while ((drv_data->rc == 0) && (drv_data->state != KW_I2C_STATE_IDLE)) {
- /* poll Status register */
- ret = kirkwood_i2c_intr();
- if (ret == IRQ_NONE)
- udelay(10);
- }
-}
-
-static void
-kirkwood_i2c_prepare_for_io(struct i2c_msg *msg)
-{
- u32 dir = 0;
-
- drv_data->msg = msg;
- drv_data->byte_posn = 0;
- drv_data->bytes_left = msg->len;
- drv_data->aborting = 0;
- drv_data->rc = 0;
- /* in u-boot we use no IRQs */
- drv_data->cntl_bits = KW_I2C_REG_CONTROL_ACK | KW_I2C_REG_CONTROL_TWSIEN;
-
- if (msg->flags & I2C_M_RD)
- dir = 1;
- if (msg->flags & I2C_M_TEN) {
- drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
- drv_data->addr2 = (u32)msg->addr & 0xff;
- } else {
- drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
- drv_data->addr2 = 0;
- }
- /* OK, no start it (from kirkwood_i2c_execute_msg())*/
- drv_data->action = KW_I2C_ACTION_SEND_START;
- drv_data->state = KW_I2C_STATE_WAITING_FOR_START_COND;
- drv_data->block = 1;
- kirkwood_i2c_do_action();
-}
-
-void
-i2c_init(int speed, int slaveadd)
-{
- kirkwood_i2c_hw_init(speed, slaveadd);
-}
-
-int
-i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
-{
- kirkwood_i2c_msg->buf = data;
- kirkwood_i2c_msg->len = length;
- kirkwood_i2c_msg->addr = dev;
- kirkwood_i2c_msg->flags = I2C_M_RD;
-
- kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
- kirkwood_i2c_doio(kirkwood_i2c_msg);
- return drv_data->rc;
-}
-
-int
-i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
-{
- kirkwood_i2c_msg->buf = data;
- kirkwood_i2c_msg->len = length;
- kirkwood_i2c_msg->addr = dev;
- kirkwood_i2c_msg->flags = 0;
-
- kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
- kirkwood_i2c_doio(kirkwood_i2c_msg);
- return drv_data->rc;
-}
-
-int
-i2c_probe(uchar chip)
-{
- return i2c_read(chip, 0, 0, NULL, 0);
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#if defined(CONFIG_I2C_MUX)
- if (bus < CONFIG_SYS_MAX_I2C_BUS) {
- i2c_bus_num = bus;
- } else {
- int ret;
-
- ret = i2x_mux_select_mux(bus);
- if (ret)
- return ret;
- i2c_bus_num = 0;
- }
- i2c_bus_num_mux = bus;
-#else
- if (bus > 0) {
- return -1;
- }
-
- i2c_bus_num = bus;
-#endif
- return 0;
-}
-
-unsigned int i2c_get_bus_num(void)
-{
-#if defined(CONFIG_I2C_MUX)
- return i2c_bus_num_mux;
-#else
- return i2c_bus_num;
-#endif
-}
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
new file mode 100644
index 0000000..16a536f
--- /dev/null
+++ b/drivers/i2c/mvtwsi.c
@@ -0,0 +1,428 @@
+/*
+ * Driver for the TWSI (i2c) controller found on the Marvell
+ * orion5x and kirkwood SoC families.
+ *
+ * Author: Albert Aribaud <albert.aribaud@free.fr>
+ * Copyright (c) 2010 Albert Aribaud.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+/*
+ * include a file that will provide CONFIG_I2C_MVTWSI_BASE
+ * and possibly other settings
+ */
+
+#if defined(CONFIG_ORION5X)
+#include <asm/arch/orion5x.h>
+#elif defined(CONFIG_KIRKWOOD)
+#include <asm/arch/kirkwood.h>
+#else
+#error Driver mvtwsi not supported by SoC or board
+#endif
+
+/*
+ * TWSI register structure
+ */
+
+struct mvtwsi_registers {
+ u32 slave_address;
+ u32 data;
+ u32 control;
+ union {
+ u32 status; /* when reading */
+ u32 baudrate; /* when writing */
+ };
+ u32 xtnd_slave_addr;
+ u32 reserved[2];
+ u32 soft_reset;
+};
+
+/*
+ * Control register fields
+ */
+
+#define MVTWSI_CONTROL_ACK 0x00000004
+#define MVTWSI_CONTROL_IFLG 0x00000008
+#define MVTWSI_CONTROL_STOP 0x00000010
+#define MVTWSI_CONTROL_START 0x00000020
+#define MVTWSI_CONTROL_TWSIEN 0x00000040
+#define MVTWSI_CONTROL_INTEN 0x00000080
+
+/*
+ * Status register values -- only those expected in normal master
+ * operation on non-10-bit-address devices; whatever status we don't
+ * expect in nominal conditions (bus errors, arbitration losses,
+ * missing ACKs...) we just pass back to the caller as an error
+ * code.
+ */
+
+#define MVTWSI_STATUS_START 0x08
+#define MVTWSI_STATUS_REPEATED_START 0x10
+#define MVTWSI_STATUS_ADDR_W_ACK 0x18
+#define MVTWSI_STATUS_DATA_W_ACK 0x28
+#define MVTWSI_STATUS_ADDR_R_ACK 0x40
+#define MVTWSI_STATUS_ADDR_R_NAK 0x48
+#define MVTWSI_STATUS_DATA_R_ACK 0x50
+#define MVTWSI_STATUS_DATA_R_NAK 0x58
+#define MVTWSI_STATUS_IDLE 0xF8
+
+/*
+ * The single instance of the controller we'll be dealing with
+ */
+
+static struct mvtwsi_registers *twsi =
+ (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE;
+
+/*
+ * Returned statuses are 0 for success and nonzero otherwise.
+ * Currently, cmd_i2c and cmd_eeprom do not interpret an error status.
+ * Thus to ease debugging, the return status contains some debug info:
+ * - bits 31..24 are error class: 1 is timeout, 2 is 'status mismatch'.
+ * - bits 23..16 are the last value of the control register.
+ * - bits 15..8 are the last value of the status register.
+ * - bits 7..0 are the expected value of the status register.
+ */
+
+#define MVTWSI_ERROR_WRONG_STATUS 0x01
+#define MVTWSI_ERROR_TIMEOUT 0x02
+
+#define MVTWSI_ERROR(ec, lc, ls, es) (((ec << 24) & 0xFF000000) | \
+ ((lc << 16) & 0x00FF0000) | ((ls<<8) & 0x0000FF00) | (es & 0xFF))
+
+/*
+ * Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
+ * return 0 (ok) or return 'wrong status'.
+ */
+static int twsi_wait(int expected_status)
+{
+ int control, status;
+ int timeout = 1000;
+
+ do {
+ control = readl(&twsi->control);
+ if (control & MVTWSI_CONTROL_IFLG) {
+ status = readl(&twsi->status);
+ if (status == expected_status)
+ return 0;
+ else
+ return MVTWSI_ERROR(
+ MVTWSI_ERROR_WRONG_STATUS,
+ control, status, expected_status);
+ }
+ udelay(10); /* one clock cycle at 100 kHz */
+ } while (timeout--);
+ status = readl(&twsi->status);
+ return MVTWSI_ERROR(
+ MVTWSI_ERROR_TIMEOUT, control, status, expected_status);
+}
+
+/*
+ * These flags are ORed to any write to the control register
+ * They allow global setting of TWSIEN and ACK.
+ * By default none are set.
+ * twsi_start() sets TWSIEN (in case the controller was disabled)
+ * twsi_recv() sets ACK or resets it depending on expected status.
+ */
+static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
+
+/*
+ * Assert the START condition, either in a single I2C transaction
+ * or inside back-to-back ones (repeated starts).
+ */
+static int twsi_start(int expected_status)
+{
+ /* globally set TWSIEN in case it was not */
+ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN;
+ /* assert START */
+ writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control);
+ /* wait for controller to process START */
+ return twsi_wait(expected_status);
+}
+
+/*
+ * Send a byte (i2c address or data).
+ */
+static int twsi_send(u8 byte, int expected_status)
+{
+ /* put byte in data register for sending */
+ writel(byte, &twsi->data);
+ /* clear any pending interrupt -- that'll cause sending */
+ writel(twsi_control_flags, &twsi->control);
+ /* wait for controller to receive byte and check ACK */
+ return twsi_wait(expected_status);
+}
+
+/*
+ * Receive a byte.
+ * Global mvtwsi_control_flags variable says if we should ack or nak.
+ */
+static int twsi_recv(u8 *byte)
+{
+ int expected_status, status;
+
+ /* compute expected status based on ACK bit in global control flags */
+ if (twsi_control_flags & MVTWSI_CONTROL_ACK)
+ expected_status = MVTWSI_STATUS_DATA_R_ACK;
+ else
+ expected_status = MVTWSI_STATUS_DATA_R_NAK;
+ /* acknowledge *previous state* and launch receive */
+ writel(twsi_control_flags, &twsi->control);
+ /* wait for controller to receive byte and assert ACK or NAK */
+ status = twsi_wait(expected_status);
+ /* if we did receive expected byte then store it */
+ if (status == 0)
+ *byte = readl(&twsi->data);
+ /* return status */
+ return status;
+}
+
+/*
+ * Assert the STOP condition.
+ * This is also used to force the bus back in idle (SDA=SCL=1).
+ */
+static int twsi_stop(int status)
+{
+ int control, stop_status;
+ int timeout = 1000;
+
+ /* assert STOP */
+ control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
+ writel(control, &twsi->control);
+ /* wait for IDLE; IFLG won't rise so twsi_wait() is no use. */
+ do {
+ stop_status = readl(&twsi->status);
+ if (stop_status == MVTWSI_STATUS_IDLE)
+ break;
+ udelay(10); /* one clock cycle at 100 kHz */
+ } while (timeout--);
+ control = readl(&twsi->control);
+ if (stop_status != MVTWSI_STATUS_IDLE)
+ if (status == 0)
+ status = MVTWSI_ERROR(
+ MVTWSI_ERROR_TIMEOUT,
+ control, status, MVTWSI_STATUS_IDLE);
+ return status;
+}
+
+/*
+ * Ugly formula to convert m and n values to a frequency comes from
+ * TWSI specifications
+ */
+
+#define TWSI_FREQUENCY(m, n) \
+ ((u8) (CONFIG_SYS_TCLK / (10 * (m + 1) * 2 * (1 << n))))
+
+/*
+ * These are required to be reprogrammed before enabling the controller
+ * because a reset loses them.
+ * Default values come from the spec, but a twsi_reset will change them.
+ * twsi_slave_address left uninitialized lest checkpatch.pl complains.
+ */
+
+/* Baudrate generator: m (bits 7..4) =4, n (bits 3..0) =4 */
+static u8 twsi_baud_rate = 0x44; /* baudrate at controller reset */
+/* Default frequency corresponding to default m=4, n=4 */
+static u8 twsi_actual_speed = TWSI_FREQUENCY(4, 4);
+/* Default slave address is 0 (so is an uninitialized static) */
+static u8 twsi_slave_address;
+
+/*
+ * Reset controller.
+ * Called at end of i2c_init unsuccessful i2c transactions.
+ * Controller reset also resets the baud rate and slave address, so
+ * re-establish them.
+ */
+static void twsi_reset(void)
+{
+ /* ensure controller will be enabled by any twsi*() function */
+ twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
+ /* reset controller */
+ writel(0, &twsi->soft_reset);
+ /* wait 2 ms -- this is what the Marvell LSP does */
+ udelay(20000);
+ /* set baud rate */
+ writel(twsi_baud_rate, &twsi->baudrate);
+ /* set slave address even though we don't use it */
+ writel(twsi_slave_address, &twsi->slave_address);
+ writel(0, &twsi->xtnd_slave_addr);
+ /* assert STOP but don't care for the result */
+ (void) twsi_stop(0);
+}
+
+/*
+ * I2C init called by cmd_i2c when doing 'i2c reset'.
+ * Sets baud to the highest possible value not exceeding requested one.
+ */
+void i2c_init(int requested_speed, int slaveadd)
+{
+ int tmp_speed, highest_speed, n, m;
+ int baud = 0x44; /* baudrate at controller reset */
+
+ /* use actual speed to collect progressively higher values */
+ highest_speed = 0;
+ /* compute m, n setting for highest speed not above requested speed */
+ for (n = 0; n < 8; n++) {
+ for (m = 0; m < 16; m++) {
+ tmp_speed = TWSI_FREQUENCY(m, n);
+ if ((tmp_speed <= requested_speed)
+ && (tmp_speed > highest_speed)) {
+ highest_speed = tmp_speed;
+ baud = (m << 3) | n;
+ }
+ }
+ }
+ /* save baud rate and slave for later calls to twsi_reset */
+ twsi_baud_rate = baud;
+ twsi_actual_speed = highest_speed;
+ twsi_slave_address = slaveadd;
+ /* reset controller */
+ twsi_reset();
+}
+
+/*
+ * Begin I2C transaction with expected start status, at given address.
+ * Common to i2c_probe, i2c_read and i2c_write.
+ * Expected address status will derive from direction bit (bit 0) in addr.
+ */
+static int i2c_begin(int expected_start_status, u8 addr)
+{
+ int status, expected_addr_status;
+
+ /* compute expected address status from direction bit in addr */
+ if (addr & 1) /* reading */
+ expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
+ else /* writing */
+ expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
+ /* assert START */
+ status = twsi_start(expected_start_status);
+ /* send out the address if the start went well */
+ if (status == 0)
+ status = twsi_send(addr, expected_addr_status);
+ /* return ok or status of first failure to caller */
+ return status;
+}
+
+/*
+ * I2C probe called by cmd_i2c when doing 'i2c probe'.
+ * Begin read, nak data byte, end.
+ */
+int i2c_probe(uchar chip)
+{
+ u8 dummy_byte;
+ int status;
+
+ /* begin i2c read */
+ status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1);
+ /* dummy read was accepted: receive byte but NAK it. */
+ if (status == 0)
+ status = twsi_recv(&dummy_byte);
+ /* Stop transaction */
+ twsi_stop(0);
+ /* return 0 or status of first failure */
+ return status;
+}
+
+/*
+ * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
+ * Begin write, send address byte(s), begin read, receive data bytes, end.
+ *
+ * NOTE: some EEPROMS want a stop right before the second start, while
+ * some will choke if it is there. Deciding which we should do is eeprom
+ * stuff, not i2c, but at the moment the APIs won't let us put it in
+ * cmd_eeprom, so we have to choose here, and for the moment that'll be
+ * a repeated start without a preceding stop.
+ */
+int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ int status;
+
+ /* begin i2c write to send the address bytes */
+ status = i2c_begin(MVTWSI_STATUS_START, (dev << 1));
+ /* send addr bytes */
+ while ((status == 0) && alen--)
+ status = twsi_send(addr >> (8*alen),
+ MVTWSI_STATUS_DATA_W_ACK);
+ /* begin i2c read to receive eeprom data bytes */
+ if (status == 0)
+ status = i2c_begin(
+ MVTWSI_STATUS_REPEATED_START, (dev << 1) | 1);
+ /* prepare ACK if at least one byte must be received */
+ if (length > 0)
+ twsi_control_flags |= MVTWSI_CONTROL_ACK;
+ /* now receive actual bytes */
+ while ((status == 0) && length--) {
+ /* reset NAK if we if no more to read now */
+ if (length == 0)
+ twsi_control_flags &= ~MVTWSI_CONTROL_ACK;
+ /* read current byte */
+ status = twsi_recv(data++);
+ }
+ /* Stop transaction */
+ status = twsi_stop(status);
+ /* return 0 or status of first failure */
+ return status;
+}
+
+/*
+ * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
+ * Begin write, send address byte(s), send data bytes, end.
+ */
+int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ int status;
+
+ /* begin i2c write to send the eeprom adress bytes then data bytes */
+ status = i2c_begin(MVTWSI_STATUS_START, (dev << 1));
+ /* send addr bytes */
+ while ((status == 0) && alen--)
+ status = twsi_send(addr >> (8*alen),
+ MVTWSI_STATUS_DATA_W_ACK);
+ /* send data bytes */
+ while ((status == 0) && (length-- > 0))
+ status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK);
+ /* Stop transaction */
+ status = twsi_stop(status);
+ /* return 0 or status of first failure */
+ return status;
+}
+
+/*
+ * Bus set routine: we only support bus 0.
+ */
+int i2c_set_bus_num(unsigned int bus)
+{
+ if (bus > 0) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Bus get routine: hard-return bus 0.
+ */
+unsigned int i2c_get_bus_num(void)
+{
+ return 0;
+}
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 3256133..7c98f15 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -27,6 +27,8 @@
#include "omap24xx_i2c.h"
+#define I2C_TIMEOUT 10
+
static void wait_for_bb (void);
static u16 wait_for_pin (void);
static void flush_fifo(void);
@@ -41,6 +43,7 @@ void i2c_init (int speed, int slaveadd)
int psc, fsscll, fssclh;
int hsscll = 0, hssclh = 0;
u32 scll, sclh;
+ int timeout = I2C_TIMEOUT;
/* Only handle standard, fast and high speeds */
if ((speed != OMAP_I2C_STANDARD) &&
@@ -102,15 +105,24 @@ void i2c_init (int speed, int slaveadd)
sclh = (unsigned int)fssclh;
}
- writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
- udelay(1000);
- writew(0x0, &i2c_base->sysc); /* will probably self clear but */
-
if (readw (&i2c_base->con) & I2C_CON_EN) {
writew (0, &i2c_base->con);
udelay (50000);
}
+ writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
+ udelay(1000);
+
+ writew(I2C_CON_EN, &i2c_base->con);
+ while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
+ if (timeout <= 0) {
+ printf("ERROR: Timeout in soft-reset\n");
+ return;
+ }
+ udelay(1000);
+ }
+
+ writew(0, &i2c_base->con);
writew(psc, &i2c_base->psc);
writew(scll, &i2c_base->scll);
writew(sclh, &i2c_base->sclh);
@@ -159,15 +171,14 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
}
if (!i2c_error) {
- /* free bus, otherwise we can't use a combined transction */
- writew (0, &i2c_base->con);
- while (readw (&i2c_base->stat) || (readw (&i2c_base->con) & I2C_CON_MST)) {
+ writew (I2C_CON_EN, &i2c_base->con);
+ while (readw(&i2c_base->stat) &
+ (I2C_STAT_XRDY | I2C_STAT_ARDY)) {
udelay (10000);
/* Have to clear pending interrupt to clear I2C_STAT */
writew (0xFFFF, &i2c_base->stat);
}
- wait_for_bb ();
/* set slave address */
writew (devaddr, &i2c_base->sa);
/* read one byte from slave */
@@ -191,8 +202,8 @@ static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
if (!i2c_error) {
writew (I2C_CON_EN, &i2c_base->con);
- while (readw (&i2c_base->stat)
- || (readw (&i2c_base->con) & I2C_CON_MST)) {
+ while (readw (&i2c_base->stat) &
+ (I2C_STAT_RRDY | I2C_STAT_ARDY)) {
udelay (10000);
writew (0xFFFF, &i2c_base->stat);
}
diff --git a/drivers/i2c/omap24xx_i2c.h b/drivers/i2c/omap24xx_i2c.h
index 92a3416..1f38c23 100644
--- a/drivers/i2c/omap24xx_i2c.h
+++ b/drivers/i2c/omap24xx_i2c.h
@@ -20,8 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-#ifndef _OMAP24XX_I2C_H_
-#define _OMAP24XX_I2C_H_
+#ifndef _OMAP2PLUS_I2C_H_
+#define _OMAP2PLUS_I2C_H_
/* I2C masks */
@@ -85,6 +85,10 @@
#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */
#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */
+/* I2C System Status Register (I2C_SYSS): */
+
+#define I2C_SYSS_RDONE (1 << 0) /* Internel reset monitoring */
+
#define I2C_SCLL_SCLL 0
#define I2C_SCLL_SCLL_M 0xFF
#define I2C_SCLL_HSSCLL 8
diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c
index 9506cca..15d41e5 100644
--- a/drivers/mmc/omap3_mmc.c
+++ b/drivers/mmc/omap3_mmc.c
@@ -33,7 +33,7 @@
#include "omap3_mmc.h"
-const unsigned short mmc_transspeed_val[15][4] = {
+static const unsigned short mmc_transspeed_val[15][4] = {
{CLKD(10, 1), CLKD(10, 10), CLKD(10, 100), CLKD(10, 1000)},
{CLKD(12, 1), CLKD(12, 10), CLKD(12, 100), CLKD(12, 1000)},
{CLKD(13, 1), CLKD(13, 10), CLKD(13, 100), CLKD(13, 1000)},
@@ -51,7 +51,7 @@ const unsigned short mmc_transspeed_val[15][4] = {
{CLKD(80, 1), CLKD(80, 10), CLKD(80, 100), CLKD(80, 1000)}
};
-mmc_card_data cur_card_data;
+static mmc_card_data cur_card_data;
static block_dev_desc_t mmc_blk_dev;
static hsmmc_t *mmc_base = (hsmmc_t *)OMAP_HSMMC1_BASE;
@@ -80,7 +80,7 @@ block_dev_desc_t *mmc_get_dev(int dev)
return (block_dev_desc_t *) &mmc_blk_dev;
}
-unsigned char mmc_board_init(void)
+static unsigned char mmc_board_init(void)
{
#if defined(CONFIG_TWL4030_POWER)
twl4030_power_mmc_init();
@@ -114,7 +114,7 @@ unsigned char mmc_board_init(void)
return 1;
}
-void mmc_init_stream(void)
+static void mmc_init_stream(void)
{
writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con);
@@ -129,7 +129,7 @@ void mmc_init_stream(void)
writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
}
-unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
+static unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
{
unsigned int val;
@@ -158,7 +158,7 @@ unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
return 1;
}
-unsigned char mmc_init_setup(void)
+static unsigned char mmc_init_setup(void)
{
unsigned int reg_val;
@@ -192,7 +192,7 @@ unsigned char mmc_init_setup(void)
return 1;
}
-unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
+static unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
unsigned int *response)
{
unsigned int mmc_stat;
@@ -228,7 +228,7 @@ unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
return 1;
}
-unsigned char mmc_read_data(unsigned int *output_buf)
+static unsigned char mmc_read_data(unsigned int *output_buf)
{
unsigned int mmc_stat;
unsigned int read_count = 0;
@@ -269,7 +269,7 @@ unsigned char mmc_read_data(unsigned int *output_buf)
return 1;
}
-unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
+static unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
{
unsigned char err;
unsigned int argument = 0;
@@ -380,7 +380,7 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
return 1;
}
-unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data,
+static unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data,
mmc_csd_reg_t *cur_csd)
{
mmc_extended_csd_reg_t ext_csd;
@@ -434,45 +434,48 @@ unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data,
return 1;
}
-unsigned char omap_mmc_read_sect(unsigned int start_sec, unsigned int num_bytes,
- mmc_card_data *mmc_c,
- unsigned long *output_buf)
+static unsigned long mmc_bread(int dev_num, unsigned long blknr,
+ lbaint_t blkcnt, void *dst)
{
unsigned char err;
unsigned int argument;
unsigned int resp[4];
- unsigned int num_sec_val =
- (num_bytes + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE;
+ unsigned int *output_buf = dst;
unsigned int sec_inc_val;
+ lbaint_t i;
- if (num_sec_val == 0)
- return 1;
+ if (blkcnt == 0)
+ return 0;
- if (mmc_c->mode == SECTOR_MODE) {
- argument = start_sec;
+ if (cur_card_data.mode == SECTOR_MODE) {
+ argument = blknr;
sec_inc_val = 1;
} else {
- argument = start_sec * MMCSD_SECTOR_SIZE;
+ argument = blknr * MMCSD_SECTOR_SIZE;
sec_inc_val = MMCSD_SECTOR_SIZE;
}
- while (num_sec_val) {
+ for (i = 0; i < blkcnt; i++) {
err = mmc_send_cmd(MMC_CMD17, argument, resp);
- if (err != 1)
- return err;
+ if (err != 1) {
+ printf("mmc: CMD17 failed, status = %08x\n", err);
+ break;
+ }
- err = mmc_read_data((unsigned int *) output_buf);
- if (err != 1)
- return err;
+ err = mmc_read_data(output_buf);
+ if (err != 1) {
+ printf("mmc: read failed, status = %08x\n", err);
+ break;
+ }
output_buf += (MMCSD_SECTOR_SIZE / 4);
argument += sec_inc_val;
- num_sec_val--;
}
- return 1;
+
+ return i;
}
-unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
+static unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
{
unsigned char ret_val;
unsigned int argument;
@@ -541,13 +544,6 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
return 1;
}
-unsigned long mmc_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt,
- void *dst)
-{
- omap_mmc_read_sect(blknr, (blkcnt * MMCSD_SECTOR_SIZE), &cur_card_data,
- (unsigned long *) dst);
- return 1;
-}
int mmc_legacy_init(int dev)
{
diff --git a/drivers/mmc/omap3_mmc.h b/drivers/mmc/omap3_mmc.h
index cbb3dc3..e4d263c 100644
--- a/drivers/mmc/omap3_mmc.h
+++ b/drivers/mmc/omap3_mmc.h
@@ -230,13 +230,4 @@ typedef union {
mmc_csd_reg_t Card_CSD;
} mmc_resp_t;
-extern mmc_card_data mmc_dev;
-
-unsigned char mmc_lowlevel_init(void);
-unsigned char mmc_send_command(unsigned int cmd, unsigned int arg,
- unsigned int *response);
-unsigned char mmc_setup_clock(unsigned int iclk, unsigned short clkd);
-unsigned char mmc_set_opendrain(unsigned char state);
-unsigned char mmc_read_data(unsigned int *output_buf);
-
#endif /* MMC_H */
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 3267c5d..44ebb9d 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1096,8 +1096,30 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
return rcode;
}
-/*-----------------------------------------------------------------------
- */
+#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
+static int sector_erased(flash_info_t *info, int i)
+{
+ int k;
+ int size;
+ volatile unsigned long *flash;
+
+ /*
+ * Check if whole sector is erased
+ */
+ size = flash_sector_size(info, i);
+ flash = (volatile unsigned long *) info->start[i];
+ /* divide by 4 for longword access */
+ size = size >> 2;
+
+ for (k = 0; k < size; k++) {
+ if (*flash++ != 0xffffffff)
+ return 0; /* not erased */
+ }
+
+ return 1; /* erased */
+}
+#endif /* CONFIG_SYS_FLASH_EMPTY_INFO */
+
void flash_print_info (flash_info_t * info)
{
int i;
@@ -1142,8 +1164,10 @@ void flash_print_info (flash_info_t * info)
printf ("Unknown (%d)", info->vendor);
break;
}
- printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
- info->manufacturer_id, info->device_id);
+ printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x",
+ info->manufacturer_id);
+ printf (info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
+ info->device_id);
if (info->device_id == 0x7E) {
printf("%04X", info->device_id2);
}
@@ -1159,32 +1183,15 @@ void flash_print_info (flash_info_t * info)
puts ("\n Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
+ if (ctrlc())
+ break;
if ((i % 5) == 0)
- printf ("\n");
+ putc('\n');
#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
- int k;
- int size;
- int erased;
- volatile unsigned long *flash;
-
- /*
- * Check if whole sector is erased
- */
- size = flash_sector_size(info, i);
- erased = 1;
- flash = (volatile unsigned long *) info->start[i];
- size = size >> 2; /* divide by 4 for longword access */
- for (k = 0; k < size; k++) {
- if (*flash++ != 0xffffffff) {
- erased = 0;
- break;
- }
- }
-
/* print empty and read-only info */
printf (" %08lX %c %s ",
info->start[i],
- erased ? 'E' : ' ',
+ sector_erased(info, i) ? 'E' : ' ',
info->protect[i] ? "RO" : " ");
#else /* ! CONFIG_SYS_FLASH_EMPTY_INFO */
printf (" %08lX %s ",
@@ -1348,15 +1355,32 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
case CFI_CMDSET_INTEL_PROG_REGIONS:
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
- flash_write_cmd (info, sector, 0,
- FLASH_CMD_CLEAR_STATUS);
- flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
- if (prot)
- flash_write_cmd (info, sector, 0,
- FLASH_CMD_PROTECT_SET);
- else
+ /*
+ * see errata called
+ * "Numonyx Axcell P33/P30 Specification Update" :)
+ */
+ flash_write_cmd (info, sector, 0, FLASH_CMD_READ_ID);
+ if (!flash_isequal (info, sector, FLASH_OFFSET_PROTECT,
+ prot)) {
+ /*
+ * cmd must come before FLASH_CMD_PROTECT + 20us
+ * Disable interrupts which might cause a timeout here.
+ */
+ int flag = disable_interrupts ();
+ unsigned short cmd;
+
+ if (prot)
+ cmd = FLASH_CMD_PROTECT_SET;
+ else
+ cmd = FLASH_CMD_PROTECT_CLEAR;
+
flash_write_cmd (info, sector, 0,
- FLASH_CMD_PROTECT_CLEAR);
+ FLASH_CMD_PROTECT);
+ flash_write_cmd (info, sector, 0, cmd);
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts ();
+ }
break;
case CFI_CMDSET_AMD_EXTENDED:
case CFI_CMDSET_AMD_STANDARD:
@@ -1477,8 +1501,9 @@ static void cmdset_intel_read_jedec_ids(flash_info_t *info)
udelay(1000); /* some flash are slow to respond */
info->manufacturer_id = flash_read_uchar (info,
FLASH_OFFSET_MANUFACTURER_ID);
- info->device_id = flash_read_uchar (info,
- FLASH_OFFSET_DEVICE_ID);
+ info->device_id = (info->chipwidth == FLASH_CFI_16BIT) ?
+ flash_read_word (info, FLASH_OFFSET_DEVICE_ID) :
+ flash_read_uchar (info, FLASH_OFFSET_DEVICE_ID);
flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
}
@@ -1993,7 +2018,7 @@ unsigned long flash_init (void)
#ifdef CONFIG_SYS_FLASH_PROTECTION
/* read environment from EEPROM */
char s[64];
- getenv_r ("unlock", s, sizeof(s));
+ getenv_f("unlock", s, sizeof(s));
#endif
#define BANK_BASE(i) (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index 144b851..d9487ad 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -305,9 +305,9 @@ static void mal_err (struct eth_device *dev, unsigned long isr,
static void emac_err (struct eth_device *dev, unsigned long isr);
extern int phy_setup_aneg (char *devname, unsigned char addr);
-extern int emac4xx_miiphy_read (char *devname, unsigned char addr,
+extern int emac4xx_miiphy_read (const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value);
-extern int emac4xx_miiphy_write (char *devname, unsigned char addr,
+extern int emac4xx_miiphy_write (const char *devname, unsigned char addr,
unsigned char reg, unsigned short value);
int board_emac_count(void);
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 5c0c274..d45aab1 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -426,7 +426,7 @@ static int tse_mdio_write(struct altera_tse_priv *priv, unsigned int regnum,
/* MDIO access to phy */
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
-static int altera_tse_miiphy_write(char *devname, unsigned char addr,
+static int altera_tse_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
struct eth_device *dev;
@@ -439,7 +439,7 @@ static int altera_tse_miiphy_write(char *devname, unsigned char addr,
return 0;
}
-static int altera_tse_miiphy_read(char *devname, unsigned char addr,
+static int altera_tse_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
struct eth_device *dev;
diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c
index 245da12..d82459b 100644
--- a/drivers/net/at91_emac.c
+++ b/drivers/net/at91_emac.c
@@ -162,7 +162,7 @@ int at91emac_write(at91_emac_t *at91mac, unsigned char addr,
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-at91_emac_t *get_emacbase_by_name(char *devname)
+at91_emac_t *get_emacbase_by_name(const char *devname)
{
struct eth_device *netdev;
@@ -170,7 +170,7 @@ at91_emac_t *get_emacbase_by_name(char *devname)
return (at91_emac_t *) netdev->iobase;
}
-int at91emac_mii_read(char *devname, unsigned char addr,
+int at91emac_mii_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
at91_emac_t *emac;
@@ -181,7 +181,7 @@ int at91emac_mii_read(char *devname, unsigned char addr,
}
-int at91emac_mii_write(char *devname, unsigned char addr,
+int at91emac_mii_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
at91_emac_t *emac;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index e691bdf..36d4046 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -71,7 +71,7 @@ static int bfin_miiphy_wait(void)
return 0;
}
-static int bfin_miiphy_read(char *devname, uchar addr, uchar reg, ushort *val)
+static int bfin_miiphy_read(const char *devname, uchar addr, uchar reg, ushort *val)
{
if (bfin_miiphy_wait())
return 1;
@@ -82,7 +82,7 @@ static int bfin_miiphy_read(char *devname, uchar addr, uchar reg, ushort *val)
return 0;
}
-static int bfin_miiphy_write(char *devname, uchar addr, uchar reg, ushort val)
+static int bfin_miiphy_write(const char *devname, uchar addr, uchar reg, ushort val)
{
if (bfin_miiphy_wait())
return 1;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 02bbb8c..41a9910 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -252,12 +252,12 @@ static int gen_auto_negotiate(int phy_addr)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-static int davinci_mii_phy_read(char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
+static int davinci_mii_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value)
{
return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1);
}
-static int davinci_mii_phy_write(char *devname, unsigned char addr, unsigned char reg, unsigned short value)
+static int davinci_mii_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value)
{
return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1);
}
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index d0d9827..2f923f2 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -451,7 +451,7 @@ static int configure_phy(struct eth_device *dev)
}
#if defined(CONFIG_MII)
-static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
+static int dw_mii_read(const char *devname, u8 addr, u8 reg, u16 *val)
{
struct eth_device *dev;
@@ -462,7 +462,7 @@ static int dw_mii_read(char *devname, u8 addr, u8 reg, u16 *val)
return 0;
}
-static int dw_mii_write(char *devname, u8 addr, u8 reg, u16 val)
+static int dw_mii_write(const char *devname, u8 addr, u8 reg, u16 val)
{
struct eth_device *dev;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 9c06b25..22e14e3 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -321,7 +321,8 @@ static int set_phyreg (struct eth_device *dev, unsigned char addr,
/* Check if given phyaddr is valid, i.e. there is a PHY connected.
* Do this by checking model value field from ID2 register.
*/
-static struct eth_device* verify_phyaddr (char *devname, unsigned char addr)
+static struct eth_device* verify_phyaddr (const char *devname,
+ unsigned char addr)
{
struct eth_device *dev;
unsigned short value;
@@ -350,7 +351,7 @@ static struct eth_device* verify_phyaddr (char *devname, unsigned char addr)
return dev;
}
-static int eepro100_miiphy_read (char *devname, unsigned char addr,
+static int eepro100_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
struct eth_device *dev;
@@ -367,7 +368,7 @@ static int eepro100_miiphy_read (char *devname, unsigned char addr,
return 0;
}
-static int eepro100_miiphy_write (char *devname, unsigned char addr,
+static int eepro100_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
struct eth_device *dev;
diff --git a/drivers/net/ep93xx_eth.c b/drivers/net/ep93xx_eth.c
index 4e39948..c09384c 100644
--- a/drivers/net/ep93xx_eth.c
+++ b/drivers/net/ep93xx_eth.c
@@ -44,9 +44,9 @@
#define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs)
/* ep93xx_miiphy ops forward declarations */
-static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
+static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short * const value);
-static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
+static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short const value);
#if defined(EP93XX_MAC_DEBUG)
@@ -555,7 +555,7 @@ eth_init_done:
/**
* Read a 16-bit value from an MII register.
*/
-static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
+static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short * const value)
{
struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
@@ -607,7 +607,7 @@ static int ep93xx_miiphy_read(char * const dev, unsigned char const addr,
/**
* Write a 16-bit value to an MII register.
*/
-static int ep93xx_miiphy_write(char * const dev, unsigned char const addr,
+static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
unsigned char const reg, unsigned short const value)
{
struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 57f89a3..2d4ffed 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -62,7 +62,7 @@ struct fec_priv gfec = {
/*
* MII-interface related functions
*/
-static int fec_miiphy_read(char *dev, uint8_t phyAddr, uint8_t regAddr,
+static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
uint16_t *retVal)
{
struct eth_device *edev = eth_get_dev_by_name(dev);
@@ -119,7 +119,7 @@ static void fec_mii_setspeed(struct fec_priv *fec)
debug("fec_init: mii_speed %#lx\n",
fec->eth->mii_speed);
}
-static int fec_miiphy_write(char *dev, uint8_t phyAddr, uint8_t regAddr,
+static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
uint16_t data)
{
struct eth_device *edev = eth_get_dev_by_name(dev);
@@ -743,7 +743,7 @@ static int fec_probe(bd_t *bd)
writel(0x05ee0024, &fec->eth->r_cntrl); /* FIXME 0x05ee0004 */
fec_mii_setspeed(fec);
- sprintf(edev->name, "FEC_MXC");
+ sprintf(edev->name, "FEC");
miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 6a58a37..acb8d20 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -167,7 +167,7 @@ static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
#if defined(CONFIG_CMD_MII)
-int macb_miiphy_read(char *devname, u8 phy_adr, u8 reg, u16 *value)
+int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct macb_device *macb = to_macb(dev);
@@ -180,7 +180,7 @@ int macb_miiphy_read(char *devname, u8 phy_adr, u8 reg, u16 *value)
return 0;
}
-int macb_miiphy_write(char *devname, u8 phy_adr, u8 reg, u16 value)
+int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct macb_device *macb = to_macb(dev);
diff --git a/drivers/net/mcfmii.c b/drivers/net/mcfmii.c
index 060bdd7..401182d 100644
--- a/drivers/net/mcfmii.c
+++ b/drivers/net/mcfmii.c
@@ -293,7 +293,7 @@ void __mii_init(void)
* Otherwise they hang in mii_send() !!! Sorry!
*/
-int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg,
+int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
unsigned short *value)
{
short rdreg; /* register working value */
@@ -312,7 +312,7 @@ int mcffec_miiphy_read(char *devname, unsigned char addr, unsigned char reg,
return 0;
}
-int mcffec_miiphy_write(char *devname, unsigned char addr, unsigned char reg,
+int mcffec_miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
unsigned short value)
{
short rdreg; /* register working value */
diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c
index c580c82..f56d940 100644
--- a/drivers/net/mpc512x_fec.c
+++ b/drivers/net/mpc512x_fec.c
@@ -25,8 +25,8 @@ DECLARE_GLOBAL_DATA_PTR;
#error "CONFIG_MII has to be defined!"
#endif
-int fec512x_miiphy_read(char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
-int fec512x_miiphy_write(char *devname, u8 phyAddr, u8 regAddr, u16 data);
+int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 * retVal);
+int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data);
int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
static uchar rx_buff[FEC_BUFFER_SIZE];
@@ -637,7 +637,7 @@ int mpc512x_fec_initialize (bd_t * bis)
dev->send = mpc512x_fec_send;
dev->recv = mpc512x_fec_recv;
- sprintf (dev->name, "FEC ETHERNET");
+ sprintf (dev->name, "FEC");
eth_register (dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
@@ -672,7 +672,7 @@ int mpc512x_fec_initialize (bd_t * bis)
/* MII-interface related functions */
/********************************************************************/
-int fec512x_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
+int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 *retVal)
{
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
volatile fec512x_t *eth = &im->fec;
@@ -719,7 +719,7 @@ int fec512x_miiphy_read (char *devname, u8 phyAddr, u8 regAddr, u16 * retVal)
}
/********************************************************************/
-int fec512x_miiphy_write (char *devname, u8 phyAddr, u8 regAddr, u16 data)
+int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data)
{
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
volatile fec512x_t *eth = &im->fec;
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index 1681e26..c88e596 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -35,8 +35,8 @@ typedef struct {
uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */
} NBUF;
-int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal);
-int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
+int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 *retVal);
+int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis);
@@ -913,7 +913,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
dev->send = mpc5xxx_fec_send;
dev->recv = mpc5xxx_fec_recv;
- sprintf(dev->name, "FEC ETHERNET");
+ sprintf(dev->name, "FEC");
eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
@@ -941,7 +941,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
/* MII-interface related functions */
/********************************************************************/
-int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
+int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
{
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */
@@ -983,7 +983,7 @@ int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * re
}
/********************************************************************/
-int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
+int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
{
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index cad4023..c701f43 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -54,7 +54,7 @@ DECLARE_GLOBAL_DATA_PTR;
*
* Returns 16bit phy register value, or 0xffff on error
*/
-static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
+static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
@@ -131,7 +131,7 @@ static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
* Returns 0 if write succeed, -EINVAL on bad parameters
* -ETIME on timeout
*/
-static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
{
struct eth_device *dev = eth_get_dev_by_name(devname);
struct mvgbe_device *dmvgbe = to_mvgbe(dev);
diff --git a/drivers/net/ns7520_eth.c b/drivers/net/ns7520_eth.c
index c28726e..bfa651b 100644
--- a/drivers/net/ns7520_eth.c
+++ b/drivers/net/ns7520_eth.c
@@ -761,7 +761,7 @@ enum mii_status {
/**
* Read a 16-bit value from an MII register.
*/
-extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
+extern int ns7520_miiphy_read(const char *devname, unsigned char const addr,
unsigned char const reg, unsigned short *const value)
{
int ret = MII_STATUS_FAILURE;
@@ -807,7 +807,7 @@ extern int ns7520_miiphy_read(char *devname, unsigned char const addr,
/**
* Write a 16-bit value to an MII register.
*/
-extern int ns7520_miiphy_write(char *devname, unsigned char const addr,
+extern int ns7520_miiphy_write(const char *devname, unsigned char const addr,
unsigned char const reg, unsigned short const value)
{
int ret = MII_STATUS_FAILURE;
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index 2768c75..1045cf1 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -143,7 +143,7 @@ void bb_miiphy_init(void)
}
}
-static inline struct bb_miiphy_bus *bb_miiphy_getbus(char *devname)
+static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
{
#ifdef CONFIG_BITBANGMII_MULTI
int i;
@@ -246,7 +246,7 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* Returns:
* 0 on success
*/
-int bb_miiphy_read(char *devname, unsigned char addr,
+int bb_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
short rdreg; /* register working value */
@@ -327,7 +327,7 @@ int bb_miiphy_read(char *devname, unsigned char addr,
* Returns:
* 0 on success
*/
-int bb_miiphy_write (char *devname, unsigned char addr,
+int bb_miiphy_write (const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
struct bb_miiphy_bus *bus;
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 54c4a70..9b5dd92 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -60,9 +60,9 @@ static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
static void adjust_link(struct eth_device *dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
&& !defined(BITBANGMII)
-static int tsec_miiphy_write(char *devname, unsigned char addr,
+static int tsec_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value);
-static int tsec_miiphy_read(char *devname, unsigned char addr,
+static int tsec_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value);
#endif
#ifdef CONFIG_MCAST_TFTP
@@ -1919,7 +1919,7 @@ static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
* Returns:
* 0 on success
*/
-static int tsec_miiphy_read(char *devname, unsigned char addr,
+static int tsec_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
unsigned short ret;
@@ -1942,7 +1942,7 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
* Returns:
* 0 on success
*/
-static int tsec_miiphy_write(char *devname, unsigned char addr,
+static int tsec_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
struct tsec_private *priv = privlist[0];
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dd06514..db53173 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libpower.a
COBJS-$(CONFIG_TWL4030_POWER) += twl4030.o
+COBJS-$(CONFIG_TWL6030_POWER) += twl6030.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c
new file mode 100644
index 0000000..cf1da6b
--- /dev/null
+++ b/drivers/power/twl6030.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <config.h>
+#ifdef CONFIG_TWL6030_POWER
+
+#include <twl6030.h>
+
+/* Functions to read and write from TWL6030 */
+static inline int twl6030_i2c_write_u8(u8 chip_no, u8 val, u8 reg)
+{
+ return i2c_write(chip_no, reg, 1, &val, 1);
+}
+
+static inline int twl6030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg)
+{
+ return i2c_read(chip_no, reg, 1, val, 1);
+}
+
+void twl6030_start_usb_charging(void)
+{
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VICHRG_1500,
+ CHARGERUSB_VICHRG);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CIN_LIMIT_NONE,
+ CHARGERUSB_CINLIMIT);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MBAT_TEMP,
+ CONTROLLER_INT_MASK);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, MASK_MCHARGERUSB_THMREG,
+ CHARGERUSB_INT_MASK);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_VOREG_4P0,
+ CHARGERUSB_VOREG);
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL2_VITERM_100,
+ CHARGERUSB_CTRL2);
+ /* Enable USB charging */
+ twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1_EN_CHARGER,
+ CONTROLLER_CTRL1);
+ return;
+}
+
+void twl6030_init_battery_charging(void)
+{
+ twl6030_start_usb_charging();
+ return;
+}
+
+void twl6030_usb_device_settings()
+{
+ u8 data = 0;
+
+ /* Select APP Group and set state to ON */
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VUSB_CFG_STATE);
+
+ twl6030_i2c_read_u8(TWL6030_CHIP_PM, &data, MISC2);
+ data |= 0x10;
+
+ /* Select the input supply for VBUS regulator */
+ twl6030_i2c_write_u8(TWL6030_CHIP_PM, data, MISC2);
+}
+#endif
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index ccbf27d..e10c0f3 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -603,7 +603,7 @@ static void phy_change(struct eth_device *dev)
* Returns:
* The index where the device is located, -1 on error
*/
-static int uec_miiphy_find_dev_by_name(char *devname)
+static int uec_miiphy_find_dev_by_name(const char *devname)
{
int i;
@@ -628,7 +628,7 @@ static int uec_miiphy_find_dev_by_name(char *devname)
* Returns:
* 0 on success
*/
-static int uec_miiphy_read(char *devname, unsigned char addr,
+static int uec_miiphy_read(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
int devindex = 0;
@@ -650,7 +650,7 @@ static int uec_miiphy_read(char *devname, unsigned char addr,
* Returns:
* 0 on success
*/
-static int uec_miiphy_write(char *devname, unsigned char addr,
+static int uec_miiphy_write(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
int devindex = 0;
@@ -1367,7 +1367,7 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
uec->uec_info = uec_info;
uec->dev = dev;
- sprintf(dev->name, "FSL UEC%d", uec_info->uf_info.ucc_num);
+ sprintf(dev->name, "UEC%d", uec_info->uf_info.ucc_num);
dev->iobase = 0;
dev->priv = (void *)uec;
dev->init = uec_init;
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c
index 3baffe4..2d3a896 100644
--- a/drivers/qe/uec_phy.c
+++ b/drivers/qe/uec_phy.c
@@ -71,8 +71,8 @@
* {name, speed, duplex},
*
* #define CONFIG_SYS_FIXED_PHY_PORTS \
- * CONFIG_SYS_FIXED_PHY_PORT("FSL UEC0",SPEED_100,DUPLEX_FULL) \
- * CONFIG_SYS_FIXED_PHY_PORT("FSL UEC2",SPEED_100,DUPLEX_HALF)
+ * CONFIG_SYS_FIXED_PHY_PORT("UEC0",SPEED_100,DUPLEX_FULL) \
+ * CONFIG_SYS_FIXED_PHY_PORT("UEC2",SPEED_100,DUPLEX_HALF)
*/
#ifndef CONFIG_FIXED_PHY
@@ -102,7 +102,7 @@ static const struct fixed_phy_port fixed_phy_port[] = {
* Example board header file to define bitbang ethernet ports:
*
* #define CONFIG_SYS_BITBANG_PHY_PORT(name) name,
- * #define CONFIG_SYS_BITBANG_PHY_PORTS CONFIG_SYS_BITBANG_PHY_PORT("FSL UEC0")
+ * #define CONFIG_SYS_BITBANG_PHY_PORTS CONFIG_SYS_BITBANG_PHY_PORT("UEC0")
*/
#ifndef CONFIG_SYS_BITBANG_PHY_PORTS
#define CONFIG_SYS_BITBANG_PHY_PORTS /* default is an empty array */
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 397f5fe..7d23e06 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -31,6 +31,7 @@ COBJS-$(CONFIG_USB_BLACKFIN) += blackfin_usb.o
COBJS-$(CONFIG_USB_DAVINCI) += davinci.o
COBJS-$(CONFIG_USB_OMAP3) += omap3.o
COBJS-$(CONFIG_USB_DA8XX) += da8xx.o
+COBJS-$(CONFIG_USB_AM35X) += am35x.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
new file mode 100644
index 0000000..1706c13
--- /dev/null
+++ b/drivers/usb/musb/am35x.c
@@ -0,0 +1,150 @@
+/*
+ * am35x.c - TI's AM35x platform specific usb wrapper functions.
+ *
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
+ *
+ * Based on drivers/usb/musb/da8xx.c
+ *
+ * Copyright (c) 2010 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <common.h>
+
+#include "am35x.h"
+
+/* MUSB platform configuration */
+struct musb_config musb_cfg = {
+ .regs = (struct musb_regs *)AM35X_USB_OTG_CORE_BASE,
+ .timeout = AM35X_USB_OTG_TIMEOUT,
+ .musb_speed = 0,
+};
+
+/*
+ * Enable the USB phy
+ */
+static u8 phy_on(void)
+{
+ u32 devconf2;
+ u32 timeout;
+
+ devconf2 = readl(&am35x_scm_general_regs->devconf2);
+
+ devconf2 &= ~(DEVCONF2_RESET | DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN |
+ DEVCONF2_OTGMODE | DEVCONF2_REFFREQ |
+ DEVCONF2_PHY_GPIOMODE);
+ devconf2 |= DEVCONF2_SESENDEN | DEVCONF2_VBDTCTEN | DEVCONF2_PHY_PLLON |
+ DEVCONF2_REFFREQ_13MHZ | DEVCONF2_DATPOL;
+
+ writel(devconf2, &am35x_scm_general_regs->devconf2);
+
+ /* wait until the USB phy is turned on */
+ timeout = musb_cfg.timeout;
+ while (timeout--)
+ if (readl(&am35x_scm_general_regs->devconf2) & DEVCONF2_PHYCKGD)
+ return 1;
+
+ /* USB phy was not turned on */
+ return 0;
+}
+
+/*
+ * Disable the USB phy
+ */
+static void phy_off(void)
+{
+ u32 devconf2;
+
+ /*
+ * Power down the on-chip PHY.
+ */
+ devconf2 = readl(&am35x_scm_general_regs->devconf2);
+
+ devconf2 &= ~DEVCONF2_PHY_PLLON;
+ devconf2 |= DEVCONF2_PHYPWRDN | DEVCONF2_OTGPWRDN;
+ writel(devconf2, &am35x_scm_general_regs->devconf2);
+}
+
+/*
+ * This function performs platform specific initialization for usb0.
+ */
+int musb_platform_init(void)
+{
+ u32 revision;
+ u32 sw_reset;
+
+ /* global usb reset */
+ sw_reset = readl(&am35x_scm_general_regs->ip_sw_reset);
+ sw_reset |= (1 << 0);
+ writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
+ sw_reset &= ~(1 << 0);
+ writel(sw_reset, &am35x_scm_general_regs->ip_sw_reset);
+
+ /* reset the controller */
+ writel(0x1, &am35x_usb_regs->control);
+ udelay(5000);
+
+ /* start the on-chip usb phy and its pll */
+ if (phy_on() == 0)
+ return -1;
+
+ /* Returns zero if e.g. not clocked */
+ revision = readl(&am35x_usb_regs->revision);
+ if (revision == 0)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * This function performs platform specific deinitialization for usb0.
+ */
+void musb_platform_deinit(void)
+{
+ /* Turn off the phy */
+ phy_off();
+}
+
+/*
+ * This function reads data from endpoint fifo for AM35x
+ * which supports only 32bit read operation.
+ *
+ * ep - endpoint number
+ * length - number of bytes to read from FIFO
+ * fifo_data - pointer to data buffer into which data is read
+ */
+__attribute__((weak))
+void read_fifo(u8 ep, u32 length, void *fifo_data)
+{
+ u8 *data = (u8 *)fifo_data;
+ u32 val;
+ int i;
+
+ /* select the endpoint index */
+ writeb(ep, &musbr->index);
+
+ if (length > 4) {
+ for (i = 0; i < (length >> 2); i++) {
+ val = readl(&musbr->fifox[ep]);
+ memcpy(data, &val, 4);
+ data += 4;
+ }
+ length %= 4;
+ }
+ if (length > 0) {
+ val = readl(&musbr->fifox[ep]);
+ memcpy(data, &val, length);
+ }
+}
diff --git a/drivers/usb/musb/am35x.h b/drivers/usb/musb/am35x.h
new file mode 100644
index 0000000..756c3ae
--- /dev/null
+++ b/drivers/usb/musb/am35x.h
@@ -0,0 +1,94 @@
+/*
+ * am35x.h - TI's AM35x platform specific usb wrapper definitions.
+ *
+ * Author: Ajay Kumar Gupta <ajay.gupta@ti.com>
+ *
+ * Based on drivers/usb/musb/da8xx.h
+ *
+ * Copyright (c) 2010 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __AM35X_USB_H__
+#define __AM35X_USB_H__
+
+#include <asm/arch/am35x_def.h>
+#include "musb_core.h"
+
+/* Base address of musb wrapper */
+#define AM35X_USB_OTG_BASE 0x5C040000
+
+/* Base address of musb core */
+#define AM35X_USB_OTG_CORE_BASE (AM35X_USB_OTG_BASE + 0x400)
+
+/* Timeout for AM35x usb module */
+#define AM35X_USB_OTG_TIMEOUT 0x3FFFFFF
+
+/*
+ * AM35x platform USB wrapper register overlay.
+ */
+struct am35x_usb_regs {
+ u32 revision;
+ u32 control;
+ u32 status;
+ u32 emulation;
+ u32 reserved0[1];
+ u32 autoreq;
+ u32 srpfixtime;
+ u32 ep_intsrc;
+ u32 ep_intsrcset;
+ u32 ep_intsrcclr;
+ u32 ep_intmsk;
+ u32 ep_intmskset;
+ u32 ep_intmskclr;
+ u32 ep_intsrcmsked;
+ u32 reserved1[1];
+ u32 core_intsrc;
+ u32 core_intsrcset;
+ u32 core_intsrcclr;
+ u32 core_intmsk;
+ u32 core_intmskset;
+ u32 core_intmskclr;
+ u32 core_intsrcmsked;
+ u32 reserved2[1];
+ u32 eoi;
+ u32 mop_sop_en;
+ u32 reserved3[2];
+ u32 txmode;
+ u32 rxmode;
+ u32 epcount_mode;
+};
+
+#define am35x_usb_regs ((struct am35x_usb_regs *)AM35X_USB_OTG_BASE)
+
+/* USB 2.0 PHY Control */
+#define DEVCONF2_PHY_GPIOMODE (1 << 23)
+#define DEVCONF2_OTGMODE (3 << 14)
+#define DEVCONF2_SESENDEN (1 << 13) /* Vsess_end comparator */
+#define DEVCONF2_VBDTCTEN (1 << 12) /* Vbus comparator */
+#define DEVCONF2_REFFREQ_24MHZ (2 << 8)
+#define DEVCONF2_REFFREQ_26MHZ (7 << 8)
+#define DEVCONF2_REFFREQ_13MHZ (6 << 8)
+#define DEVCONF2_REFFREQ (0xf << 8)
+#define DEVCONF2_PHYCKGD (1 << 7)
+#define DEVCONF2_VBUSSENSE (1 << 6)
+#define DEVCONF2_PHY_PLLON (1 << 5) /* override PLL suspend */
+#define DEVCONF2_RESET (1 << 4)
+#define DEVCONF2_PHYPWRDN (1 << 3)
+#define DEVCONF2_OTGPWRDN (1 << 2)
+#define DEVCONF2_DATPOL (1 << 1)
+
+#endif /* __AM35X_USB_H__ */
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index dc740cf..6fe2c39 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -142,6 +142,11 @@ void write_fifo(u8 ep, u32 length, void *fifo_data)
}
/*
+ * AM35x supports only 32bit read operations so
+ * use seperate read_fifo() function for it.
+ */
+#ifndef CONFIG_USB_AM35X
+/*
* This function reads data from endpoint fifo
*
* ep - endpoint number
@@ -160,3 +165,4 @@ void read_fifo(u8 ep, u32 length, void *fifo_data)
while (length--)
*data++ = readb(&musbr->fifox[ep]);
}
+#endif /* CONFIG_USB_AM35X */
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
index fc43cf4..6f6ed61 100644
--- a/drivers/usb/musb/musb_udc.c
+++ b/drivers/usb/musb/musb_udc.c
@@ -57,6 +57,8 @@
#include "musb_core.h"
#if defined(CONFIG_USB_OMAP3)
#include "omap3.h"
+#elif defined(CONFIG_USB_AM35X)
+#include "am35x.h"
#elif defined(CONFIG_USB_DAVINCI)
#include "davinci.h"
#endif
diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c
index a983552..c7876ed 100644
--- a/drivers/usb/musb/omap3.c
+++ b/drivers/usb/musb/omap3.c
@@ -31,6 +31,7 @@
*/
#include <twl4030.h>
+#include <twl6030.h>
#include "omap3.h"
static int platform_needs_initialization = 1;
@@ -65,7 +66,12 @@ static struct omap3_otg_regs *otg;
#define OMAP3_OTG_SYSSTATUS_RESETDONE 0x0001
+/* OMAP4430 has an internal PHY, use it */
+#ifdef CONFIG_OMAP4430
+#define OMAP3_OTG_INTERFSEL_OMAP 0x0000
+#else
#define OMAP3_OTG_INTERFSEL_OMAP 0x0001
+#endif
#define OMAP3_OTG_FORCESTDBY_STANDBY 0x0001
@@ -105,6 +111,11 @@ int musb_platform_init(void)
goto end;
}
#endif
+
+#ifdef CONFIG_TWL6030_POWER
+ twl6030_usb_device_settings();
+#endif
+
otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE;
/* Set OTG to always be on */
@@ -122,6 +133,11 @@ int musb_platform_init(void)
#ifdef CONFIG_OMAP3_EVM
musb_cfg.extvbus = omap3_evm_need_extvbus();
#endif
+
+#ifdef CONFIG_OMAP4430
+ u32 *usbotghs_control = (u32 *)(CTRL_BASE + 0x33C);
+ *usbotghs_control = 0x15;
+#endif
platform_needs_initialization = 0;
}
diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h
index 2886d7e..b2acdf4 100644
--- a/drivers/usb/musb/omap3.h
+++ b/drivers/usb/musb/omap3.h
@@ -31,10 +31,11 @@
#ifndef _MUSB_OMAP3_H_
#define _MUSB_OMAP3_H_
+#include <asm/arch/cpu.h>
#include "musb_core.h"
/* Base address of MUSB registers */
-#define MENTOR_USB0_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+#define MENTOR_USB0_BASE MUSB_BASE
/* Base address of OTG registers */
#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 7d84fc7..4be82e7 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
COBJS-$(CONFIG_VIDEO_MB862xx) += mb862xx.o videomodes.o
+COBJS-$(CONFIG_VIDEO_MB86R0xGDC) += mb86r0xgdc.o videomodes.o
COBJS-$(CONFIG_VIDEO_MX3) += mx3fb.o
COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
COBJS-$(CONFIG_SED156X) += sed156x.o
diff --git a/drivers/video/mb86r0xgdc.c b/drivers/video/mb86r0xgdc.c
new file mode 100644
index 0000000..3bdc1db
--- /dev/null
+++ b/drivers/video/mb86r0xgdc.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2010
+ * Matthias Weisser <weisserm@arcor.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * mb86r0xgdc.c - Graphic interface for Fujitsu MB86R0x integrated graphic
+ * controller.
+ */
+
+#include <common.h>
+
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <video_fb.h>
+#include "videomodes.h"
+
+/*
+ * 4MB (at the end of system RAM)
+ */
+#define VIDEO_MEM_SIZE 0x400000
+
+#define FB_SYNC_CLK_INV (1<<16) /* pixel clock inverted */
+
+/*
+ * Graphic Device
+ */
+static GraphicDevice mb86r0x;
+
+static void dsp_init(struct mb86r0x_gdc_dsp *dsp, char *modestr,
+ u32 *videomem)
+{
+ struct ctfb_res_modes var_mode;
+ u32 dcm1, dcm2, dcm3;
+ u16 htp, hdp, hdb, hsp, vtr, vsp, vdp;
+ u8 hsw, vsw;
+ u32 l2m, l2em, l2oa0, l2da0, l2oa1, l2da1;
+ u16 l2dx, l2dy, l2wx, l2wy, l2ww, l2wh;
+ unsigned long div;
+ int bpp;
+ u32 i;
+
+ bpp = video_get_params(&var_mode, modestr);
+
+ if (bpp == 0) {
+ var_mode.xres = 640;
+ var_mode.yres = 480;
+ var_mode.pixclock = 39721; /* 25MHz */
+ var_mode.left_margin = 48;
+ var_mode.right_margin = 16;
+ var_mode.upper_margin = 33;
+ var_mode.lower_margin = 10;
+ var_mode.hsync_len = 96;
+ var_mode.vsync_len = 2;
+ var_mode.sync = 0;
+ var_mode.vmode = 0;
+ bpp = 15;
+ }
+
+ /* Fill memory with white */
+ for (i = 0; i < var_mode.xres * var_mode.yres / 2; i++)
+ *videomem++ = 0xFFFFFFFF;
+
+ mb86r0x.winSizeX = var_mode.xres;
+ mb86r0x.winSizeY = var_mode.yres;
+
+ /* LCD base clock is ~ 660MHZ. We do calculations in kHz */
+ div = 660000 / (1000000000L / var_mode.pixclock);
+ if (div > 64)
+ div = 64;
+ if (0 == div)
+ div = 1;
+
+ dcm1 = (div - 1) << 8;
+ dcm2 = 0x00000000;
+ if (var_mode.sync & FB_SYNC_CLK_INV)
+ dcm3 = 0x00000100;
+ else
+ dcm3 = 0x00000000;
+
+ htp = var_mode.left_margin + var_mode.xres +
+ var_mode.hsync_len + var_mode.right_margin;
+ hdp = var_mode.xres;
+ hdb = var_mode.xres;
+ hsp = var_mode.xres + var_mode.right_margin;
+ hsw = var_mode.hsync_len;
+
+ vsw = var_mode.vsync_len;
+ vtr = var_mode.upper_margin + var_mode.yres +
+ var_mode.vsync_len + var_mode.lower_margin;
+ vsp = var_mode.yres + var_mode.lower_margin;
+ vdp = var_mode.yres;
+
+ l2m = ((var_mode.yres - 1) << (0)) |
+ (((var_mode.xres * 2) / 64) << (16)) |
+ ((1) << (31));
+
+ l2em = (1 << 0) | (1 << 1);
+
+ l2oa0 = mb86r0x.frameAdrs;
+ l2da0 = mb86r0x.frameAdrs;
+ l2oa1 = mb86r0x.frameAdrs;
+ l2da1 = mb86r0x.frameAdrs;
+ l2dx = 0;
+ l2dy = 0;
+ l2wx = 0;
+ l2wy = 0;
+ l2ww = var_mode.xres;
+ l2wh = var_mode.yres - 1;
+
+ writel(dcm1, &dsp->dcm1);
+ writel(dcm2, &dsp->dcm2);
+ writel(dcm3, &dsp->dcm3);
+
+ writew(htp, &dsp->htp);
+ writew(hdp, &dsp->hdp);
+ writew(hdb, &dsp->hdb);
+ writew(hsp, &dsp->hsp);
+ writeb(hsw, &dsp->hsw);
+
+ writeb(vsw, &dsp->vsw);
+ writew(vtr, &dsp->vtr);
+ writew(vsp, &dsp->vsp);
+ writew(vdp, &dsp->vdp);
+
+ writel(l2m, &dsp->l2m);
+ writel(l2em, &dsp->l2em);
+ writel(l2oa0, &dsp->l2oa0);
+ writel(l2da0, &dsp->l2da0);
+ writel(l2oa1, &dsp->l2oa1);
+ writel(l2da1, &dsp->l2da1);
+ writew(l2dx, &dsp->l2dx);
+ writew(l2dy, &dsp->l2dy);
+ writew(l2wx, &dsp->l2wx);
+ writew(l2wy, &dsp->l2wy);
+ writew(l2ww, &dsp->l2ww);
+ writew(l2wh, &dsp->l2wh);
+
+ writel(dcm1 | (1 << 18) | (1 << 31), &dsp->dcm1);
+}
+
+void *video_hw_init(void)
+{
+ struct mb86r0x_gdc *gdc = (struct mb86r0x_gdc *) MB86R0x_GDC_BASE;
+ GraphicDevice *pGD = &mb86r0x;
+ char *s;
+ u32 *vid;
+
+ memset(pGD, 0, sizeof(GraphicDevice));
+
+ pGD->gdfIndex = GDF_15BIT_555RGB;
+ pGD->gdfBytesPP = 2;
+ pGD->memSize = VIDEO_MEM_SIZE;
+ pGD->frameAdrs = PHYS_SDRAM + PHYS_SDRAM_SIZE - VIDEO_MEM_SIZE;
+
+ vid = (u32 *)pGD->frameAdrs;
+
+ s = getenv("videomode");
+ if (s != NULL)
+ dsp_init(&gdc->dsp0, s, vid);
+
+ s = getenv("videomode1");
+ if (s != NULL)
+ dsp_init(&gdc->dsp1, s, vid);
+
+ return pGD;
+}