*.orig
*.a
*.o
+*.su
*~
*.swp
*.patch
igep0020 ARM ARMV7 (OMAP3xx SoC)
igep0030 ARM ARMV7 (OMAP3xx SoC)
-Dirk Behme <dirk.behme@gmail.com>
-
- omap3_beagle ARM ARMV7 (OMAP3530 SoC)
-
Eric Benard <eric@eukrea.com>
cpuat91 ARM920T
Kshitij Gupta <kshitij@ti.com>
omap1510inn ARM925T
- omap1610inn ARM926EJS
Stefan Herbrechtsmeier <stefan@code.herbrechtsmeier.net>
am3517_crane ARM ARMV7 (AM35x SoC)
-Chandan Nath <chandan.nath@ti.com>
-
- am335x_evm ARM ARMV7 (AM33xx Soc)
-
Kyungmin Park <kyungmin.park@samsung.com>
apollon ARM1136EJS
Tom Rini <trini@ti.com>
+ am335x_evm ARM ARMV7 (AM33xx Soc)
+ omap3_beagle ARM ARMV7 (OMAP3xx SoC)
omap3_evm ARM ARMV7 (OMAP3xx SoC)
Tom Rix <Tom.Rix@windriver.com>
-v VENDOR, --vendor VENDOR Build all boards with vendor VENDOR
-s SOC, --soc SOC Build all boards with soc SOC
-l, --list List all targets to be built
+ -m, --maintainers List all targets and maintainer email
+ -M, --mails List all targets and all affilated emails
-h, --help This help output
Selections by these options are logically ANDed; if the same option
exit ${ret}
}
-SHORT_OPTS="ha:c:v:s:l"
-LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list"
+SHORT_OPTS="ha:c:v:s:lmM"
+LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list,maintainers,mails"
# Option processing based on util-linux-2.13/getopt-parse.bash
SELECTED=''
ONLY_LIST=''
+PRINT_MAINTS=''
+MAINTAINERS_ONLY=''
while true ; do
case "$1" in
-l|--list)
ONLY_LIST='y'
shift ;;
+ -m|--maintainers)
+ ONLY_LIST='y'
+ PRINT_MAINTS='y'
+ MAINTAINERS_ONLY='y'
+ shift ;;
+ -M|--mails)
+ ONLY_LIST='y'
+ PRINT_MAINTS='y'
+ shift ;;
-h|--help)
usage ;;
--)
#-----------------------------------------------------------------------
+get_target_location() {
+ local target=$1
+ local BOARD_NAME=""
+ local CONFIG_NAME=""
+ local board=""
+ local vendor=""
+
+ # Automatic mode
+ local line=`egrep -i "^[[:space:]]*${target}[[:space:]]" boards.cfg`
+
+ if [ -z "${line}" ] ; then echo "" ; return ; fi
+
+ set ${line}
+
+ # add default board name if needed
+ [ $# = 3 ] && set ${line} ${1}
+
+ CONFIG_NAME="${1%_config}"
+
+ [ "${BOARD_NAME}" ] || BOARD_NAME="${1%_config}"
+
+ if [ "$4" = "-" ] ; then
+ board=${BOARD_NAME}
+ else
+ board="$4"
+ fi
+
+ [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5"
+ [ $# -gt 6 ] && [ "$7" != "-" ] && {
+ tmp="${7%:*}"
+ if [ "$tmp" ] ; then
+ CONFIG_NAME="$tmp"
+ fi
+ }
+
+ # Assign board directory to BOARDIR variable
+ if [ -z "${vendor}" ] ; then
+ BOARDDIR=${board}
+ else
+ BOARDDIR=${vendor}/${board}
+ fi
+
+ echo "${CONFIG_NAME}:${BOARDDIR}"
+}
+
+get_target_maintainers() {
+ local name=`echo $1 | cut -d : -f 1`
+
+ if ! grep -qsi "[[:blank:]]${name}[[:blank:]]" MAINTAINERS ; then
+ echo ""
+ return ;
+ fi
+
+ local line=`tac MAINTAINERS | grep -ni "[[:blank:]]${name}[[:blank:]]" | cut -d : -f 1`
+ local mail=`tac MAINTAINERS | tail -n +${line} | \
+ sed -n ":start /.*@.*/ { b mail } ; n ; b start ; :mail /.*@.*/ { p ; n ; b mail } ; q" | \
+ sed "s/^.*<//;s/>.*$//"`
+ echo "$mail"
+}
+
+list_target() {
+ if [ "$PRINT_MAINTS" != 'y' ] ; then
+ echo "$1"
+ return
+ fi
+
+ echo -n "$1:"
+
+ local loc=`get_target_location $1`
+
+ if [ -z "${loc}" ] ; then echo "ERROR" ; return ; fi
+
+ local maintainers_result=`get_target_maintainers ${loc} | tr " " "\n"`
+
+ if [ "$MAINTAINERS_ONLY" != 'y' ] ; then
+
+ local dir=`echo ${loc} | cut -d ":" -f 2`
+ local cfg=`echo ${loc} | cut -d ":" -f 1`
+ local git_result=`git log --format=%aE board/${dir} \
+ include/configs/${cfg}.h | grep "@"`
+ local git_result_recent=`echo ${git_result} | tr " " "\n" | \
+ head -n 3`
+ local git_result_top=`echo ${git_result} | tr " " "\n" | \
+ sort | uniq -c | sort -nr | head -n 3 | \
+ sed "s/^ \+[0-9]\+ \+//"`
+
+ echo -e "$git_result_recent\n$git_result_top\n$maintainers_result" | \
+ sort -u | tr "\n" " " | sed "s/ $//" ;
+ else
+ echo -e "$maintainers_result" | sort -u | tr "\n" " " | \
+ sed "s/ $//" ;
+ fi
+
+ echo ""
+}
+
build_target() {
target=$1
if [ "$ONLY_LIST" == 'y' ] ; then
- echo "$target"
+ list_target ${target}
return
fi
TOTAL_CNT=$((TOTAL_CNT + 1))
- ${CROSS_COMPILE}size ${BUILD_DIR}/u-boot \
- | tee -a ${LOG_DIR}/$target.MAKELOG
+ OBJS=${BUILD_DIR}/u-boot
+ if [ -e ${BUILD_DIR}/spl/u-boot-spl ]; then
+ OBJS="${OBJS} ${BUILD_DIR}/spl/u-boot-spl"
+ fi
+
+ ${CROSS_COMPILE}size ${OBJS} | tee -a ${LOG_DIR}/$target.MAKELOG
}
build_targets() {
for t in "$@" ; do
#
-# (C) Copyright 2000-2011
+# (C) Copyright 2000-2012
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# MA 02111-1307 USA
#
-VERSION = 2011
-PATCHLEVEL = 12
+VERSION = 2012
+PATCHLEVEL = 04
SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
ifneq "$(SUBLEVEL)" ""
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
else
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
+LDSCRIPT_MAKEFILE_DIR = $(dir $(LDSCRIPT))
+
ifndef LDSCRIPT
#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
ifdef CONFIG_SYS_LDSCRIPT
endif
endif
+# If there is no specified link script, we look in a number of places for it
ifndef LDSCRIPT
ifeq ($(CONFIG_NAND_U_BOOT),y)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds
endif
+ ifeq ($(wildcard $(LDSCRIPT)),)
+ LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
+ # We don't expect a Makefile here
+ LDSCRIPT_MAKEFILE_DIR =
+ endif
ifeq ($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
endif
# on the fly.
LDPPFLAGS += \
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
+ -DCPUDIR=$(CPUDIR) \
$(shell $(LD) --version | \
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin
ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin
ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin
-ALL-$(CONFIG_MMC_U_BOOT) += $(obj)mmc_spl/u-boot-mmc-spl.bin
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
$(obj)u-boot-onenand.bin: onenand_ipl $(obj)u-boot.bin
cat $(ONENAND_BIN) $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
-mmc_spl: $(TIMESTAMP_FILE) $(VERSION_FILE) depend
- $(MAKE) -C mmc_spl/board/$(BOARDDIR) all
-
-$(obj)mmc_spl/u-boot-mmc-spl.bin: mmc_spl
-
$(obj)spl/u-boot-spl.bin: $(SUBDIR_TOOLS) depend
$(MAKE) -C spl all
$(obj)include/autoconf.mk \
$(obj)include/generated/generic-asm-offsets.h \
$(obj)include/generated/asm-offsets.h
- for dir in $(SUBDIRS) $(CPUDIR) $(dir $(LDSCRIPT)) ; do \
+ for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do \
$(MAKE) -C $$dir _depend ; done
TAG_SUBDIRS = $(SUBDIRS)
FIND := find
FINDFLAGS := -L
+checkstack:
+ $(CROSS_COMPILE)objdump -d $(obj)u-boot \
+ `$(FIND) $(obj) -name u-boot-spl -print` | \
+ perl $(src)tools/checkstack.pl $(ARCH)
+
tags ctags:
ctags -w -o $(obj)ctags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \
-name '*.[chS]' -print`
fi;
@$(MKCONFIG) -n $@ SX1 arm arm925t sx1
-#########################################################################
-## XScale Systems
-#########################################################################
-
-pdnb3_config \
-scpu_config: unconfig
- @mkdir -p $(obj)include
- @if [ "$(findstring scpu_,$@)" ] ; then \
- echo "#define CONFIG_SCPU" >>$(obj)include/config.h ; \
- fi
- @$(MKCONFIG) -n $@ -a pdnb3 arm ixp pdnb3 prodrive
-
#########################################################################
## ARM1176 Systems
#########################################################################
@rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s
@rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map}
@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl.map}
- @rm -f $(obj)mmc_spl/{u-boot.lds,u-boot-spl,u-boot-spl.map,u-boot-spl.bin,u-boot-mmc-spl.bin}
@rm -f $(ONENAND_BIN)
@rm -f $(obj)onenand_ipl/u-boot.lds
@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map}
@rm -f $(obj)MLO
@rm -f $(TIMESTAMP_FILE) $(VERSION_FILE)
@find $(OBJTREE) -type f \
- \( -name 'core' -o -name '*.bak' -o -name '*~' \
+ \( -name 'core' -o -name '*.bak' -o -name '*~' -o -name '*.su' \
-o -name '*.o' -o -name '*.a' -o -name '*.exe' \) -print \
| xargs rm -f
@rm -fr $(obj)include/generated
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f
- @[ ! -d $(obj)mmc_spl ] || find $(obj)mmc_spl -name "*" -type l -print | xargs rm -f
@rm -f $(obj)dts/*.tmp
mrproper \
'Sane' compilers will generate smaller code if
CONFIG_PRE_CON_BUF_SZ is a power of 2
-- Pre-console putc():
- Prior to the console being initialised, console output is
- normally silently discarded. This can be annoying if a
- panic() happens in this time.
-
- If the CONFIG_PRE_CONSOLE_PUTC option is defined, then
- U-Boot will call board_pre_console_putc() for each output
- character in this case, This function should try to output
- the character if possible, perhaps on all available UARTs
- (it will need to do this directly, since the console code
- is not functional yet). Note that if the panic happens
- early enough, then it is possible that board_init_f()
- (or even arch_cpu_init() on ARM) has not been called yet.
- You should init all clocks, GPIOs, etc. that are needed
- to get the character out. Baud rates will need to default
- to something sensible.
-
- Safe printf() functions
Define CONFIG_SYS_VSNPRINTF to compile in safe versions of
the printf() functions. These are defined in
May be defined to allow interrupt polling
instead of using asynchronous interrupts
+ CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
+ txfilltuning field in the EHCI controller on reset.
+
- USB Device:
Define the below if you wish to use the USB console.
Once firmware is rebuilt from a serial console issue the
Define this to have a tty type of device available to
talk to the UDC device
+ CONFIG_USBD_HS
+ Define this to enable the high speed support for usb
+ device and usbtty. If this feature is enabled, a routine
+ int is_usbd_high_speed(void)
+ also needs to be defined by the driver to dynamically poll
+ whether the enumeration has succeded at high speed or full
+ speed.
+
CONFIG_SYS_CONSOLE_IS_IN_ENV
Define this if you want stdin, stdout &/or stderr to
be set to usbtty.
- FAT(File Allocation Table) filesystem write function support:
CONFIG_FAT_WRITE
- Support for saving memory data as a file
- in FAT formatted partition
+
+ Define this to enable support for saving memory data as a
+ file in FAT formatted partition.
+
+ This will also enable the command "fatwrite" enabling the
+ user to write files to FAT.
- Keyboard Support:
CONFIG_ISA_KEYBOARD
example, some LED's) on your board. At the moment,
the following checkpoints are implemented:
+- Detailed boot stage timing
+ CONFIG_BOOTSTAGE
+ Define this option to get detailed timing of each stage
+ of the boot process.
+
+ CONFIG_BOOTSTAGE_USER_COUNT
+ This is the number of available user bootstage records.
+ Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...)
+ a new ID will be allocated from this stash. If you exceed
+ the limit, recording will stop.
+
+ CONFIG_BOOTSTAGE_REPORT
+ Define this to print a report before boot, similar to this:
+
+ Timer summary in microseconds:
+ Mark Elapsed Stage
+ 0 0 reset
+ 3,575,678 3,575,678 board_init_f start
+ 3,575,695 17 arch_cpu_init A9
+ 3,575,777 82 arch_cpu_init done
+ 3,659,598 83,821 board_init_r start
+ 3,910,375 250,777 main_loop
+ 29,916,167 26,005,792 bootm_start
+ 30,361,327 445,160 start_kernel
+
Legacy uImage format:
Arg Where When
CONFIG_SPL
Enable building of SPL globally.
+ CONFIG_SPL_LDSCRIPT
+ LDSCRIPT for linking the SPL binary.
+
+ CONFIG_SPL_MAX_SIZE
+ Maximum binary size (text, data and rodata) of the SPL binary.
+
CONFIG_SPL_TEXT_BASE
TEXT_BASE for linking the SPL binary.
- CONFIG_SPL_LDSCRIPT
- LDSCRIPT for linking the SPL binary.
+ CONFIG_SPL_BSS_START_ADDR
+ Link address for the BSS within the SPL binary.
+
+ CONFIG_SPL_BSS_MAX_SIZE
+ Maximum binary size of the BSS section of the SPL binary.
+
+ CONFIG_SPL_STACK
+ Adress of the start of the stack SPL will use
+
+ CONFIG_SYS_SPL_MALLOC_START
+ Starting address of the malloc pool used in SPL.
+
+ CONFIG_SYS_SPL_MALLOC_SIZE
+ The size of the malloc pool used in SPL.
CONFIG_SPL_LIBCOMMON_SUPPORT
Support for common/libcommon.o in SPL binary
CONFIG_SPL_MMC_SUPPORT
Support for drivers/mmc/libmmc.o in SPL binary
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+ CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS,
+ CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION
+ Address, size and partition on the MMC to load U-Boot from
+ when the MMC is being used in raw mode.
+
+ CONFIG_SPL_FAT_SUPPORT
+ Support for fs/fat/libfat.o in SPL binary
+
+ CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
+ Filename to read to load U-Boot when reading from FAT
+
+ CONFIG_SPL_NAND_SIMPLE
+ Support for drivers/mtd/nand/libnand.o in SPL binary
+
+ CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT,
+ CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE,
+ CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS,
+ CONFIG_SYS_NAND_ECCPOS, CONFIG_SYS_NAND_ECCSIZE,
+ CONFIG_SYS_NAND_ECCBYTES
+ Defines the size and behavior of the NAND that SPL uses
+ to read U-Boot with CONFIG_SPL_NAND_SIMPLE
+
+ CONFIG_SYS_NAND_U_BOOT_OFFS
+ Location in NAND for CONFIG_SPL_NAND_SIMPLE to read U-Boot
+ from.
+
+ CONFIG_SYS_NAND_U_BOOT_START
+ Location in memory for CONFIG_SPL_NAND_SIMPLE to load U-Boot
+ to.
+
+ CONFIG_SYS_NAND_HW_ECC_OOBFIRST
+ Define this if you need to first read the OOB and then the
+ data. This is used for example on davinci plattforms.
+
+ CONFIG_SPL_OMAP3_ID_NAND
+ Support for an OMAP3-specific set of functions to return the
+ ID and MFR of the first attached NAND chip, if present.
+
CONFIG_SPL_SERIAL_SUPPORT
Support for drivers/serial/libserial.o in SPL binary
CONFIG_SPL_SPI_SUPPORT
Support for drivers/spi/libspi.o in SPL binary
- CONFIG_SPL_FAT_SUPPORT
- Support for fs/fat/libfat.o in SPL binary
-
CONFIG_SPL_LIBGENERIC_SUPPORT
Support for lib/libgeneric.o in SPL binary
that is executed before the actual U-Boot. E.g. when
compiling a NAND SPL.
-- CONFIG_SYS_NAND_HW_ECC_OOBFIRST
- define this, if you want to read first the oob data
- and then the data. This is used for example on
- davinci plattforms.
-
- CONFIG_USE_ARCH_MEMCPY
CONFIG_USE_ARCH_MEMSET
If these options are used a optimized version of memcpy/memset will
run - run commands in an environment variable
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
+bootz - boot zImage from memory
tftpboot- boot image via network using TFTP protocol
and env variables "ipaddr" and "serverip"
(and eventually "gatewayip")
fdt_high - if set this restricts the maximum address that the
flattened device tree will be copied into upon boot.
+ For example, if you have a system with 1 GB memory
+ at physical address 0x10000000, while Linux kernel
+ only recognizes the first 704 MB as low memory, you
+ may need to set fdt_high as 0x3C000000 to have the
+ device tree blob be copied to the maximum address
+ of the 704 MB low memory, so that Linux kernel can
+ access it during the boot procedure.
+
If this is set to the special value 0xFFFFFFFF then
the fdt will not be copied at all on boot. For this
to work it must reside in writable memory, have
useful when you configure U-Boot to use a real shell (hush)
as command interpreter.
+Booting the Linux zImage:
+-------------------------
+
+On some platforms, it's possible to boot Linux zImage. This is done
+using the "bootz" command. The syntax of "bootz" command is the same
+as the syntax of "bootm" command.
+
+Note, defining the CONFIG_SUPPORT_INITRD_RAW allows user to supply
+kernel with raw initrd images. The syntax is slightly different, the
+address of the initrd must be augmented by it's size, in the following
+format: "<initrd addres>:<initrd size>".
+
Standalone HOWTO:
=================
endif
endif
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else
-LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
-endif
-
# needed for relocation
ifndef CONFIG_NAND_SPL
LDFLAGS_u-boot += -pie
return "WDOG";
case 0x0006:
return "JTAG";
+ case 0x0007:
+ return "ARM11P power gating";
default:
return "unknown reset";
}
/*NOP*/;
}
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_MX31_CLK32;
+}
+
void reset_cpu(ulong addr)
{
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
""
);
+#if defined(CONFIG_DISPLAY_CPUINFO)
static char *get_reset_cause(void)
{
/* read RCSR register from CCM module */
}
}
-#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
u32 srev = get_cpu_rev();
#include <common.h>
#include <asm/io.h>
+#include <div64.h>
#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp (gd->tbl)
+#define lastinc (gd->lastinc)
/* General purpose timers bitfields */
#define GPTCR_SWR (1<<15) /* Software reset */
#define GPTCR_CLKSOURCE_32 (0x100<<6) /* Clock source */
#define GPTCR_CLKSOURCE_IPG (0x001<<6) /* Clock source */
#define GPTCR_TEN (1) /* Timer enable */
-#define GPTPR_VAL (66)
+
+#define TIMER_FREQ_HZ mxc_get_clock(MXC_IPG_CLK)
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, TIMER_FREQ_HZ);
+
+ return tick;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long usec)
+{
+ usec *= TIMER_FREQ_HZ;
+ do_div(usec, 1000000);
+
+ return usec;
+}
int timer_init(void)
{
for (i = 0; i < 100; i++)
writel(0, &gpt->ctrl); /* We have no udelay by now */
- writel(GPTPR_VAL, &gpt->pre);
+ writel(0, &gpt->pre);
/* Freerun Mode, PERCLK1 input */
writel(readl(&gpt->ctrl) |
GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
return 0;
}
-void reset_timer_masked(void)
+unsigned long long get_ticks(void)
{
struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
-
- writel(0, &gpt->ctrl);
- /* Freerun Mode, PERCLK1 input */
- writel(GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
- &gpt->ctrl);
+ ulong now = readl(&gpt->counter); /* current tick value */
+
+ if (now >= lastinc) {
+ /*
+ * normal mode (non roll)
+ * move stamp forward with absolut diff ticks
+ */
+ timestamp += (now - lastinc);
+ } else {
+ /* we have rollover of incrementer */
+ timestamp += (0xFFFFFFFF - lastinc) + now;
+ }
+ lastinc = now;
+ return timestamp;
}
-inline ulong get_timer_masked(void)
+ulong get_timer_masked(void)
{
-
- struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
- ulong val = readl(&gpt->counter);
-
- return val;
+ /*
+ * get_ticks() returns a long long (64 bit), it wraps in
+ * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+ * 5 * 10^6 days - long enough.
+ */
+ return tick_to_time(get_ticks());
}
ulong get_timer(ulong base)
{
- ulong tmp;
+ return get_timer_masked() - base;
+}
- tmp = get_timer_masked();
+/* delay x useconds AND preserve advance timstamp value */
+void __udelay(unsigned long usec)
+{
+ unsigned long long tmp;
+ ulong tmo;
- if (tmp <= (base * 1000)) {
- /* Overflow */
- tmp += (0xffffffff - base);
- }
+ tmo = us_to_tick(usec);
+ tmp = get_ticks() + tmo; /* get current timestamp */
- return (tmp / 1000) - base;
+ while (get_ticks() < tmp) /* loop till event */
+ /*NOP*/;
}
/*
- * delay x useconds AND preserve advance timstamp value
- * GPTCNT is now supposed to tick 1 by 1 us.
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
*/
-void __udelay(unsigned long usec)
+ulong get_tbclk(void)
{
- ulong tmp;
-
- tmp = get_timer_masked(); /* get current timestamp */
-
- /* if setting this forward will roll time stamp */
- if ((usec + tmp + 1) < tmp) {
- /* reset "advancing" timestamp to 0, set lastinc value */
- reset_timer_masked();
- } else {
- /* else, set advancing stamp wake up time */
- tmp += usec;
- }
-
- while (get_timer_masked() < tmp) /* loop till event */
- /*NOP*/;
+ return TIMER_FREQ_HZ;
}
+++ /dev/null
-/*
- * (C) Copyright 2009
- * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
- *
- * Copyright (C) 2005-2007 Samsung Electronics
- * Kyungin Park <kyugnmin.park@samsung.com>
- *
- * Copyright (c) 2004 Texas Instruments
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm1136/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2002-2004
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm1176/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm720t/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
#include <asm/io.h>
#include <asm/arch/s3c24x0_cpu.h>
-int timer_load_val = 0;
-static ulong timer_clk;
-
-/* macro to read the 16 bit timer */
-static inline ulong READ_TIMER(void)
-{
- struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
-
- return readl(&timers->tcnto4) & 0xffff;
-}
-
-static ulong timestamp;
-static ulong lastdec;
+DECLARE_GLOBAL_DATA_PTR;
int timer_init(void)
{
/* use PWM Timer 4 because it has no output */
/* prescaler for Timer 4 is 16 */
writel(0x0f00, &timers->tcfg0);
- if (timer_load_val == 0) {
+ if (gd->tbu == 0) {
/*
* for 10 ms clock period @ PCLK with 4 bit divider = 1/2
* (default) and prescaler = 16. Should be 10390
* @33.25MHz and 15625 @ 50 MHz
*/
- timer_load_val = get_PCLK() / (2 * 16 * 100);
- timer_clk = get_PCLK() / (2 * 16);
+ gd->tbu = get_PCLK() / (2 * 16 * 100);
+ gd->timer_rate_hz = get_PCLK() / (2 * 16);
}
/* load value for 10 ms timeout */
- lastdec = timer_load_val;
- writel(timer_load_val, &timers->tcntb4);
+ writel(gd->tbu, &timers->tcntb4);
/* auto load, manual update of timer 4 */
tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
writel(tmr, &timers->tcon);
/* auto load, start timer 4 */
tmr = (tmr & ~0x0700000) | 0x0500000;
writel(tmr, &timers->tcon);
- timestamp = 0;
+ gd->lastinc = 0;
+ gd->tbl = 0;
- return (0);
+ return 0;
}
/*
ulong start = get_ticks();
tmo = usec / 1000;
- tmo *= (timer_load_val * 100);
+ tmo *= (gd->tbu * 100);
tmo /= 1000;
while ((ulong) (get_ticks() - start) < tmo)
{
ulong tmr = get_ticks();
- return tmr / (timer_clk / CONFIG_SYS_HZ);
+ return tmr / (gd->timer_rate_hz / CONFIG_SYS_HZ);
}
void udelay_masked(unsigned long usec)
if (usec >= 1000) {
tmo = usec / 1000;
- tmo *= (timer_load_val * 100);
+ tmo *= (gd->tbu * 100);
tmo /= 1000;
} else {
- tmo = usec * (timer_load_val * 100);
+ tmo = usec * (gd->tbu * 100);
tmo /= (1000 * 1000);
}
*/
unsigned long long get_ticks(void)
{
- ulong now = READ_TIMER();
+ struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
+ ulong now = readl(&timers->tcnto4) & 0xffff;
- if (lastdec >= now) {
+ if (gd->lastinc >= now) {
/* normal mode */
- timestamp += lastdec - now;
+ gd->tbl += gd->lastinc - now;
} else {
/* we have an overflow ... */
- timestamp += lastdec + timer_load_val - now;
+ gd->tbl += gd->lastinc + gd->tbu - now;
}
- lastdec = now;
+ gd->lastinc = now;
- return timestamp;
+ return gd->tbl;
}
/*
*/
ulong get_tbclk(void)
{
- ulong tbclk;
-
-#if defined(CONFIG_SMDK2400)
- tbclk = timer_load_val * 100;
-#elif defined(CONFIG_SBC2410X) || \
- defined(CONFIG_SMDK2410) || \
- defined(CONFIG_S3C2440) || \
- defined(CONFIG_VCMA9)
- tbclk = CONFIG_SYS_HZ;
-#else
-# error "tbclk not configured"
-#endif
-
- return tbclk;
+ return CONFIG_SYS_HZ;
}
/*
pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)",
usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (usb_pipeint(pipe)) {
info("Root-Hub submit IRQ: NOT implemented");
#ifdef DEBUG
ohci_dump_roothub(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
len = min_t(int, len, leni);
pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)",
0 /*usb_pipein(pipe) */);
#else
- wait_ms(1);
+ mdelay(1);
#endif
return stat;
pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_common_message: pipesize for pipe %lx is zero",
return -1;
}
- wait_ms(10);
+ mdelay(10);
/* ohci_dump_status(&gohci); */
/* allow more time for a BULK device to react - some are slow */
}
if (--timeout) {
- wait_ms(1);
+ mdelay(1);
if (!urb_finished)
dbg("\%");
pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)",
usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* free TDs in urb_priv */
pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB",
usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_control_message: pipesize for pipe %lx is zero",
writel(OHCI_OCR, &ohci->regs->cmdstatus);
info("USB HC TakeOver from SMM");
while (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms(10);
+ mdelay(10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
#ifdef DEBUG
ohci_dump(ohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* FIXME: be optimistic, hope that bug won't repeat often. */
/* Make some non-interrupt context restart the controller. */
}
if (ints & OHCI_INTR_WDH) {
- wait_ms(1);
+ mdelay(1);
writel(OHCI_INTR_WDH, ®s->intrdisable);
stat = dl_done_list(&gohci, dl_reverse_done_list(&gohci));
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
writel(OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
writel(OHCI_INTR_SF, ®s->intrenable);
/* FIXME this is a second HC reset; why?? */
gohci.hc_control = OHCI_USB_RESET;
writel(gohci.hc_control, &gohci.regs->control);
- wait_ms(10);
+ mdelay(10);
if (hc_start(&gohci) < 0) {
err("can't start usb-%s", gohci.slot_name);
#ifdef DEBUG
ohci_dump(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
ohci_inited = 1;
urb_finished = 1;
+++ /dev/null
-/*
- * (c) Copyright 2004
- * Techware Information Technology, Inc.
- * Ming-Len Wu <minglen_wu@techware.com.tw>
- *
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <gj@denx.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
- *
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm920t/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2004
- * Wolfgang Denk, DENX Software Engineering, <wg@denx.de>
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm925t/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
}
#endif
-#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+#if defined(CONFIG_GENERIC_ATMEL_MCI)
void at91_mci_hw_init(void)
{
at91_set_a_periph(AT91_PIO_PORTA, 8, 1); /* MCCK */
#include <common.h>
#ifndef CONFIG_SYS_DCACHE_OFF
-static inline void dcache_noop(void)
+
+#ifndef CONFIG_SYS_CACHELINE_SIZE
+#define CONFIG_SYS_CACHELINE_SIZE 32
+#endif
+
+void invalidate_dcache_all(void)
{
- if (dcache_status()) {
- puts("WARNING: cache operations are not implemented!\n"
- "WARNING: disabling D-Cache now, you can re-enable it"
- "later with 'dcache on' command\n");
- dcache_disable();
- }
+ asm volatile("mcr p15, 0, %0, c7, c6, 0\n"::"r"(0));
}
-void invalidate_dcache_all(void)
+void flush_dcache_all(void)
{
- dcache_noop();
+ asm volatile(
+ "0:"
+ "mrc p15, 0, r15, c7, c14, 3\n"
+ "bne 0b\n"
+ "mcr p15, 0, %0, c7, c10, 4\n"
+ ::"r"(0):"memory"
+ );
+}
+
+static int check_cache_range(unsigned long start, unsigned long stop)
+{
+ int ok = 1;
+
+ if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (!ok)
+ printf("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
+ start, stop);
+
+ return ok;
}
void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
- dcache_noop();
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c6, 1\n"::"r"(start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
}
void flush_dcache_range(unsigned long start, unsigned long stop)
{
- dcache_noop();
+ if (!check_cache_range(start, stop))
+ return;
+
+ while (start < stop) {
+ asm volatile("mcr p15, 0, %0, c7, c14, 1\n"::"r"(start));
+ start += CONFIG_SYS_CACHELINE_SIZE;
+ }
+
+ asm("mcr p15, 0, %0, c7, c10, 4\n"::"r"(0));
+}
+
+void flush_cache(unsigned long start, unsigned long size)
+{
+ flush_dcache_range(start, start + size);
}
#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
void invalidate_dcache_all(void)
{
}
-void flush_cache(unsigned long start, unsigned long size)
+void flush_cache(unsigned long start, unsigned long size)
{
}
#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
{
volatile void *pllbase = (volatile void *) pll_addr;
#ifdef CONFIG_SOC_DM646X
- unsigned base = CFG_REFCLK_FREQ / 1000;
+ unsigned base = CONFIG_REFCLK_FREQ / 1000;
#else
unsigned base = CONFIG_SYS_HZ_CLOCK / 1000;
#endif
void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr)
{
uint8_t env_enetaddr[6];
+ int ret;
- eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr);
- if (!memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
+ ret = eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr);
+ if (ret) {
/*
* There is no MAC address in the environment, so we
* initialize it from the value in the EEPROM.
debug("### Setting environment from EEPROM MAC address = "
"\"%pM\"\n",
env_enetaddr);
- eth_setenv_enetaddr("ethaddr", rom_enetaddr);
+ ret = !eth_setenv_enetaddr("ethaddr", rom_enetaddr);
}
+ if (!ret)
+ printf("Failed to set mac address from EEPROM\n");
}
#endif /* CONFIG_DRIVER_TI_EMAC */
}
debug("Starting %s process...\n", __FUNCTION__);
-#if !defined(CONFIG_SYS_HUSH_PARSER)
- ret = run_command (s, 0);
-#else
- ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON
- | FLAG_EXIT_FROM_LOOP);
-#endif
+ ret = run_command(s, 0);
if (ret < 0)
debug("Error.. %s failed\n", __FUNCTION__);
else
while (get_ticks() < tmp) /* loop till event */
/*NOP*/;
}
+
+ulong get_tbclk(void)
+{
+ return CONFIG_MX27_CLK32;
+}
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- uint32_t clkctrl, clkseq, clkfrac;
- uint32_t frac, div;
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu);
}
/* REF Path */
- clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac0);
- frac = clkfrac & CLKCTRL_FRAC0_CPUFRAC_MASK;
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
}
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- uint32_t frac, div;
- uint32_t clkctrl, clkseq, clkfrac;
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi);
return XTAL_FREQ_MHZ / div;
}
- clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac0);
-
/* REF Path */
- frac = (clkfrac & CLKCTRL_FRAC0_EMIFRAC_MASK) >>
- CLKCTRL_FRAC0_EMIFRAC_OFFSET;
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK;
return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
}
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- uint32_t frac, div;
- uint32_t clkctrl, clkseq, clkfrac;
+ uint32_t clkctrl, clkseq, div;
+ uint8_t clkfrac, frac;
clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi);
return XTAL_FREQ_MHZ / div;
}
- clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac1);
-
/* REF Path */
- frac = (clkfrac & CLKCTRL_FRAC1_GPMIFRAC_MASK) >>
- CLKCTRL_FRAC1_GPMIFRAC_OFFSET;
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
div = clkctrl & CLKCTRL_GPMI_DIV_MASK;
return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
}
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
uint32_t div;
+ int io_reg;
if (freq == 0)
return;
- if (io > MXC_IOCLK1)
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
return;
div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq;
if (div > 35)
div = 35;
- if (io == MXC_IOCLK0) {
- writel(CLKCTRL_FRAC0_CLKGATEIO0,
- &clkctrl_regs->hw_clkctrl_frac0_set);
- clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
- CLKCTRL_FRAC0_IO0FRAC_MASK,
- div << CLKCTRL_FRAC0_IO0FRAC_OFFSET);
- writel(CLKCTRL_FRAC0_CLKGATEIO0,
- &clkctrl_regs->hw_clkctrl_frac0_clr);
- } else {
- writel(CLKCTRL_FRAC0_CLKGATEIO1,
- &clkctrl_regs->hw_clkctrl_frac0_set);
- clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
- CLKCTRL_FRAC0_IO1FRAC_MASK,
- div << CLKCTRL_FRAC0_IO1FRAC_OFFSET);
- writel(CLKCTRL_FRAC0_CLKGATEIO1,
- &clkctrl_regs->hw_clkctrl_frac0_clr);
- }
+ io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[io_reg]);
+ writeb(CLKCTRL_FRAC_CLKGATE | (div & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[io_reg]);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[io_reg]);
}
/*
{
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- uint32_t tmp, ret;
+ uint8_t ret;
+ int io_reg;
- if (io > MXC_IOCLK1)
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
return 0;
- tmp = readl(&clkctrl_regs->hw_clkctrl_frac0);
+ io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
- if (io == MXC_IOCLK0)
- ret = (tmp & CLKCTRL_FRAC0_IO0FRAC_MASK) >>
- CLKCTRL_FRAC0_IO0FRAC_OFFSET;
- else
- ret = (tmp & CLKCTRL_FRAC0_IO1FRAC_MASK) >>
- CLKCTRL_FRAC0_IO1FRAC_OFFSET;
+ ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) &
+ CLKCTRL_FRAC_FRAC_MASK;
return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret;
}
return;
clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
- (ssp * sizeof(struct mx28_register));
+ (ssp * sizeof(struct mx28_register_32));
clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE);
while (readl(clkreg) & CLKCTRL_SSP_CLKGATE)
return XTAL_FREQ_KHZ;
clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
- (ssp * sizeof(struct mx28_register));
+ (ssp * sizeof(struct mx28_register_32));
tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
{
u32 reg, ofs, bp, bm;
void *iomux_base = (void *)MXS_PINCTRL_BASE;
- struct mx28_register *mxs_reg;
+ struct mx28_register_32 *mxs_reg;
/* muxsel */
ofs = 0x100;
/* vol */
if (PAD_VOL_VALID(pad)) {
bp = PAD_PIN(pad) % 8 * 4 + 2;
- mxs_reg = (struct mx28_register *)(iomux_base + ofs);
+ mxs_reg = (struct mx28_register_32 *)(iomux_base + ofs);
if (PAD_VOL(pad))
writel(1 << bp, &mxs_reg->reg_set);
else
ofs = PULL_OFFSET;
ofs += PAD_BANK(pad) * 0x10;
bp = PAD_PIN(pad);
- mxs_reg = (struct mx28_register *)(iomux_base + ofs);
+ mxs_reg = (struct mx28_register_32 *)(iomux_base + ofs);
if (PAD_PULL(pad))
writel(1 << bp, &mxs_reg->reg_set);
else
;
}
-int mx28_wait_mask_set(struct mx28_register *reg, uint32_t mask, int timeout)
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+ icache_enable();
+#endif
+#ifndef CONFIG_SYS_DCACHE_OFF
+ dcache_enable();
+#endif
+}
+
+int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout)
{
while (--timeout) {
if ((readl(®->reg) & mask) == mask)
return !timeout;
}
-int mx28_wait_mask_clr(struct mx28_register *reg, uint32_t mask, int timeout)
+int mx28_wait_mask_clr(struct mx28_register_32 *reg, uint32_t mask, int timeout)
{
while (--timeout) {
if ((readl(®->reg) & mask) == 0)
return !timeout;
}
-int mx28_reset_block(struct mx28_register *reg)
+int mx28_reset_block(struct mx28_register_32 *reg)
{
/* Clear SFTRST */
writel(MX28_BLOCK_SFTRST, ®->reg_clr);
}
#endif
-#define HW_DIGCTRL_SCRATCH0 0x8001c280
-#define HW_DIGCTRL_SCRATCH1 0x8001c290
int mx28_dram_init(void)
{
+ struct mx28_digctl_regs *digctl_regs =
+ (struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
uint32_t sz[2];
- sz[0] = readl(HW_DIGCTRL_SCRATCH0);
- sz[1] = readl(HW_DIGCTRL_SCRATCH1);
+ sz[0] = readl(&digctl_regs->hw_digctl_scratch0);
+ sz[1] = readl(&digctl_regs->hw_digctl_scratch1);
if (sz[0] != sz[1]) {
printf("MX28:\n"
#include "mx28_init.h"
uint32_t dram_vals[] = {
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00010101, 0x01010101, 0x000f0f01, 0x0f02020a,
- 0x00000000, 0x00010101, 0x00000100, 0x00000100, 0x00000000,
- 0x00000002, 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
- 0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612, 0x02030202,
- 0x00c8001c, 0x00000000, 0x00000000, 0x00012100, 0xffff0303,
- 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, 0x00012100,
- 0xffff0303, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000612, 0x01000F02, 0x06120612, 0x00000200,
- 0x00020007, 0xf5014b27, 0xf5014b27, 0xf5014b27, 0xf5014b27,
- 0x07000300, 0x07000300, 0x07000300, 0x07000300, 0x00000006,
- 0x00000000, 0x00000000, 0x01000000, 0x01020408, 0x08040201,
- 0x000f1133, 0x00000000, 0x00001f04, 0x00001f04, 0x00001f04,
- 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00010000, 0x00020304, 0x00000004,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x01010000, 0x01000000, 0x03030000, 0x00010303,
- 0x01020202, 0x00000000, 0x02040303, 0x21002103, 0x00061200,
- 0x06120612, 0x04320432, 0x04320432, 0x00040004, 0x00040004,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00010101, 0x01010101,
+ 0x000f0f01, 0x0f02010a, 0x00000000, 0x00010101,
+ 0x00000100, 0x00000100, 0x00000000, 0x00000002,
+ 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
+ 0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612,
+ 0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000612, 0x01000F02,
+ 0x06120612, 0x00000200, 0x00020007, 0xf5014b27,
+ 0xf5014b27, 0xf5014b27, 0xf5014b27, 0x07000300,
+ 0x07000300, 0x07000300, 0x07000300, 0x00000006,
+ 0x00000000, 0x00000000, 0x01000000, 0x01020408,
+ 0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+ 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+ 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00010000, 0x00020304,
+ 0x00000004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x01010000,
+ 0x01000000, 0x03030000, 0x00010303, 0x01020202,
+ 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+ 0x06120612, 0x04320432, 0x04320432, 0x00040004,
+ 0x00040004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00010001
};
void init_m28_200mhz_ddr2(void)
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
/* Gate EMI clock */
- writel(CLKCTRL_FRAC0_CLKGATEEMI,
- &clkctrl_regs->hw_clkctrl_frac0_set);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]);
- /* EMI = 205MHz */
- writel(CLKCTRL_FRAC0_EMIFRAC_MASK,
- &clkctrl_regs->hw_clkctrl_frac0_set);
- writel((0x2a << CLKCTRL_FRAC0_EMIFRAC_OFFSET) &
- CLKCTRL_FRAC0_EMIFRAC_MASK,
- &clkctrl_regs->hw_clkctrl_frac0_clr);
+ /* Set fractional divider for ref_emi to 480 * 18 / 21 = 411MHz */
+ writeb(CLKCTRL_FRAC_CLKGATE | (21 & CLKCTRL_FRAC_FRAC_MASK),
+ &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]);
/* Ungate EMI clock */
- writel(CLKCTRL_FRAC0_CLKGATEEMI,
- &clkctrl_regs->hw_clkctrl_frac0_clr);
+ writeb(CLKCTRL_FRAC_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
early_delay(11000);
+ /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
(1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
&clkctrl_regs->hw_clkctrl_emi);
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
- /* CPU = 454MHz and ungate CPU clock */
- clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
- CLKCTRL_FRAC0_CPUFRAC_MASK | CLKCTRL_FRAC0_CLKGATECPU,
- 19 << CLKCTRL_FRAC0_CPUFRAC_OFFSET);
+ /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz
+ * and ungate CPU clock */
+ writeb(19 & CLKCTRL_FRAC_FRAC_MASK,
+ (uint8_t *)&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
/* Set CPU bypass */
writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
&power_regs->hw_power_vdddctrl);
}
-#define HW_DIGCTRL_SCRATCH0 0x8001c280
-#define HW_DIGCTRL_SCRATCH1 0x8001c290
-void data_abort_memdetect_handler(void) __attribute__((naked));
-void data_abort_memdetect_handler(void)
-{
- asm volatile("subs pc, r14, #4");
-}
-
void mx28_mem_get_size(void)
{
+ struct mx28_digctl_regs *digctl_regs =
+ (struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
uint32_t sz, da;
uint32_t *vt = (uint32_t *)0x20;
+ /* The following is "subs pc, r14, #4", used as return from DABT. */
+ const uint32_t data_abort_memdetect_handler = 0xe25ef004;
/* Replace the DABT handler. */
da = vt[4];
- vt[4] = (uint32_t)&data_abort_memdetect_handler;
+ vt[4] = data_abort_memdetect_handler;
sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
- writel(sz, HW_DIGCTRL_SCRATCH0);
- writel(sz, HW_DIGCTRL_SCRATCH1);
+ writel(sz, &digctl_regs->hw_digctl_scratch0);
+ writel(sz, &digctl_regs->hw_digctl_scratch1);
/* Restore the old DABT handler. */
vt[4] = da;
clrsetbits_le32(&power_regs->hw_power_vddioctrl,
POWER_VDDIOCTRL_TRG_MASK, diff);
- if (powered_by_linreg)
- early_delay(1500);
+ if (powered_by_linreg ||
+ (readl(&power_regs->hw_power_sts) &
+ POWER_STS_VDD5V_GT_VDDIO))
+ early_delay(500);
else {
while (!(readl(&power_regs->hw_power_sts) &
POWER_STS_DC_OK))
clrsetbits_le32(&power_regs->hw_power_vddioctrl,
POWER_VDDIOCTRL_TRG_MASK, diff);
- if (powered_by_linreg)
- early_delay(1500);
+ if (powered_by_linreg ||
+ (readl(&power_regs->hw_power_sts) &
+ POWER_STS_VDD5V_GT_VDDIO))
+ early_delay(500);
else {
while (!(readl(&power_regs->hw_power_sts) &
POWER_STS_DC_OK))
clrsetbits_le32(&power_regs->hw_power_vdddctrl,
POWER_VDDDCTRL_TRG_MASK, diff);
- if (powered_by_linreg)
- early_delay(1500);
+ if (powered_by_linreg ||
+ (readl(&power_regs->hw_power_sts) &
+ POWER_STS_VDD5V_GT_VDDIO))
+ early_delay(500);
else {
while (!(readl(&power_regs->hw_power_sts) &
POWER_STS_DC_OK))
clrsetbits_le32(&power_regs->hw_power_vdddctrl,
POWER_VDDDCTRL_TRG_MASK, diff);
- if (powered_by_linreg)
- early_delay(1500);
+ if (powered_by_linreg ||
+ (readl(&power_regs->hw_power_sts) &
+ POWER_STS_VDD5V_GT_VDDIO))
+ early_delay(500);
else {
while (!(readl(&power_regs->hw_power_sts) &
POWER_STS_DC_OK))
*/
push {r0-r12,r14}
+ /* save control register c1 */
+ mrc p15, 0, r0, c1, c0, 0
+ push {r0}
+
/*
- * set the cpu to SVC32 mode
+ * set the cpu to SVC32 mode and store old CPSR register content
*/
mrs r0,cpsr
+ push {r0}
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
bl board_init_ll
+ /*
+ * restore bootrom's cpu mode (especially FIQ)
+ */
+ pop {r0}
+ msr cpsr,r0
+
+ /*
+ * restore c1 register
+ * (especially set exception vector location back to
+ * bootrom space which is required by bootrom for USB boot)
+ */
+ pop {r0}
+ mcr p15, 0, r0, c1, c0, 0
+
pop {r0-r12,r14}
bx lr
return 0;
}
-ulong get_timer(ulong base)
+unsigned long long get_ticks(void)
{
struct mx28_timrot_regs *timrot_regs =
(struct mx28_timrot_regs *)MXS_TIMROT_BASE;
}
lastdec = now;
- return tick_to_time(timestamp) - base;
+ return timestamp;
+}
+
+ulong get_timer_masked(void)
+{
+ return tick_to_time(get_ticks());
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
}
/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
old = new;
}
}
+
+ulong get_tbclk(void)
+{
+ return MX28_INCREMENTER_HZ;
+}
while ((signed)(end - READ_TIMER()) > 0)
;
}
+
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
+++ /dev/null
-/*
- * (C) Copyright 2002-2004
- * Gary Jennejohn, DENX Software Engineering, <gj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm926ejs/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm946es/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/arm_intcm/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
START := start.o
-ifndef CONFIG_SPL_BUILD
COBJS += cache_v7.o
-endif
COBJS += cpu.o
COBJS += syslib.o
*
* we turn off caches etc ...
*/
+#ifndef CONFIG_SPL_BUILD
disable_interrupts();
+#endif
/*
* Turn off I-cache and invalidate it
LIB = $(obj)lib$(SOC).o
-COBJS := timer.o
+COBJS := timer.o bootcount.o
SOBJS :=
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
--- /dev/null
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * 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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+void bootcount_store(ulong a)
+{
+ writel((BOOTCOUNT_MAGIC & 0xffff0000) | a, CONFIG_SYS_BOOTCOUNT_ADDR);
+}
+
+ulong bootcount_load(void)
+{
+ u32 tmp = readl(CONFIG_SYS_BOOTCOUNT_ADDR);
+
+ if ((tmp & 0xffff0000) != (BOOTCOUNT_MAGIC & 0xffff0000))
+ return 0;
+ else
+ return tmp & 0x0000ffff;
+}
+#endif
--- /dev/null
+PLATFORM_CPPFLAGS += -march=armv7-a
static inline unsigned long long us_to_tick(unsigned long long us)
{
- unsigned long long tick = us << 16;
+ unsigned long long tick = us * 1000;
tick += NS_PER_TICK - 1;
do_div(tick, NS_PER_TICK);
- return tick >> 16;
+ return tick;
}
unsigned long long get_ticks(void)
{
return tick_to_time(get_ticks());
}
+
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
switch (cause) {
case 0x00001:
+ case 0x00011:
return "POR";
case 0x00004:
return "CSU";
}
#if defined(CONFIG_DISPLAY_CPUINFO)
+
+static char *get_imx_type(u32 imxtype)
+{
+ switch (imxtype) {
+ case 0x63:
+ return "6Q"; /* Quad-core version of the mx6 */
+ case 0x61:
+ return "6DS"; /* Dual/Solo version of the mx6 */
+ case 0x60:
+ return "6SL"; /* Solo-Lite version of the mx6 */
+ case 0x51:
+ return "51";
+ case 0x53:
+ return "53";
+ default:
+ return "unknown";
+ }
+}
+
int print_cpuinfo(void)
{
u32 cpurev;
cpurev = get_cpu_rev();
- printf("CPU: Freescale i.MX%x family rev%d.%d at %d MHz\n",
- (cpurev & 0xFF000) >> 12,
+
+ printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n",
+ get_imx_type((cpurev & 0xFF000) >> 12),
(cpurev & 0x000F0) >> 4,
(cpurev & 0x0000F) >> 0,
mxc_get_clock(MXC_ARM_CLK) / 1000000);
#include <common.h>
#include <asm/io.h>
+#include <div64.h>
#include <asm/arch/imx-regs.h>
/* General purpose timers registers */
#define timestamp (gd->tbl)
#define lastinc (gd->lastinc)
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, CLK_32KHZ);
+
+ return tick;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long usec)
+{
+ usec *= CLK_32KHZ;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
int timer_init(void)
{
int i;
return 0;
}
-ulong get_timer_masked(void)
+unsigned long long get_ticks(void)
{
- ulong val = __raw_readl(&cur_gpt->counter);
- val /= (CLK_32KHZ / CONFIG_SYS_HZ);
- if (val >= lastinc)
- timestamp += (val - lastinc);
- else
- timestamp += ((0xFFFFFFFF / (CLK_32KHZ / CONFIG_SYS_HZ))
- - lastinc) + val;
- lastinc = val;
+ ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */
+
+ if (now >= lastinc) {
+ /*
+ * normal mode (non roll)
+ * move stamp forward with absolut diff ticks
+ */
+ timestamp += (now - lastinc);
+ } else {
+ /* we have rollover of incrementer */
+ timestamp += (0xFFFFFFFF - lastinc) + now;
+ }
+ lastinc = now;
return timestamp;
}
+ulong get_timer_masked(void)
+{
+ /*
+ * get_ticks() returns a long long (64 bit), it wraps in
+ * 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+ * 5 * 10^6 days - long enough.
+ */
+ return tick_to_time(get_ticks());
+}
+
ulong get_timer(ulong base)
{
return get_timer_masked() - base;
}
-/* delay x useconds AND preserve advance timestamp value */
+/* delay x useconds AND preserve advance timstamp value */
void __udelay(unsigned long usec)
{
- unsigned long now, start, tmo;
- tmo = usec * (CLK_32KHZ / 1000) / 1000;
-
- if (!tmo)
- tmo = 1;
+ unsigned long long tmp;
+ ulong tmo;
- now = start = readl(&cur_gpt->counter);
+ tmo = us_to_tick(usec);
+ tmp = get_ticks() + tmo; /* get current timestamp */
- while ((now - start) < tmo)
- now = readl(&cur_gpt->counter);
+ while (get_ticks() < tmp) /* loop till event */
+ /*NOP*/;
+}
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CLK_32KHZ;
}
ldr r1, =0x00C30321
str r1, [r0, #CLKCTL_CSCDR1]
#elif defined(CONFIG_MX53)
+ /* Switch peripheral to PLL2 */
+ ldr r0, =CCM_BASE_ADDR
+ ldr r1, =0x00808145
+ orr r1, r1, #(2 << 10)
+ orr r1, r1, #(0 << 16)
+ orr r1, r1, #(1 << 19)
+ str r1, [r0, #CLKCTL_CBCDR]
+
+ ldr r1, =0x00016154
+ str r1, [r0, #CLKCTL_CBCMR]
+ /* Change uart clk parent to pll2*/
+ ldr r1, [r0, #CLKCTL_CSCMR1]
+ and r1, r1, #0xfcffffff
+ orr r1, r1, #0x01000000
+ str r1, [r0, #CLKCTL_CSCMR1]
ldr r1, [r0, #CLKCTL_CSCDR1]
- orr r1, r1, #0x3f
- eor r1, r1, #0x3f
- orr r1, r1, #0x21
+ and r1, r1, #0xffffffc0
+ orr r1, r1, #0x0a
str r1, [r0, #CLKCTL_CSCDR1]
#endif
/* make sure divider effective */
struct imx_ccm_reg *imx_ccm = (struct imx_ccm_reg *)CCM_BASE_ADDR;
+void enable_usboh3_clk(unsigned char enable)
+{
+ u32 reg;
+
+ reg = __raw_readl(&imx_ccm->CCGR6);
+ if (enable)
+ reg |= MXC_CCM_CCGR_CG_MASK << MXC_CCM_CCGR0_CG0_OFFSET;
+ else
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << MXC_CCM_CCGR0_CG0_OFFSET);
+ __raw_writel(reg, &imx_ccm->CCGR6);
+
+}
+
static u32 decode_pll(enum pll_clocks pll, u32 infreq)
{
u32 div;
u32 get_cpu_rev(void)
{
- int system_rev = 0x61000 | CHIP_REV_1_0;
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ int reg = readl(&anatop->digprog);
+
+ /* Read mx6 variant: quad, dual or solo */
+ int system_rev = (reg >> 4) & 0xFF000;
+ /* Read mx6 silicon revision */
+ system_rev |= (reg & 0xFF) + 0x10;
return system_rev;
}
ifdef CONFIG_SPL_MMC_SUPPORT
COBJS += spl_mmc.o
endif
+ifdef CONFIG_SPL_YMODEM_SUPPORT
+COBJS += spl_ymodem.o
+endif
endif
ifndef CONFIG_SPL_BUILD
#ifdef CONFIG_SYS_CLOCKS_ENABLE_ALL
static void setup_non_essential_dplls(void)
{
- u32 sys_clk_khz, abe_ref_clk;
+ u32 abe_ref_clk;
const struct dpll_params *params;
- sys_clk_khz = get_sys_clk_freq() / 1000;
-
/* IVA */
clrsetbits_le32(&prcm->cm_bypclk_dpll_iva,
CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2);
relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
}
+/*
+ * Default function to determine if u-boot or the OS should
+ * be started. This implementation always returns 1.
+ *
+ * Please implement your own board specific funcion to do this.
+ *
+ * RETURN
+ * 0 to not start u-boot
+ * positive if u-boot should start
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+__weak int spl_start_uboot(void)
+{
+ printf("SPL: Please implement spl_start_uboot() for your board\n");
+ printf("SPL: Direct Linux boot not active!\n");
+ return 1;
+}
+#endif
+
void spl_parse_image_header(const struct image_header *header)
{
u32 header_size = sizeof(struct image_header);
/* Signature not found - assume u-boot.bin */
printf("mkimage signature not found - ih_magic = %x\n",
header->ih_magic);
- puts("Assuming u-boot.bin ..\n");
+ debug("Assuming u-boot.bin ..\n");
/* Let's assume U-Boot will not be more than 200 KB */
spl_image.size = 200 * 1024;
spl_image.entry_point = CONFIG_SYS_TEXT_BASE;
}
}
-static void jump_to_image_no_args(void)
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ * arg: Pointer to paramter image in RAM
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+static void __noreturn jump_to_image_linux(void *arg)
+{
+ debug("Entering kernel arg pointer: 0x%p\n", arg);
+ typedef void (*image_entry_arg_t)(int, int, void *)
+ __attribute__ ((noreturn));
+ image_entry_arg_t image_entry =
+ (image_entry_arg_t) spl_image.entry_point;
+ cleanup_before_linux();
+ image_entry(0, CONFIG_MACH_TYPE, arg);
+}
+#endif
+
+static void __noreturn jump_to_image_no_args(void)
{
- typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn));
+ typedef void __noreturn (*image_entry_noargs_t)(u32 *);
image_entry_noargs_t image_entry =
(image_entry_noargs_t) spl_image.entry_point;
image_entry((u32 *)boot_params_ptr_addr);
}
-void jump_to_image_no_args(void) __attribute__ ((noreturn));
void board_init_r(gd_t *id, ulong dummy)
{
u32 boot_device;
case BOOT_DEVICE_NAND:
spl_nand_load_image();
break;
+#endif
+#ifdef CONFIG_SPL_YMODEM_SUPPORT
+ case BOOT_DEVICE_UART:
+ spl_ymodem_load_image();
+ break;
#endif
default:
printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device);
debug("Jumping to U-Boot\n");
jump_to_image_no_args();
break;
+#ifdef CONFIG_SPL_OS_BOOT
+ case IH_OS_LINUX:
+ debug("Jumping to Linux\n");
+ spl_board_prepare_for_linux();
+ jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ break;
+#endif
default:
puts("Unsupported OS image.. Jumping nevertheless..\n");
jump_to_image_no_args();
#include <asm/u-boot.h>
#include <asm/utils.h>
#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
#include <nand.h>
#include <version.h>
#include <asm/omap_common.h>
-
void spl_nand_load_image(void)
{
struct image_header *header;
+ int *src __attribute__((unused));
+ int *dst __attribute__((unused));
+
switch (omap_boot_mode()) {
case NAND_MODE_HW_ECC:
debug("spl: nand - using hw ecc\n");
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ /*
+ * load parameter image
+ * load to temp position since nand_spl_load_image reads
+ * a whole block which is typically larger than
+ * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite
+ * following sections like BSS
+ */
+ nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
+ CONFIG_CMD_SPL_WRITE_SIZE,
+ (void *)CONFIG_SYS_TEXT_BASE);
+ /* copy to destintion */
+ for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
+ src = (int *)CONFIG_SYS_TEXT_BASE;
+ src < (int *)(CONFIG_SYS_TEXT_BASE +
+ CONFIG_CMD_SPL_WRITE_SIZE);
+ src++, dst++) {
+ writel(readl(src), dst);
+ }
+ /* load linux */
+ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+ spl_parse_image_header(header);
+ if (header->ih_os == IH_OS_LINUX) {
+ /* happy - was a linux */
+ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+ spl_image.size, (void *)spl_image.load_addr);
+ nand_deselect();
+ return;
+ } else {
+ printf("The Expected Linux image was not"
+ "found. Please check your NAND"
+ "configuration.\n");
+ printf("Trying to start u-boot now...\n");
+ }
+ }
+#endif
#ifdef CONFIG_NAND_ENV_DST
nand_spl_load_image(CONFIG_ENV_OFFSET,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header);
nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
- (void *)image_load_addr);
+ (void *)spl_image.load_addr);
#ifdef CONFIG_ENV_OFFSET_REDUND
nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header);
nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
- (void *)image_load_addr);
+ (void *)spl_image.load_addr);
#endif
#endif
/* Load u-boot */
--- /dev/null
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2011
+ * Texas Instruments, <www.ti.com>
+ *
+ * Matt Porter <mporter@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 <common.h>
+#include <xyzModem.h>
+#include <asm/u-boot.h>
+#include <asm/utils.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+
+#define BUF_SIZE 1024
+
+static int getcymodem(void) {
+ if (tstc())
+ return (getc());
+ return -1;
+}
+
+void spl_ymodem_load_image(void)
+{
+ int size = 0;
+ int err;
+ int res;
+ int ret;
+ connection_info_t info;
+ char buf[BUF_SIZE];
+ ulong store_addr = ~0;
+ ulong addr = 0;
+
+ info.mode = xyzModem_ymodem;
+ ret = xyzModem_stream_open(&info, &err);
+
+ if (!ret) {
+ while ((res =
+ xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
+ if (addr == 0)
+ spl_parse_image_header((struct image_header *)buf);
+ store_addr = addr + spl_image.load_addr;
+ size += res;
+ addr += res;
+ memcpy((char *)(store_addr), buf, res);
+ }
+ } else {
+ printf("spl: ymodem err - %s\n", xyzModem_error(err));
+ hang();
+ }
+
+ xyzModem_stream_close(&err);
+ xyzModem_stream_terminate(false, &getcymodem);
+
+ printf("Loaded %d bytes\n", size);
+}
void spl_board_init(void)
{
+#ifdef CONFIG_SPL_I2C_SUPPORT
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
}
#endif /* CONFIG_SPL_BUILD */
omap3_update_aux_cr(0x2, 0);
}
-void v7_outer_cache_disable(void)
+void omap3_outer_cache_disable(void)
{
/* Clear L2EN */
omap3_update_aux_cr_secure(0, 0x2);
write_sdrc_timings(CS0, sdrc_actim_base0, mcfg, ctrla, ctrlb,
rfr_ctrl, mr);
make_cs1_contiguous();
- write_sdrc_timings(CS0, sdrc_actim_base1, mcfg, ctrla, ctrlb,
+ write_sdrc_timings(CS1, sdrc_actim_base1, mcfg, ctrla, ctrlb,
rfr_ctrl, mr);
#endif
LIB = $(obj)lib$(SOC).o
SOBJS := lowlevel_init.o
-COBJS := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o
+COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o
+COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
+COBJS := $(COBJS-y)
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
static int is_cpu_powered(void)
{
- struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
}
static void remove_cpu_io_clamps(void)
{
- struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
u32 reg;
/* Remove the clamps on the CPU I/O signals */
static void powerup_cpu(void)
{
- struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
u32 reg;
int timeout = IO_STABILIZATION_DELAY;
static void enable_cpu_power_rail(void)
{
- struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
u32 reg;
reg = readl(&pmc->pmc_cntrl);
void init_pmc_scratch(void)
{
- struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
int i;
/* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */
writel(0xC0, &pmt->pmt_cfg_ctl);
/*
- * If we are ARM7 - give it a different stack. We are about to
- * start up the A9 which will want to use this one.
- */
- asm volatile("ldr sp, =%c0\n"
- : : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+ * If we are ARM7 - give it a different stack. We are about to
+ * start up the A9 which will want to use this one.
+ */
+ asm volatile("mov sp, %0\n"
+ : : "r"(AVP_EARLY_BOOT_STACK_LIMIT));
start_cpu((u32)_start);
halt_avp();
unsigned int query_sdram_size(void)
{
- struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
u32 reg;
reg = readl(&pmc->pmc_scratch20);
#include <asm/arch/tegra2.h>
#include <common.h>
#include <div64.h>
+#include <fdtdec.h>
/*
* This is our record of the current clock rate of each clock. We don't
CLOCK_TYPE_MCPT,
CLOCK_TYPE_PCM,
CLOCK_TYPE_PCMT,
+ CLOCK_TYPE_PCMT16, /* CLOCK_TYPE_PCMT with 16-bit divider */
CLOCK_TYPE_PCXTS,
CLOCK_TYPE_PDCT,
{ CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) },
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) },
{ CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) },
+ { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) },
{ CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) },
{ CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) },
};
/* 0x08 */
TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT),
- TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT),
- TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT),
+ TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16),
+ TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16),
TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT),
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT),
TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT),
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT),
- TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT),
+ TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16),
TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT),
/* 0x28 */
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT),
- TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT),
+ TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16),
TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT),
/* 0x30 */
* Given the parent's rate and the required rate for the children, this works
* out the peripheral clock divider to use, in 7.1 binary format.
*
+ * @param divider_bits number of divider bits (8 or 16)
* @param parent_rate clock rate of parent clock in Hz
* @param rate required clock rate for this clock
* @return divider which should be used
*/
-static int clk_div7_1_get_divider(unsigned long parent_rate,
- unsigned long rate)
+static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
+ unsigned long rate)
{
u64 divider = parent_rate * 2;
+ unsigned max_divider = 1 << divider_bits;
divider += rate - 1;
do_div(divider, rate);
if ((s64)divider - 2 < 0)
return 0;
- if ((s64)divider - 2 > 255)
+ if ((s64)divider - 2 >= max_divider)
return -1;
return divider - 2;
* required child clock rate. This function assumes that a second-stage
* divisor is available which can divide by powers of 2 from 1 to 256.
*
+ * @param divider_bits number of divider bits (8 or 16)
* @param parent_rate clock rate of parent clock in Hz
* @param rate required clock rate for this clock
* @param extra_div value for the second-stage divisor (not set if this
* @return divider which should be used, or -1 if nothing is valid
*
*/
-static int find_best_divider(unsigned long parent_rate, unsigned long rate,
- int *extra_div)
+static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
+ unsigned long rate, int *extra_div)
{
int shift;
int best_divider = -1;
/* try dividers from 1 to 256 and find closest match */
for (shift = 0; shift <= 8 && best_error > 0; shift++) {
unsigned divided_parent = parent_rate >> shift;
- int divider = clk_div7_1_get_divider(divided_parent, rate);
+ int divider = clk_get_divider(divider_bits, divided_parent,
+ rate);
unsigned effective_rate = get_rate_from_divider(divided_parent,
divider);
int error = rate - effective_rate;
* @param periph_id peripheral to start
* @param source PLL id of required parent clock
* @param mux_bits Set to number of bits in mux register: 2 or 4
+ * @param divider_bits Set to number of divider bits (8 or 16)
* @return mux value (0-4, or -1 if not found)
*/
static int get_periph_clock_source(enum periph_id periph_id,
- enum clock_id parent, int *mux_bits)
+ enum clock_id parent, int *mux_bits, int *divider_bits)
{
enum clock_type_id type;
enum periphc_internal_id internal_id;
type = clock_periph_type[internal_id];
assert(clock_type_id_isvalid(type));
- /* Special case here for the clock with a 4-bit source mux */
+ /*
+ * Special cases here for the clock with a 4-bit source mux and I2C
+ * with its 16-bit divisor
+ */
if (type == CLOCK_TYPE_PCXTS)
*mux_bits = 4;
else
*mux_bits = 2;
+ if (type == CLOCK_TYPE_PCMT16)
+ *divider_bits = 16;
+ else
+ *divider_bits = 8;
for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
if (clock_source[type][mux] == parent)
* Adjust peripheral PLL to use the given divider and source.
*
* @param periph_id peripheral to adjust
- * @param parent Required parent clock (for source mux)
- * @param divider Required divider in 7.1 format
+ * @param source Source number (0-3 or 0-7)
+ * @param mux_bits Number of mux bits (2 or 4)
+ * @param divider Required divider in 7.1 or 15.1 format
* @return 0 if ok, -1 on error (requesting a parent clock which is not valid
* for this peripheral)
*/
-static int adjust_periph_pll(enum periph_id periph_id,
- enum clock_id parent, unsigned divider)
+static int adjust_periph_pll(enum periph_id periph_id, int source,
+ int mux_bits, unsigned divider)
{
u32 *reg = get_periph_source_reg(periph_id);
- unsigned source;
- int mux_bits;
clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
divider << OUT_CLK_DIVISOR_SHIFT);
udelay(1);
/* work out the source clock and set it */
- source = get_periph_clock_source(periph_id, parent, &mux_bits);
if (source < 0)
return -1;
if (mux_bits == 4) {
enum clock_id parent, unsigned rate, int *extra_div)
{
unsigned effective_rate;
+ int mux_bits, divider_bits, source;
int divider;
+ /* work out the source clock and set it */
+ source = get_periph_clock_source(periph_id, parent, &mux_bits,
+ ÷r_bits);
+
if (extra_div)
- divider = find_best_divider(pll_rate[parent], rate, extra_div);
+ divider = find_best_divider(divider_bits, pll_rate[parent],
+ rate, extra_div);
else
- divider = clk_div7_1_get_divider(pll_rate[parent], rate);
+ divider = clk_get_divider(divider_bits, pll_rate[parent],
+ rate);
assert(divider >= 0);
- if (adjust_periph_pll(periph_id, parent, divider))
+ if (adjust_periph_pll(periph_id, source, mux_bits, divider))
return -1U;
debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
get_periph_source_reg(periph_id),
reset_set_enable(periph_id, 0);
}
+#ifdef CONFIG_OF_CONTROL
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id Clock ID according to tegra2 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+static enum periph_id clk_id_to_periph_id(int clk_id)
+{
+ if (clk_id > 95)
+ return PERIPH_ID_NONE;
+
+ switch (clk_id) {
+ case 1:
+ case 2:
+ case 7:
+ case 10:
+ case 20:
+ case 30:
+ case 35:
+ case 49:
+ case 56:
+ case 74:
+ case 76:
+ case 77:
+ case 78:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 91:
+ case 95:
+ return PERIPH_ID_NONE;
+ default:
+ return clk_id;
+ }
+}
+
+int clock_decode_periph_id(const void *blob, int node)
+{
+ enum periph_id id;
+ u32 cell[2];
+ int err;
+
+ err = fdtdec_get_int_array(blob, node, "clocks", cell,
+ ARRAY_SIZE(cell));
+ if (err)
+ return -1;
+ id = clk_id_to_periph_id(cell[1]);
+ assert(clock_periph_id_isvalid(id));
+ return id;
+}
+#endif /* CONFIG_OF_CONTROL */
+
int clock_verify(void)
{
struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
endif
USE_PRIVATE_LIBGCC = yes
+
+CONFIG_ARCH_DEVICE_TREE := tegra20
--- /dev/null
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010,2011 NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/uart.h>
+#include <asm/arch/usb.h>
+#include <libfdt.h>
+#include <fdtdec.h>
+
+enum {
+ USB_PORTS_MAX = 4, /* Maximum ports we allow */
+};
+
+/* Parameters we need for USB */
+enum {
+ PARAM_DIVN, /* PLL FEEDBACK DIVIDer */
+ PARAM_DIVM, /* PLL INPUT DIVIDER */
+ PARAM_DIVP, /* POST DIVIDER (2^N) */
+ PARAM_CPCON, /* BASE PLLC CHARGE Pump setup ctrl */
+ PARAM_LFCON, /* BASE PLLC LOOP FILter setup ctrl */
+ PARAM_ENABLE_DELAY_COUNT, /* PLL-U Enable Delay Count */
+ PARAM_STABLE_COUNT, /* PLL-U STABLE count */
+ PARAM_ACTIVE_DELAY_COUNT, /* PLL-U Active delay count */
+ PARAM_XTAL_FREQ_COUNT, /* PLL-U XTAL frequency count */
+ PARAM_DEBOUNCE_A_TIME, /* 10MS DELAY for BIAS_DEBOUNCE_A */
+ PARAM_BIAS_TIME, /* 20US DELAY AFter bias cell op */
+
+ PARAM_COUNT
+};
+
+/* Possible port types (dual role mode) */
+enum dr_mode {
+ DR_MODE_NONE = 0,
+ DR_MODE_HOST, /* supports host operation */
+ DR_MODE_DEVICE, /* supports device operation */
+ DR_MODE_OTG, /* supports both */
+};
+
+/* Information about a USB port */
+struct fdt_usb {
+ struct usb_ctlr *reg; /* address of registers in physical memory */
+ unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */
+ unsigned enabled:1; /* 1 to enable, 0 to disable */
+ unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
+ enum dr_mode dr_mode; /* dual role mode */
+ enum periph_id periph_id;/* peripheral id */
+ struct fdt_gpio_state vbus_gpio; /* GPIO for vbus enable */
+};
+
+static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */
+static unsigned port_count; /* Number of available ports */
+static int port_current; /* Current port (-1 = none) */
+
+/*
+ * This table has USB timing parameters for each Oscillator frequency we
+ * support. There are four sets of values:
+ *
+ * 1. PLLU configuration information (reference clock is osc/clk_m and
+ * PLLU-FOs are fixed at 12MHz/60MHz/480MHz).
+ *
+ * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz
+ * ----------------------------------------------------------------------
+ * DIVN 960 (0x3c0) 200 (0c8) 960 (3c0h) 960 (3c0)
+ * DIVM 13 (0d) 4 (04) 12 (0c) 26 (1a)
+ * Filter frequency (MHz) 1 4.8 6 2
+ * CPCON 1100b 0011b 1100b 1100b
+ * LFCON0 0 0 0 0
+ *
+ * 2. PLL CONFIGURATION & PARAMETERS for different clock generators:
+ *
+ * Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz
+ * ---------------------------------------------------------------------------
+ * PLLU_ENABLE_DLY_COUNT 02 (0x02) 03 (03) 02 (02) 04 (04)
+ * PLLU_STABLE_COUNT 51 (33) 75 (4B) 47 (2F) 102 (66)
+ * PLL_ACTIVE_DLY_COUNT 05 (05) 06 (06) 04 (04) 09 (09)
+ * XTAL_FREQ_COUNT 127 (7F) 187 (BB) 118 (76) 254 (FE)
+ *
+ * 3. Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and
+ * SessEnd. Each of these signals have their own debouncer and for each of
+ * those one out of two debouncing times can be chosen (BIAS_DEBOUNCE_A or
+ * BIAS_DEBOUNCE_B).
+ *
+ * The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows:
+ * 0xffff -> No debouncing at all
+ * <n> ms = <n> *1000 / (1/19.2MHz) / 4
+ *
+ * So to program a 1 ms debounce for BIAS_DEBOUNCE_A, we have:
+ * BIAS_DEBOUNCE_A[15:0] = 1000 * 19.2 / 4 = 4800 = 0x12c0
+ *
+ * We need to use only DebounceA for BOOTROM. We don't need the DebounceB
+ * values, so we can keep those to default.
+ *
+ * 4. The 20 microsecond delay after bias cell operation.
+ */
+static const unsigned usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
+ /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */
+ { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 },
+ { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 },
+ { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 },
+ { 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }
+};
+
+/* UTMIP Idle Wait Delay */
+static const u8 utmip_idle_wait_delay = 17;
+
+/* UTMIP Elastic limit */
+static const u8 utmip_elastic_limit = 16;
+
+/* UTMIP High Speed Sync Start Delay */
+static const u8 utmip_hs_sync_start_delay = 9;
+
+/* Put the port into host mode (this only works for OTG ports) */
+static void set_host_mode(struct fdt_usb *config)
+{
+ if (config->dr_mode == DR_MODE_OTG) {
+ /* Check whether remote host from USB1 is driving VBus */
+ if (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)
+ return;
+
+ /*
+ * If not driving, we set the GPIO to enable VBUS. We assume
+ * that the pinmux is set up correctly for this.
+ */
+ if (fdt_gpio_isvalid(&config->vbus_gpio)) {
+ fdtdec_setup_gpio(&config->vbus_gpio);
+ gpio_direction_output(config->vbus_gpio.gpio, 1);
+ debug("set_host_mode: GPIO %d high\n",
+ config->vbus_gpio.gpio);
+ }
+ }
+}
+
+void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
+{
+ /* Reset the USB controller with 2us delay */
+ reset_periph(config->periph_id, 2);
+
+ /*
+ * Set USB1_NO_LEGACY_MODE to 1, Registers are accessible under
+ * base address
+ */
+ if (config->has_legacy_mode)
+ setbits_le32(&usbctlr->usb1_legacy_ctrl, USB1_NO_LEGACY_MODE);
+
+ /* Put UTMIP1/3 in reset */
+ setbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);
+
+ /* Enable the UTMIP PHY */
+ if (config->utmi)
+ setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB);
+
+ /*
+ * TODO: where do we take the USB1 out of reset? The old code would
+ * take USB3 out of reset, but not USB1. This code doesn't do either.
+ */
+}
+
+/* set up the USB controller with the parameters provided */
+static int init_usb_controller(struct fdt_usb *config,
+ struct usb_ctlr *usbctlr, const u32 timing[])
+{
+ u32 val;
+ int loop_count;
+
+ clock_enable(config->periph_id);
+
+ /* Reset the usb controller */
+ usbf_reset_controller(config, usbctlr);
+
+ /* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */
+ clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
+
+ /* Follow the crystal clock disable by >100ns delay */
+ udelay(1);
+
+ /*
+ * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP
+ * mux must be switched to actually use a_sess_vld threshold.
+ */
+ if (fdt_gpio_isvalid(&config->vbus_gpio)) {
+ clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
+ VBUS_SENSE_CTL_MASK,
+ VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
+ }
+
+ /*
+ * PLL Delay CONFIGURATION settings. The following parameters control
+ * the bring up of the plls.
+ */
+ val = readl(&usbctlr->utmip_misc_cfg1);
+ clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
+ timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
+ timing[PARAM_ACTIVE_DELAY_COUNT] <<
+ UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
+ writel(val, &usbctlr->utmip_misc_cfg1);
+
+ /* Set PLL enable delay count and crystal frequency count */
+ val = readl(&usbctlr->utmip_pll_cfg1);
+ clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
+ timing[PARAM_ENABLE_DELAY_COUNT] <<
+ UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
+ timing[PARAM_XTAL_FREQ_COUNT] <<
+ UTMIP_XTAL_FREQ_COUNT_SHIFT);
+ writel(val, &usbctlr->utmip_pll_cfg1);
+
+ /* Setting the tracking length time */
+ clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
+ UTMIP_BIAS_PDTRK_COUNT_MASK,
+ timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT);
+
+ /* Program debounce time for VBUS to become valid */
+ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
+ UTMIP_DEBOUNCE_CFG0_MASK,
+ timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);
+
+ setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);
+
+ /* Disable battery charge enabling bit */
+ setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG);
+
+ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE);
+ setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);
+
+ /*
+ * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
+ * Setting these fields, together with default values of the
+ * other fields, results in programming the registers below as
+ * follows:
+ * UTMIP_HSRX_CFG0 = 0x9168c000
+ * UTMIP_HSRX_CFG1 = 0x13
+ */
+
+ /* Set PLL enable delay count and Crystal frequency count */
+ val = readl(&usbctlr->utmip_hsrx_cfg0);
+ clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK,
+ utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK,
+ utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT);
+ writel(val, &usbctlr->utmip_hsrx_cfg0);
+
+ /* Configure the UTMIP_HS_SYNC_START_DLY */
+ clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1,
+ UTMIP_HS_SYNC_START_DLY_MASK,
+ utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT);
+
+ /* Preceed the crystal clock disable by >100ns delay. */
+ udelay(1);
+
+ /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */
+ setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
+
+ /* Finished the per-controller init. */
+
+ /* De-assert UTMIP_RESET to bring out of reset. */
+ clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);
+
+ /* Wait for the phy clock to become valid in 100 ms */
+ for (loop_count = 100000; loop_count != 0; loop_count--) {
+ if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
+ break;
+ udelay(1);
+ }
+ if (loop_count == 100000)
+ return -1;
+
+ return 0;
+}
+
+static void power_up_port(struct usb_ctlr *usbctlr)
+{
+ /* Deassert power down state */
+ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN |
+ UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN);
+ clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN |
+ UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN);
+}
+
+static void config_clock(const u32 timing[])
+{
+ clock_start_pll(CLOCK_ID_USB,
+ timing[PARAM_DIVM], timing[PARAM_DIVN], timing[PARAM_DIVP],
+ timing[PARAM_CPCON], timing[PARAM_LFCON]);
+}
+
+/**
+ * Add a new USB port to the list of available ports.
+ *
+ * @param config USB port configuration
+ * @return 0 if ok, -1 if error (too many ports)
+ */
+static int add_port(struct fdt_usb *config, const u32 timing[])
+{
+ struct usb_ctlr *usbctlr = config->reg;
+
+ if (port_count == USB_PORTS_MAX) {
+ debug("tegrausb: Cannot register more than %d ports\n",
+ USB_PORTS_MAX);
+ return -1;
+ }
+ if (init_usb_controller(config, usbctlr, timing)) {
+ debug("tegrausb: Cannot init port\n");
+ return -1;
+ }
+ if (config->utmi) {
+ /* Disable ICUSB FS/LS transceiver */
+ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
+
+ /* Select UTMI parallel interface */
+ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
+ PTS_UTMI << PTS_SHIFT);
+ clrbits_le32(&usbctlr->port_sc1, STS);
+ power_up_port(usbctlr);
+ }
+ port[port_count++] = *config;
+
+ return 0;
+}
+
+int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor)
+{
+ struct usb_ctlr *usbctlr;
+
+ if (portnum >= port_count)
+ return -1;
+ tegrausb_stop_port();
+ set_host_mode(&port[portnum]);
+
+ usbctlr = port[portnum].reg;
+ *hccr = (u32)&usbctlr->cap_length;
+ *hcor = (u32)&usbctlr->usb_cmd;
+ port_current = portnum;
+ return 0;
+}
+
+int tegrausb_stop_port(void)
+{
+ struct usb_ctlr *usbctlr;
+
+ if (port_current == -1)
+ return -1;
+
+ usbctlr = port[port_current].reg;
+
+ /* Stop controller */
+ writel(0, &usbctlr->usb_cmd);
+ udelay(1000);
+
+ /* Initiate controller reset */
+ writel(2, &usbctlr->usb_cmd);
+ udelay(1000);
+ port_current = -1;
+ return 0;
+}
+
+int fdt_decode_usb(const void *blob, int node, unsigned osc_frequency_mhz,
+ struct fdt_usb *config)
+{
+ const char *phy, *mode;
+
+ config->reg = (struct usb_ctlr *)fdtdec_get_addr(blob, node, "reg");
+ mode = fdt_getprop(blob, node, "dr_mode", NULL);
+ if (mode) {
+ if (0 == strcmp(mode, "host"))
+ config->dr_mode = DR_MODE_HOST;
+ else if (0 == strcmp(mode, "peripheral"))
+ config->dr_mode = DR_MODE_DEVICE;
+ else if (0 == strcmp(mode, "otg"))
+ config->dr_mode = DR_MODE_OTG;
+ else {
+ debug("%s: Cannot decode dr_mode '%s'\n", __func__,
+ mode);
+ return -FDT_ERR_NOTFOUND;
+ }
+ } else {
+ config->dr_mode = DR_MODE_HOST;
+ }
+
+ phy = fdt_getprop(blob, node, "phy_type", NULL);
+ config->utmi = phy && 0 == strcmp("utmi", phy);
+ config->enabled = fdtdec_get_is_enabled(blob, node);
+ config->has_legacy_mode = fdtdec_get_bool(blob, node,
+ "nvidia,has-legacy-mode");
+ config->periph_id = clock_decode_periph_id(blob, node);
+ if (config->periph_id == PERIPH_ID_NONE) {
+ debug("%s: Missing/invalid peripheral ID\n", __func__);
+ return -FDT_ERR_NOTFOUND;
+ }
+ fdtdec_decode_gpio(blob, node, "nvidia,vbus-gpio", &config->vbus_gpio);
+ debug("enabled=%d, legacy_mode=%d, utmi=%d, periph_id=%d, vbus=%d, "
+ "dr_mode=%d\n", config->enabled, config->has_legacy_mode,
+ config->utmi, config->periph_id, config->vbus_gpio.gpio,
+ config->dr_mode);
+
+ return 0;
+}
+
+int board_usb_init(const void *blob)
+{
+ struct fdt_usb config;
+ unsigned osc_freq = clock_get_rate(CLOCK_ID_OSC);
+ enum clock_osc_freq freq;
+ int node_list[USB_PORTS_MAX];
+ int node, count, i;
+
+ /* Set up the USB clocks correctly based on our oscillator frequency */
+ freq = clock_get_osc_freq();
+ config_clock(usb_pll[freq]);
+
+ /* count may return <0 on error */
+ count = fdtdec_find_aliases_for_id(blob, "usb",
+ COMPAT_NVIDIA_TEGRA20_USB, node_list, USB_PORTS_MAX);
+ for (i = 0; i < count; i++) {
+ debug("USB %d: ", i);
+ node = node_list[i];
+ if (!node)
+ continue;
+ if (fdt_decode_usb(blob, node, osc_freq, &config)) {
+ debug("Cannot decode USB node %s\n",
+ fdt_get_name(blob, node, NULL));
+ return -1;
+ }
+
+ if (add_port(&config, usb_pll[freq]))
+ return -1;
+ set_host_mode(&config);
+ }
+ port_current = -1;
+
+ return 0;
+}
PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
+PLATFORM_LDFLAGS += -EB
+USE_PRIVATE_LIBGCC = yes
+
# -fdata-sections triggers "section .bss overlaps section .rel.dyn" linker error
PLATFORM_RELFLAGS += -ffunction-sections
LDFLAGS_u-boot += --gc-sections
/*
* Initialize Control plane
*/
- if (ixEthDBInit() != IX_ETH_ACC_SUCCESS)
+ if (ixEthDBInit() != IX_ETH_DB_SUCCESS)
{
IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0);
IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
{
IxNpeMhMessage message;
- IxOsalMutex *ackPortAddressLock;
IX_STATUS result;
/* use this macro instead CHECK_PORT
return IX_ETH_DB_PORT_UNINITIALIZED;
}
- ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;
-
/* Operation stops here when Ethernet Learning is not enabled */
if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
{
#ifndef NDEBUG
UINT8 i = 0;
- IxQMgrQInfo *q;
UINT32 intEnableRegVal = 0;
printf ("Livelock statistics are printed on the fly.\n");
for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)
{
- q = &dispatchQInfo[i];
-
if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER)
{
printf (" %2d ", i);
+++ /dev/null
-/*
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/lh7a40x/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
while (get_ticks() < tmp) /* loop till event */
/*NOP*/;
}
+
+ulong get_tbclk(void)
+{
+ return TIMER_FREQ_HZ;
+}
+++ /dev/null
-/*
- * (C) Copyright 2000-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/pxa/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- . = ALIGN(4096);
-
- .mmutable : {
- *(.mmutable)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
#endif
writel(readl(UHCHR) | UHCHR_FHR, UHCHR);
- wait_ms(11);
+ mdelay(11);
writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR);
writel(readl(UHCHR) | UHCHR_FSBIR, UHCHR);
+++ /dev/null
-/*
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/s3c44b0/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
+++ /dev/null
-/*
- * (C) Copyright 2003-2004
- * MontaVista Software, Inc.
- *
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.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
- */
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- arch/arm/cpu/sa1100/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data)
- }
-
- . = ALIGN(4);
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- _end = .;
-
- .bss __rel_dyn_start (OVERLAY) : {
- __bss_start = .;
- *(.bss)
- . = ALIGN(4);
- __bss_end__ = .;
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
-}
/*
- * January 2004 - Changed to support H4 device
* Copyright (c) 2004-2008 Texas Instruments
*
* (C) Copyright 2002
. = 0x00000000;
. = ALIGN(4);
- .text :
+ .text :
{
- arch/arm/cpu/armv7/start.o (.text)
+ __image_copy_start = .;
+ CPUDIR/start.o (.text)
*(.text)
}
_end = .;
+ /*
+ * Deprecated: this MMU section is used by pxa at present but
+ * should not be used by new boards/CPUs.
+ */
+ . = ALIGN(4096);
+ .mmutable : {
+ *(.mmutable)
+ }
+
.bss __rel_dyn_start (OVERLAY) : {
__bss_start = .;
*(.bss)
--- /dev/null
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value. The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0>; };
+};
--- /dev/null
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra20";
+ interrupt-parent = <&intc>;
+
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra20-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc: clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+ };
+
+ intc: interrupt-controller@50041000 {
+ compatible = "nvidia,tegra20-gic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = < 0x50041000 0x1000 >,
+ < 0x50040100 0x0100 >;
+ };
+
+ i2c@7000c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000C000 0x100>;
+ interrupts = < 70 >;
+ /* PERIPH_ID_I2C1, PLL_P_OUT3 */
+ clocks = <&tegra_car 12>, <&tegra_car 124>;
+ };
+
+ i2c@7000c400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000C400 0x100>;
+ interrupts = < 116 >;
+ /* PERIPH_ID_I2C2, PLL_P_OUT3 */
+ clocks = <&tegra_car 54>, <&tegra_car 124>;
+ };
+
+ i2c@7000c500 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000C500 0x100>;
+ interrupts = < 124 >;
+ /* PERIPH_ID_I2C3, PLL_P_OUT3 */
+ clocks = <&tegra_car 67>, <&tegra_car 124>;
+ };
+
+ i2c@7000d000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2c-dvc";
+ reg = <0x7000D000 0x200>;
+ interrupts = < 85 >;
+ /* PERIPH_ID_DVC_I2C, PLL_P_OUT3 */
+ clocks = <&tegra_car 47>, <&tegra_car 124>;
+ };
+
+ i2s@70002800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002800 0x200>;
+ interrupts = < 45 >;
+ dma-channel = < 2 >;
+ };
+
+ i2s@70002a00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2s";
+ reg = <0x70002a00 0x200>;
+ interrupts = < 35 >;
+ dma-channel = < 1 >;
+ };
+
+ das@70000c00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-das";
+ reg = <0x70000c00 0x80>;
+ };
+
+ gpio: gpio@6000d000 {
+ compatible = "nvidia,tegra20-gpio";
+ reg = < 0x6000d000 0x1000 >;
+ interrupts = < 64 65 66 67 87 119 121 >;
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+
+ pinmux: pinmux@70000000 {
+ compatible = "nvidia,tegra20-pinmux";
+ reg = < 0x70000014 0x10 /* Tri-state registers */
+ 0x70000080 0x20 /* Mux registers */
+ 0x700000a0 0x14 /* Pull-up/down registers */
+ 0x70000868 0xa8 >; /* Pad control registers */
+ };
+
+ serial@70006000 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006000 0x40>;
+ reg-shift = <2>;
+ interrupts = < 68 >;
+ };
+
+ serial@70006040 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006040 0x40>;
+ reg-shift = <2>;
+ interrupts = < 69 >;
+ };
+
+ serial@70006200 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006200 0x100>;
+ reg-shift = <2>;
+ interrupts = < 78 >;
+ };
+
+ serial@70006300 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006300 0x100>;
+ reg-shift = <2>;
+ interrupts = < 122 >;
+ };
+
+ serial@70006400 {
+ compatible = "nvidia,tegra20-uart";
+ reg = <0x70006400 0x100>;
+ reg-shift = <2>;
+ interrupts = < 123 >;
+ };
+
+ sdhci@c8000000 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000000 0x200>;
+ interrupts = < 46 >;
+ };
+
+ sdhci@c8000200 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000200 0x200>;
+ interrupts = < 47 >;
+ };
+
+ sdhci@c8000400 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000400 0x200>;
+ interrupts = < 51 >;
+ };
+
+ sdhci@c8000600 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000600 0x200>;
+ interrupts = < 63 >;
+ };
+
+ usb@c5000000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5000000 0x4000>;
+ interrupts = < 52 >;
+ phy_type = "utmi";
+ clocks = <&tegra_car 22>; /* PERIPH_ID_USBD */
+ nvidia,has-legacy-mode;
+ };
+
+ usb@c5004000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5004000 0x4000>;
+ interrupts = < 53 >;
+ phy_type = "ulpi";
+ clocks = <&tegra_car 58>; /* PERIPH_ID_USB2 */
+ };
+
+ usb@c5008000 {
+ compatible = "nvidia,tegra20-ehci", "usb-ehci";
+ reg = <0xc5008000 0x4000>;
+ interrupts = < 129 >;
+ phy_type = "utmi";
+ clocks = <&tegra_car 59>; /* PERIPH_ID_USB3 */
+ };
+
+};
#define CMD_FORCE 0x00
#define CMD_DELAY 0x00
-#define EMIF_READ_LATENCY 0x04
+#define EMIF_READ_LATENCY 0x05
#define EMIF_TIM1 0x0666B3D6
#define EMIF_TIM2 0x143731DA
#define EMIF_TIM3 0x00000347
#define SSP2_APBCLK 0x01
#define SSP2_FNCLK 0x02
+/* USB Clock/reset control bits */
+#define USB_SPH_AXICLK_EN 0x10
+#define USB_SPH_AXI_RST 0x02
+
+/* MPMU Clocks */
+#define APB2_26M_EN (1 << 20)
+#define AP_26M (1 << 4)
+
/* Register Base Addresses */
#define ARMD1_DRAM_BASE 0xB0000000
#define ARMD1_FEC_BASE 0xC0800000
#define ARMD1_SSP5_BASE 0xD4021000
#define ARMD1_UART3_BASE 0xD4026000
#define ARMD1_MPMU_BASE 0xD4050000
+#define ARMD1_USB_HOST_BASE 0xD4209000
#define ARMD1_APMU_BASE 0xD4282800
#define ARMD1_CPU_BASE 0xD4282C00
--- /dev/null
+/*
+ * (C) Copyright 2012
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __UTMI_ARMADA100__
+#define __UTMI_ARMADA100__
+
+#define UTMI_PHY_BASE 0xD4206000
+
+/* utmi_ctrl - bits */
+#define INPKT_DELAY_SOF (1 << 28)
+#define PLL_PWR_UP 2
+#define PHY_PWR_UP 1
+
+/* utmi_pll - bits */
+#define PLL_FBDIV_MASK 0x00000FF0
+#define PLL_FBDIV 4
+#define PLL_REFDIV_MASK 0x0000000F
+#define PLL_REFDIV 0
+#define PLL_READY 0x800000
+#define VCOCAL_START (1 << 21)
+
+#define N_DIVIDER 0xEE
+#define M_DIVIDER 0x0B
+
+/* utmi_tx - bits */
+#define CK60_PHSEL 17
+#define PHSEL_VAL 0x4
+#define RCAL_START (1 << 12)
+
+/*
+ * USB PHY registers
+ * Refer Datasheet Appendix A.21
+ */
+struct armd1usb_phy_reg {
+ u32 utmi_rev; /* USB PHY Revision */
+ u32 utmi_ctrl; /* USB PHY Control register */
+ u32 utmi_pll; /* PLL register */
+ u32 utmi_tx; /* Tx register */
+ u32 utmi_rx; /* Rx register */
+ u32 utmi_ivref; /* IVREF register */
+ u32 utmi_tst_g0; /* Test group 0 register */
+ u32 utmi_tst_g1; /* Test group 1 register */
+ u32 utmi_tst_g2; /* Test group 2 register */
+ u32 utmi_tst_g3; /* Test group 3 register */
+ u32 utmi_tst_g4; /* Test group 4 register */
+ u32 utmi_tst_g5; /* Test group 5 register */
+ u32 utmi_reserve; /* Reserve Register */
+ u32 utmi_usb_int; /* USB interuppt register */
+ u32 utmi_dbg_ctl; /* Debug control register */
+ u32 utmi_otg_addon; /* OTG addon register */
+};
+
+int utmi_init(void);
+
+#endif /* __UTMI_ARMADA100__ */
#define __DMC_H__
#ifndef __ASSEMBLY__
+struct exynos4_dmc {
+ unsigned int concontrol;
+ unsigned int memcontrol;
+ unsigned int memconfig0;
+ unsigned int memconfig1;
+ unsigned int directcmd;
+ unsigned int prechconfig;
+ unsigned int phycontrol0;
+ unsigned int phycontrol1;
+ unsigned int phycontrol2;
+ unsigned int phycontrol3;
+ unsigned int pwrdnconfig;
+ unsigned char res1[0x4];
+ unsigned int timingref;
+ unsigned int timingrow;
+ unsigned int timingdata;
+ unsigned int timingpower;
+ unsigned int phystatus;
+ unsigned int phyzqcontrol;
+ unsigned int chip0status;
+ unsigned int chip1status;
+ unsigned int arefstatus;
+ unsigned int mrstatus;
+ unsigned int phytest0;
+ unsigned int phytest1;
+ unsigned int qoscontrol0;
+ unsigned int qosconfig0;
+ unsigned int qoscontrol1;
+ unsigned int qosconfig1;
+ unsigned int qoscontrol2;
+ unsigned int qosconfig2;
+ unsigned int qoscontrol3;
+ unsigned int qosconfig3;
+ unsigned int qoscontrol4;
+ unsigned int qosconfig4;
+ unsigned int qoscontrol5;
+ unsigned int qosconfig5;
+ unsigned int qoscontrol6;
+ unsigned int qosconfig6;
+ unsigned int qoscontrol7;
+ unsigned int qosconfig7;
+ unsigned int qoscontrol8;
+ unsigned int qosconfig8;
+ unsigned int qoscontrol9;
+ unsigned int qosconfig9;
+ unsigned int qoscontrol10;
+ unsigned int qosconfig10;
+ unsigned int qoscontrol11;
+ unsigned int qosconfig11;
+ unsigned int qoscontrol12;
+ unsigned int qosconfig12;
+ unsigned int qoscontrol13;
+ unsigned int qosconfig13;
+ unsigned int qoscontrol14;
+ unsigned int qosconfig14;
+ unsigned int qoscontrol15;
+ unsigned int qosconfig15;
+ unsigned int qostimeout0;
+ unsigned int qostimeout1;
+ unsigned char res2[0x8];
+ unsigned int ivcontrol;
+ unsigned char res3[0x8];
+ unsigned int perevconfig;
+ unsigned char res4[0xDF00];
+ unsigned int pmnc_ppc_a;
+ unsigned char res5[0xC];
+ unsigned int cntens_ppc_a;
+ unsigned char res6[0xC];
+ unsigned int cntenc_ppc_a;
+ unsigned char res7[0xC];
+ unsigned int intens_ppc_a;
+ unsigned char res8[0xC];
+ unsigned int intenc_ppc_a;
+ unsigned char res9[0xC];
+ unsigned int flag_ppc_a;
+ unsigned char res10[0xAC];
+ unsigned int ccnt_ppc_a;
+ unsigned char res11[0xC];
+ unsigned int pmcnt0_ppc_a;
+ unsigned char res12[0xC];
+ unsigned int pmcnt1_ppc_a;
+ unsigned char res13[0xC];
+ unsigned int pmcnt2_ppc_a;
+ unsigned char res14[0xC];
+ unsigned int pmcnt3_ppc_a;
+ unsigned char res15[0xEBC];
+ unsigned int pmnc_ppc_m;
+ unsigned char res16[0xC];
+ unsigned int cntens_ppc_m;
+ unsigned char res17[0xC];
+ unsigned int cntenc_ppc_m;
+ unsigned char res18[0xC];
+ unsigned int intens_ppc_m;
+ unsigned char res19[0xC];
+ unsigned int intenc_ppc_m;
+ unsigned char res20[0xC];
+ unsigned int flag_ppc_m;
+ unsigned char res21[0xAC];
+ unsigned int ccnt_ppc_m;
+ unsigned char res22[0xC];
+ unsigned int pmcnt0_ppc_m;
+ unsigned char res23[0xC];
+ unsigned int pmcnt1_ppc_m;
+ unsigned char res24[0xC];
+ unsigned int pmcnt2_ppc_m;
+ unsigned char res25[0xC];
+ unsigned int pmcnt3_ppc_m;
+};
+
struct exynos5_dmc {
unsigned int concontrol;
unsigned int memcontrol;
#define IXP425_GPIO_GPCLKR IXP425_GPIO_REG(IXP425_GPIO_GPCLKR_OFFSET)
#define IXP425_GPIO_GPDBSELR IXP425_GPIO_REG(IXP425_GPIO_GPDBSELR_OFFSET)
+#define IXP425_GPIO_GPITR(line) (((line) >= 8) ? \
+ IXP425_GPIO_GPIT2R : IXP425_GPIO_GPIT1R)
+
/*
* Macros to make it easy to access the GPIO registers
*/
#define GPIO_OUTPUT_DISABLE(line) *IXP425_GPIO_GPOER |= (1 << (line))
#define GPIO_OUTPUT_SET(line) *IXP425_GPIO_GPOUTR |= (1 << (line))
#define GPIO_OUTPUT_CLEAR(line) *IXP425_GPIO_GPOUTR &= ~(1 << (line))
-#define GPIO_INT_ACT_LOW_SET(line) *IXP425_GPIO_GPIT1R = \
- (*IXP425_GPIO_GPIT1R & ~(0x7 << (line * 3))) | (0x1 << (line * 3))
+#define GPIO_INT_ACT_LOW_SET(line) \
+ *IXP425_GPIO_GPITR(line) = \
+ (*IXP425_GPIO_GPITR(line) & \
+ ~(0x7 << (((line) & 0x7) * 3))) | \
+ (0x1 << (((line) & 0x7) * 3)) \
/*
* Constants to make it easy to access Timer Control/Status registers
#include <asm/arch/regs-base.h>
#include <asm/arch/regs-bch.h>
#include <asm/arch/regs-clkctrl.h>
+#include <asm/arch/regs-digctl.h>
#include <asm/arch/regs-gpmi.h>
#include <asm/arch/regs-i2c.h>
#include <asm/arch/regs-ocotp.h>
#ifndef __ASSEMBLY__
struct mx28_apbh_regs {
- mx28_reg(hw_apbh_ctrl0)
- mx28_reg(hw_apbh_ctrl1)
- mx28_reg(hw_apbh_ctrl2)
- mx28_reg(hw_apbh_channel_ctrl)
- mx28_reg(hw_apbh_devsel)
- mx28_reg(hw_apbh_dma_burst_size)
- mx28_reg(hw_apbh_debug)
+ mx28_reg_32(hw_apbh_ctrl0)
+ mx28_reg_32(hw_apbh_ctrl1)
+ mx28_reg_32(hw_apbh_ctrl2)
+ mx28_reg_32(hw_apbh_channel_ctrl)
+ mx28_reg_32(hw_apbh_devsel)
+ mx28_reg_32(hw_apbh_dma_burst_size)
+ mx28_reg_32(hw_apbh_debug)
uint32_t reserved[36];
union {
struct {
- mx28_reg(hw_apbh_ch_curcmdar)
- mx28_reg(hw_apbh_ch_nxtcmdar)
- mx28_reg(hw_apbh_ch_cmd)
- mx28_reg(hw_apbh_ch_bar)
- mx28_reg(hw_apbh_ch_sema)
- mx28_reg(hw_apbh_ch_debug1)
- mx28_reg(hw_apbh_ch_debug2)
+ mx28_reg_32(hw_apbh_ch_curcmdar)
+ mx28_reg_32(hw_apbh_ch_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch_cmd)
+ mx28_reg_32(hw_apbh_ch_bar)
+ mx28_reg_32(hw_apbh_ch_sema)
+ mx28_reg_32(hw_apbh_ch_debug1)
+ mx28_reg_32(hw_apbh_ch_debug2)
} ch[16];
struct {
- mx28_reg(hw_apbh_ch0_curcmdar)
- mx28_reg(hw_apbh_ch0_nxtcmdar)
- mx28_reg(hw_apbh_ch0_cmd)
- mx28_reg(hw_apbh_ch0_bar)
- mx28_reg(hw_apbh_ch0_sema)
- mx28_reg(hw_apbh_ch0_debug1)
- mx28_reg(hw_apbh_ch0_debug2)
- mx28_reg(hw_apbh_ch1_curcmdar)
- mx28_reg(hw_apbh_ch1_nxtcmdar)
- mx28_reg(hw_apbh_ch1_cmd)
- mx28_reg(hw_apbh_ch1_bar)
- mx28_reg(hw_apbh_ch1_sema)
- mx28_reg(hw_apbh_ch1_debug1)
- mx28_reg(hw_apbh_ch1_debug2)
- mx28_reg(hw_apbh_ch2_curcmdar)
- mx28_reg(hw_apbh_ch2_nxtcmdar)
- mx28_reg(hw_apbh_ch2_cmd)
- mx28_reg(hw_apbh_ch2_bar)
- mx28_reg(hw_apbh_ch2_sema)
- mx28_reg(hw_apbh_ch2_debug1)
- mx28_reg(hw_apbh_ch2_debug2)
- mx28_reg(hw_apbh_ch3_curcmdar)
- mx28_reg(hw_apbh_ch3_nxtcmdar)
- mx28_reg(hw_apbh_ch3_cmd)
- mx28_reg(hw_apbh_ch3_bar)
- mx28_reg(hw_apbh_ch3_sema)
- mx28_reg(hw_apbh_ch3_debug1)
- mx28_reg(hw_apbh_ch3_debug2)
- mx28_reg(hw_apbh_ch4_curcmdar)
- mx28_reg(hw_apbh_ch4_nxtcmdar)
- mx28_reg(hw_apbh_ch4_cmd)
- mx28_reg(hw_apbh_ch4_bar)
- mx28_reg(hw_apbh_ch4_sema)
- mx28_reg(hw_apbh_ch4_debug1)
- mx28_reg(hw_apbh_ch4_debug2)
- mx28_reg(hw_apbh_ch5_curcmdar)
- mx28_reg(hw_apbh_ch5_nxtcmdar)
- mx28_reg(hw_apbh_ch5_cmd)
- mx28_reg(hw_apbh_ch5_bar)
- mx28_reg(hw_apbh_ch5_sema)
- mx28_reg(hw_apbh_ch5_debug1)
- mx28_reg(hw_apbh_ch5_debug2)
- mx28_reg(hw_apbh_ch6_curcmdar)
- mx28_reg(hw_apbh_ch6_nxtcmdar)
- mx28_reg(hw_apbh_ch6_cmd)
- mx28_reg(hw_apbh_ch6_bar)
- mx28_reg(hw_apbh_ch6_sema)
- mx28_reg(hw_apbh_ch6_debug1)
- mx28_reg(hw_apbh_ch6_debug2)
- mx28_reg(hw_apbh_ch7_curcmdar)
- mx28_reg(hw_apbh_ch7_nxtcmdar)
- mx28_reg(hw_apbh_ch7_cmd)
- mx28_reg(hw_apbh_ch7_bar)
- mx28_reg(hw_apbh_ch7_sema)
- mx28_reg(hw_apbh_ch7_debug1)
- mx28_reg(hw_apbh_ch7_debug2)
- mx28_reg(hw_apbh_ch8_curcmdar)
- mx28_reg(hw_apbh_ch8_nxtcmdar)
- mx28_reg(hw_apbh_ch8_cmd)
- mx28_reg(hw_apbh_ch8_bar)
- mx28_reg(hw_apbh_ch8_sema)
- mx28_reg(hw_apbh_ch8_debug1)
- mx28_reg(hw_apbh_ch8_debug2)
- mx28_reg(hw_apbh_ch9_curcmdar)
- mx28_reg(hw_apbh_ch9_nxtcmdar)
- mx28_reg(hw_apbh_ch9_cmd)
- mx28_reg(hw_apbh_ch9_bar)
- mx28_reg(hw_apbh_ch9_sema)
- mx28_reg(hw_apbh_ch9_debug1)
- mx28_reg(hw_apbh_ch9_debug2)
- mx28_reg(hw_apbh_ch10_curcmdar)
- mx28_reg(hw_apbh_ch10_nxtcmdar)
- mx28_reg(hw_apbh_ch10_cmd)
- mx28_reg(hw_apbh_ch10_bar)
- mx28_reg(hw_apbh_ch10_sema)
- mx28_reg(hw_apbh_ch10_debug1)
- mx28_reg(hw_apbh_ch10_debug2)
- mx28_reg(hw_apbh_ch11_curcmdar)
- mx28_reg(hw_apbh_ch11_nxtcmdar)
- mx28_reg(hw_apbh_ch11_cmd)
- mx28_reg(hw_apbh_ch11_bar)
- mx28_reg(hw_apbh_ch11_sema)
- mx28_reg(hw_apbh_ch11_debug1)
- mx28_reg(hw_apbh_ch11_debug2)
- mx28_reg(hw_apbh_ch12_curcmdar)
- mx28_reg(hw_apbh_ch12_nxtcmdar)
- mx28_reg(hw_apbh_ch12_cmd)
- mx28_reg(hw_apbh_ch12_bar)
- mx28_reg(hw_apbh_ch12_sema)
- mx28_reg(hw_apbh_ch12_debug1)
- mx28_reg(hw_apbh_ch12_debug2)
- mx28_reg(hw_apbh_ch13_curcmdar)
- mx28_reg(hw_apbh_ch13_nxtcmdar)
- mx28_reg(hw_apbh_ch13_cmd)
- mx28_reg(hw_apbh_ch13_bar)
- mx28_reg(hw_apbh_ch13_sema)
- mx28_reg(hw_apbh_ch13_debug1)
- mx28_reg(hw_apbh_ch13_debug2)
- mx28_reg(hw_apbh_ch14_curcmdar)
- mx28_reg(hw_apbh_ch14_nxtcmdar)
- mx28_reg(hw_apbh_ch14_cmd)
- mx28_reg(hw_apbh_ch14_bar)
- mx28_reg(hw_apbh_ch14_sema)
- mx28_reg(hw_apbh_ch14_debug1)
- mx28_reg(hw_apbh_ch14_debug2)
- mx28_reg(hw_apbh_ch15_curcmdar)
- mx28_reg(hw_apbh_ch15_nxtcmdar)
- mx28_reg(hw_apbh_ch15_cmd)
- mx28_reg(hw_apbh_ch15_bar)
- mx28_reg(hw_apbh_ch15_sema)
- mx28_reg(hw_apbh_ch15_debug1)
- mx28_reg(hw_apbh_ch15_debug2)
+ mx28_reg_32(hw_apbh_ch0_curcmdar)
+ mx28_reg_32(hw_apbh_ch0_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch0_cmd)
+ mx28_reg_32(hw_apbh_ch0_bar)
+ mx28_reg_32(hw_apbh_ch0_sema)
+ mx28_reg_32(hw_apbh_ch0_debug1)
+ mx28_reg_32(hw_apbh_ch0_debug2)
+ mx28_reg_32(hw_apbh_ch1_curcmdar)
+ mx28_reg_32(hw_apbh_ch1_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch1_cmd)
+ mx28_reg_32(hw_apbh_ch1_bar)
+ mx28_reg_32(hw_apbh_ch1_sema)
+ mx28_reg_32(hw_apbh_ch1_debug1)
+ mx28_reg_32(hw_apbh_ch1_debug2)
+ mx28_reg_32(hw_apbh_ch2_curcmdar)
+ mx28_reg_32(hw_apbh_ch2_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch2_cmd)
+ mx28_reg_32(hw_apbh_ch2_bar)
+ mx28_reg_32(hw_apbh_ch2_sema)
+ mx28_reg_32(hw_apbh_ch2_debug1)
+ mx28_reg_32(hw_apbh_ch2_debug2)
+ mx28_reg_32(hw_apbh_ch3_curcmdar)
+ mx28_reg_32(hw_apbh_ch3_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch3_cmd)
+ mx28_reg_32(hw_apbh_ch3_bar)
+ mx28_reg_32(hw_apbh_ch3_sema)
+ mx28_reg_32(hw_apbh_ch3_debug1)
+ mx28_reg_32(hw_apbh_ch3_debug2)
+ mx28_reg_32(hw_apbh_ch4_curcmdar)
+ mx28_reg_32(hw_apbh_ch4_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch4_cmd)
+ mx28_reg_32(hw_apbh_ch4_bar)
+ mx28_reg_32(hw_apbh_ch4_sema)
+ mx28_reg_32(hw_apbh_ch4_debug1)
+ mx28_reg_32(hw_apbh_ch4_debug2)
+ mx28_reg_32(hw_apbh_ch5_curcmdar)
+ mx28_reg_32(hw_apbh_ch5_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch5_cmd)
+ mx28_reg_32(hw_apbh_ch5_bar)
+ mx28_reg_32(hw_apbh_ch5_sema)
+ mx28_reg_32(hw_apbh_ch5_debug1)
+ mx28_reg_32(hw_apbh_ch5_debug2)
+ mx28_reg_32(hw_apbh_ch6_curcmdar)
+ mx28_reg_32(hw_apbh_ch6_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch6_cmd)
+ mx28_reg_32(hw_apbh_ch6_bar)
+ mx28_reg_32(hw_apbh_ch6_sema)
+ mx28_reg_32(hw_apbh_ch6_debug1)
+ mx28_reg_32(hw_apbh_ch6_debug2)
+ mx28_reg_32(hw_apbh_ch7_curcmdar)
+ mx28_reg_32(hw_apbh_ch7_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch7_cmd)
+ mx28_reg_32(hw_apbh_ch7_bar)
+ mx28_reg_32(hw_apbh_ch7_sema)
+ mx28_reg_32(hw_apbh_ch7_debug1)
+ mx28_reg_32(hw_apbh_ch7_debug2)
+ mx28_reg_32(hw_apbh_ch8_curcmdar)
+ mx28_reg_32(hw_apbh_ch8_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch8_cmd)
+ mx28_reg_32(hw_apbh_ch8_bar)
+ mx28_reg_32(hw_apbh_ch8_sema)
+ mx28_reg_32(hw_apbh_ch8_debug1)
+ mx28_reg_32(hw_apbh_ch8_debug2)
+ mx28_reg_32(hw_apbh_ch9_curcmdar)
+ mx28_reg_32(hw_apbh_ch9_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch9_cmd)
+ mx28_reg_32(hw_apbh_ch9_bar)
+ mx28_reg_32(hw_apbh_ch9_sema)
+ mx28_reg_32(hw_apbh_ch9_debug1)
+ mx28_reg_32(hw_apbh_ch9_debug2)
+ mx28_reg_32(hw_apbh_ch10_curcmdar)
+ mx28_reg_32(hw_apbh_ch10_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch10_cmd)
+ mx28_reg_32(hw_apbh_ch10_bar)
+ mx28_reg_32(hw_apbh_ch10_sema)
+ mx28_reg_32(hw_apbh_ch10_debug1)
+ mx28_reg_32(hw_apbh_ch10_debug2)
+ mx28_reg_32(hw_apbh_ch11_curcmdar)
+ mx28_reg_32(hw_apbh_ch11_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch11_cmd)
+ mx28_reg_32(hw_apbh_ch11_bar)
+ mx28_reg_32(hw_apbh_ch11_sema)
+ mx28_reg_32(hw_apbh_ch11_debug1)
+ mx28_reg_32(hw_apbh_ch11_debug2)
+ mx28_reg_32(hw_apbh_ch12_curcmdar)
+ mx28_reg_32(hw_apbh_ch12_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch12_cmd)
+ mx28_reg_32(hw_apbh_ch12_bar)
+ mx28_reg_32(hw_apbh_ch12_sema)
+ mx28_reg_32(hw_apbh_ch12_debug1)
+ mx28_reg_32(hw_apbh_ch12_debug2)
+ mx28_reg_32(hw_apbh_ch13_curcmdar)
+ mx28_reg_32(hw_apbh_ch13_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch13_cmd)
+ mx28_reg_32(hw_apbh_ch13_bar)
+ mx28_reg_32(hw_apbh_ch13_sema)
+ mx28_reg_32(hw_apbh_ch13_debug1)
+ mx28_reg_32(hw_apbh_ch13_debug2)
+ mx28_reg_32(hw_apbh_ch14_curcmdar)
+ mx28_reg_32(hw_apbh_ch14_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch14_cmd)
+ mx28_reg_32(hw_apbh_ch14_bar)
+ mx28_reg_32(hw_apbh_ch14_sema)
+ mx28_reg_32(hw_apbh_ch14_debug1)
+ mx28_reg_32(hw_apbh_ch14_debug2)
+ mx28_reg_32(hw_apbh_ch15_curcmdar)
+ mx28_reg_32(hw_apbh_ch15_nxtcmdar)
+ mx28_reg_32(hw_apbh_ch15_cmd)
+ mx28_reg_32(hw_apbh_ch15_bar)
+ mx28_reg_32(hw_apbh_ch15_sema)
+ mx28_reg_32(hw_apbh_ch15_debug1)
+ mx28_reg_32(hw_apbh_ch15_debug2)
};
};
- mx28_reg(hw_apbh_version)
+ mx28_reg_32(hw_apbh_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_bch_regs {
- mx28_reg(hw_bch_ctrl)
- mx28_reg(hw_bch_status0)
- mx28_reg(hw_bch_mode)
- mx28_reg(hw_bch_encodeptr)
- mx28_reg(hw_bch_dataptr)
- mx28_reg(hw_bch_metaptr)
+ mx28_reg_32(hw_bch_ctrl)
+ mx28_reg_32(hw_bch_status0)
+ mx28_reg_32(hw_bch_mode)
+ mx28_reg_32(hw_bch_encodeptr)
+ mx28_reg_32(hw_bch_dataptr)
+ mx28_reg_32(hw_bch_metaptr)
uint32_t reserved[4];
- mx28_reg(hw_bch_layoutselect)
- mx28_reg(hw_bch_flash0layout0)
- mx28_reg(hw_bch_flash0layout1)
- mx28_reg(hw_bch_flash1layout0)
- mx28_reg(hw_bch_flash1layout1)
- mx28_reg(hw_bch_flash2layout0)
- mx28_reg(hw_bch_flash2layout1)
- mx28_reg(hw_bch_flash3layout0)
- mx28_reg(hw_bch_flash3layout1)
- mx28_reg(hw_bch_dbgkesread)
- mx28_reg(hw_bch_dbgcsferead)
- mx28_reg(hw_bch_dbgsyndegread)
- mx28_reg(hw_bch_dbgahbmread)
- mx28_reg(hw_bch_blockname)
- mx28_reg(hw_bch_version)
+ mx28_reg_32(hw_bch_layoutselect)
+ mx28_reg_32(hw_bch_flash0layout0)
+ mx28_reg_32(hw_bch_flash0layout1)
+ mx28_reg_32(hw_bch_flash1layout0)
+ mx28_reg_32(hw_bch_flash1layout1)
+ mx28_reg_32(hw_bch_flash2layout0)
+ mx28_reg_32(hw_bch_flash2layout1)
+ mx28_reg_32(hw_bch_flash3layout0)
+ mx28_reg_32(hw_bch_flash3layout1)
+ mx28_reg_32(hw_bch_dbgkesread)
+ mx28_reg_32(hw_bch_dbgcsferead)
+ mx28_reg_32(hw_bch_dbgsyndegread)
+ mx28_reg_32(hw_bch_dbgahbmread)
+ mx28_reg_32(hw_bch_blockname)
+ mx28_reg_32(hw_bch_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_clkctrl_regs {
- mx28_reg(hw_clkctrl_pll0ctrl0) /* 0x00 */
- mx28_reg(hw_clkctrl_pll0ctrl1) /* 0x10 */
- mx28_reg(hw_clkctrl_pll1ctrl0) /* 0x20 */
- mx28_reg(hw_clkctrl_pll1ctrl1) /* 0x30 */
- mx28_reg(hw_clkctrl_pll2ctrl0) /* 0x40 */
- mx28_reg(hw_clkctrl_cpu) /* 0x50 */
- mx28_reg(hw_clkctrl_hbus) /* 0x60 */
- mx28_reg(hw_clkctrl_xbus) /* 0x70 */
- mx28_reg(hw_clkctrl_xtal) /* 0x80 */
- mx28_reg(hw_clkctrl_ssp0) /* 0x90 */
- mx28_reg(hw_clkctrl_ssp1) /* 0xa0 */
- mx28_reg(hw_clkctrl_ssp2) /* 0xb0 */
- mx28_reg(hw_clkctrl_ssp3) /* 0xc0 */
- mx28_reg(hw_clkctrl_gpmi) /* 0xd0 */
- mx28_reg(hw_clkctrl_spdif) /* 0xe0 */
- mx28_reg(hw_clkctrl_emi) /* 0xf0 */
- mx28_reg(hw_clkctrl_saif0) /* 0x100 */
- mx28_reg(hw_clkctrl_saif1) /* 0x110 */
- mx28_reg(hw_clkctrl_lcdif) /* 0x120 */
- mx28_reg(hw_clkctrl_etm) /* 0x130 */
- mx28_reg(hw_clkctrl_enet) /* 0x140 */
- mx28_reg(hw_clkctrl_hsadc) /* 0x150 */
- mx28_reg(hw_clkctrl_flexcan) /* 0x160 */
+ mx28_reg_32(hw_clkctrl_pll0ctrl0) /* 0x00 */
+ mx28_reg_32(hw_clkctrl_pll0ctrl1) /* 0x10 */
+ mx28_reg_32(hw_clkctrl_pll1ctrl0) /* 0x20 */
+ mx28_reg_32(hw_clkctrl_pll1ctrl1) /* 0x30 */
+ mx28_reg_32(hw_clkctrl_pll2ctrl0) /* 0x40 */
+ mx28_reg_32(hw_clkctrl_cpu) /* 0x50 */
+ mx28_reg_32(hw_clkctrl_hbus) /* 0x60 */
+ mx28_reg_32(hw_clkctrl_xbus) /* 0x70 */
+ mx28_reg_32(hw_clkctrl_xtal) /* 0x80 */
+ mx28_reg_32(hw_clkctrl_ssp0) /* 0x90 */
+ mx28_reg_32(hw_clkctrl_ssp1) /* 0xa0 */
+ mx28_reg_32(hw_clkctrl_ssp2) /* 0xb0 */
+ mx28_reg_32(hw_clkctrl_ssp3) /* 0xc0 */
+ mx28_reg_32(hw_clkctrl_gpmi) /* 0xd0 */
+ mx28_reg_32(hw_clkctrl_spdif) /* 0xe0 */
+ mx28_reg_32(hw_clkctrl_emi) /* 0xf0 */
+ mx28_reg_32(hw_clkctrl_saif0) /* 0x100 */
+ mx28_reg_32(hw_clkctrl_saif1) /* 0x110 */
+ mx28_reg_32(hw_clkctrl_lcdif) /* 0x120 */
+ mx28_reg_32(hw_clkctrl_etm) /* 0x130 */
+ mx28_reg_32(hw_clkctrl_enet) /* 0x140 */
+ mx28_reg_32(hw_clkctrl_hsadc) /* 0x150 */
+ mx28_reg_32(hw_clkctrl_flexcan) /* 0x160 */
uint32_t reserved[16];
- mx28_reg(hw_clkctrl_frac0) /* 0x1b0 */
- mx28_reg(hw_clkctrl_frac1) /* 0x1c0 */
- mx28_reg(hw_clkctrl_clkseq) /* 0x1d0 */
- mx28_reg(hw_clkctrl_reset) /* 0x1e0 */
- mx28_reg(hw_clkctrl_status) /* 0x1f0 */
- mx28_reg(hw_clkctrl_version) /* 0x200 */
+ mx28_reg_8(hw_clkctrl_frac0) /* 0x1b0 */
+ mx28_reg_8(hw_clkctrl_frac1) /* 0x1c0 */
+ mx28_reg_32(hw_clkctrl_clkseq) /* 0x1d0 */
+ mx28_reg_32(hw_clkctrl_reset) /* 0x1e0 */
+ mx28_reg_32(hw_clkctrl_status) /* 0x1f0 */
+ mx28_reg_32(hw_clkctrl_version) /* 0x200 */
};
#endif
#define CLKCTRL_FLEXCAN_STOP_CAN1 (1 << 28)
#define CLKCTRL_FLEXCAN_CAN1_STATUS (1 << 27)
-#define CLKCTRL_FRAC0_CLKGATEIO0 (1 << 31)
-#define CLKCTRL_FRAC0_IO0_STABLE (1 << 30)
-#define CLKCTRL_FRAC0_IO0FRAC_MASK (0x3f << 24)
-#define CLKCTRL_FRAC0_IO0FRAC_OFFSET 24
-#define CLKCTRL_FRAC0_CLKGATEIO1 (1 << 23)
-#define CLKCTRL_FRAC0_IO1_STABLE (1 << 22)
-#define CLKCTRL_FRAC0_IO1FRAC_MASK (0x3f << 16)
-#define CLKCTRL_FRAC0_IO1FRAC_OFFSET 16
-#define CLKCTRL_FRAC0_CLKGATEEMI (1 << 15)
-#define CLKCTRL_FRAC0_EMI_STABLE (1 << 14)
-#define CLKCTRL_FRAC0_EMIFRAC_MASK (0x3f << 8)
-#define CLKCTRL_FRAC0_EMIFRAC_OFFSET 8
-#define CLKCTRL_FRAC0_CLKGATECPU (1 << 7)
-#define CLKCTRL_FRAC0_CPU_STABLE (1 << 6)
-#define CLKCTRL_FRAC0_CPUFRAC_MASK 0x3f
-#define CLKCTRL_FRAC0_CPUFRAC_OFFSET 0
-
-#define CLKCTRL_FRAC1_CLKGATEGPMI (1 << 23)
-#define CLKCTRL_FRAC1_GPMI_STABLE (1 << 22)
-#define CLKCTRL_FRAC1_GPMIFRAC_MASK (0x3f << 16)
-#define CLKCTRL_FRAC1_GPMIFRAC_OFFSET 16
-#define CLKCTRL_FRAC1_CLKGATEHSADC (1 << 15)
-#define CLKCTRL_FRAC1_HSADC_STABLE (1 << 14)
-#define CLKCTRL_FRAC1_HSADCFRAC_MASK (0x3f << 8)
-#define CLKCTRL_FRAC1_HSADCFRAC_OFFSET 8
-#define CLKCTRL_FRAC1_CLKGATEPIX (1 << 7)
-#define CLKCTRL_FRAC1_PIX_STABLE (1 << 6)
-#define CLKCTRL_FRAC1_PIXFRAC_MASK 0x3f
-#define CLKCTRL_FRAC1_PIXFRAC_OFFSET 0
+#define CLKCTRL_FRAC_CLKGATE (1 << 7)
+#define CLKCTRL_FRAC_STABLE (1 << 6)
+#define CLKCTRL_FRAC_FRAC_MASK 0x3f
+#define CLKCTRL_FRAC_FRAC_OFFSET 0
+#define CLKCTRL_FRAC0_CPU 0
+#define CLKCTRL_FRAC0_EMI 1
+#define CLKCTRL_FRAC0_IO1 2
+#define CLKCTRL_FRAC0_IO0 3
+#define CLKCTRL_FRAC1_PIX 0
+#define CLKCTRL_FRAC1_HSADC 1
+#define CLKCTRL_FRAC1_GPMI 2
#define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 18)
#define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
*
*/
-#define __mx28_reg(name) \
+#define __mx28_reg_8(name) \
+ uint8_t name[4]; \
+ uint8_t name##_set[4]; \
+ uint8_t name##_clr[4]; \
+ uint8_t name##_tog[4]; \
+
+#define __mx28_reg_32(name) \
uint32_t name; \
uint32_t name##_set; \
uint32_t name##_clr; \
uint32_t name##_tog;
-struct mx28_register {
- __mx28_reg(reg)
+struct mx28_register_8 {
+ __mx28_reg_8(reg)
+};
+
+struct mx28_register_32 {
+ __mx28_reg_32(reg)
};
-#define mx28_reg(name) \
+#define mx28_reg_8(name) \
+ union { \
+ struct { __mx28_reg_8(name) }; \
+ struct mx28_register_32 name##_reg; \
+ };
+
+#define mx28_reg_32(name) \
union { \
- struct { __mx28_reg(name) }; \
- struct mx28_register name##_reg; \
+ struct { __mx28_reg_32(name) }; \
+ struct mx28_register_32 name##_reg; \
};
#endif /* __MX28_REGS_COMMON_H__ */
--- /dev/null
+/*
+ * Freescale i.MX28 DIGCTL Register Definitions
+ *
+ * Copyright (C) 2012 Robert Delien <robert@delien.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MX28_REGS_DIGCTL_H__
+#define __MX28_REGS_DIGCTL_H__
+
+#include <asm/arch/regs-common.h>
+
+#ifndef __ASSEMBLY__
+struct mx28_digctl_regs {
+ mx28_reg_32(hw_digctl_ctrl) /* 0x000 */
+ mx28_reg_32(hw_digctl_status) /* 0x010 */
+ mx28_reg_32(hw_digctl_hclkcount) /* 0x020 */
+ mx28_reg_32(hw_digctl_ramctrl) /* 0x030 */
+ mx28_reg_32(hw_digctl_emi_status) /* 0x040 */
+ mx28_reg_32(hw_digctl_read_margin) /* 0x050 */
+ uint32_t hw_digctl_writeonce; /* 0x060 */
+ uint32_t reserved_writeonce[3];
+ mx28_reg_32(hw_digctl_bist_ctl) /* 0x070 */
+ mx28_reg_32(hw_digctl_bist_status) /* 0x080 */
+ uint32_t hw_digctl_entropy; /* 0x090 */
+ uint32_t reserved_entropy[3];
+ uint32_t hw_digctl_entropy_latched; /* 0x0a0 */
+ uint32_t reserved_entropy_latched[3];
+
+ uint32_t reserved1[4];
+
+ mx28_reg_32(hw_digctl_microseconds) /* 0x0c0 */
+ uint32_t hw_digctl_dbgrd; /* 0x0d0 */
+ uint32_t reserved_hw_digctl_dbgrd[3];
+ uint32_t hw_digctl_dbg; /* 0x0e0 */
+ uint32_t reserved_hw_digctl_dbg[3];
+
+ uint32_t reserved2[4];
+
+ mx28_reg_32(hw_digctl_usb_loopback) /* 0x100 */
+ mx28_reg_32(hw_digctl_ocram_status0) /* 0x110 */
+ mx28_reg_32(hw_digctl_ocram_status1) /* 0x120 */
+ mx28_reg_32(hw_digctl_ocram_status2) /* 0x130 */
+ mx28_reg_32(hw_digctl_ocram_status3) /* 0x140 */
+ mx28_reg_32(hw_digctl_ocram_status4) /* 0x150 */
+ mx28_reg_32(hw_digctl_ocram_status5) /* 0x160 */
+ mx28_reg_32(hw_digctl_ocram_status6) /* 0x170 */
+ mx28_reg_32(hw_digctl_ocram_status7) /* 0x180 */
+ mx28_reg_32(hw_digctl_ocram_status8) /* 0x190 */
+ mx28_reg_32(hw_digctl_ocram_status9) /* 0x1a0 */
+ mx28_reg_32(hw_digctl_ocram_status10) /* 0x1b0 */
+ mx28_reg_32(hw_digctl_ocram_status11) /* 0x1c0 */
+ mx28_reg_32(hw_digctl_ocram_status12) /* 0x1d0 */
+ mx28_reg_32(hw_digctl_ocram_status13) /* 0x1e0 */
+
+ uint32_t reserved3[36];
+
+ uint32_t hw_digctl_scratch0; /* 0x280 */
+ uint32_t reserved_hw_digctl_scratch0[3];
+ uint32_t hw_digctl_scratch1; /* 0x290 */
+ uint32_t reserved_hw_digctl_scratch1[3];
+ uint32_t hw_digctl_armcache; /* 0x2a0 */
+ uint32_t reserved_hw_digctl_armcache[3];
+ mx28_reg_32(hw_digctl_debug_trap) /* 0x2b0 */
+ uint32_t hw_digctl_debug_trap_l0_addr_low; /* 0x2c0 */
+ uint32_t reserved_hw_digctl_debug_trap_l0_addr_low[3];
+ uint32_t hw_digctl_debug_trap_l0_addr_high; /* 0x2d0 */
+ uint32_t reserved_hw_digctl_debug_trap_l0_addr_high[3];
+ uint32_t hw_digctl_debug_trap_l3_addr_low; /* 0x2e0 */
+ uint32_t reserved_hw_digctl_debug_trap_l3_addr_low[3];
+ uint32_t hw_digctl_debug_trap_l3_addr_high; /* 0x2f0 */
+ uint32_t reserved_hw_digctl_debug_trap_l3_addr_high[3];
+ uint32_t hw_digctl_fsl; /* 0x300 */
+ uint32_t reserved_hw_digctl_fsl[3];
+ uint32_t hw_digctl_chipid; /* 0x310 */
+ uint32_t reserved_hw_digctl_chipid[3];
+
+ uint32_t reserved4[4];
+
+ uint32_t hw_digctl_ahb_stats_select; /* 0x330 */
+ uint32_t reserved_hw_digctl_ahb_stats_select[3];
+
+ uint32_t reserved5[12];
+
+ uint32_t hw_digctl_l1_ahb_active_cycles; /* 0x370 */
+ uint32_t reserved_hw_digctl_l1_ahb_active_cycles[3];
+ uint32_t hw_digctl_l1_ahb_data_stalled; /* 0x380 */
+ uint32_t reserved_hw_digctl_l1_ahb_data_stalled[3];
+ uint32_t hw_digctl_l1_ahb_data_cycles; /* 0x390 */
+ uint32_t reserved_hw_digctl_l1_ahb_data_cycles[3];
+ uint32_t hw_digctl_l2_ahb_active_cycles; /* 0x3a0 */
+ uint32_t reserved_hw_digctl_l2_ahb_active_cycles[3];
+ uint32_t hw_digctl_l2_ahb_data_stalled; /* 0x3b0 */
+ uint32_t reserved_hw_digctl_l2_ahb_data_stalled[3];
+ uint32_t hw_digctl_l2_ahb_data_cycles; /* 0x3c0 */
+ uint32_t reserved_hw_digctl_l2_ahb_data_cycles[3];
+ uint32_t hw_digctl_l3_ahb_active_cycles; /* 0x3d0 */
+ uint32_t reserved_hw_digctl_l3_ahb_active_cycles[3];
+ uint32_t hw_digctl_l3_ahb_data_stalled; /* 0x3e0 */
+ uint32_t reserved_hw_digctl_l3_ahb_data_stalled[3];
+ uint32_t hw_digctl_l3_ahb_data_cycles; /* 0x3f0 */
+ uint32_t reserved_hw_digctl_l3_ahb_data_cycles[3];
+
+ uint32_t reserved6[64];
+
+ uint32_t hw_digctl_mpte0_loc; /* 0x500 */
+ uint32_t reserved_hw_digctl_mpte0_loc[3];
+ uint32_t hw_digctl_mpte1_loc; /* 0x510 */
+ uint32_t reserved_hw_digctl_mpte1_loc[3];
+ uint32_t hw_digctl_mpte2_loc; /* 0x520 */
+ uint32_t reserved_hw_digctl_mpte2_loc[3];
+ uint32_t hw_digctl_mpte3_loc; /* 0x530 */
+ uint32_t reserved_hw_digctl_mpte3_loc[3];
+ uint32_t hw_digctl_mpte4_loc; /* 0x540 */
+ uint32_t reserved_hw_digctl_mpte4_loc[3];
+ uint32_t hw_digctl_mpte5_loc; /* 0x550 */
+ uint32_t reserved_hw_digctl_mpte5_loc[3];
+ uint32_t hw_digctl_mpte6_loc; /* 0x560 */
+ uint32_t reserved_hw_digctl_mpte6_loc[3];
+ uint32_t hw_digctl_mpte7_loc; /* 0x570 */
+ uint32_t reserved_hw_digctl_mpte7_loc[3];
+ uint32_t hw_digctl_mpte8_loc; /* 0x580 */
+ uint32_t reserved_hw_digctl_mpte8_loc[3];
+ uint32_t hw_digctl_mpte9_loc; /* 0x590 */
+ uint32_t reserved_hw_digctl_mpte9_loc[3];
+ uint32_t hw_digctl_mpte10_loc; /* 0x5a0 */
+ uint32_t reserved_hw_digctl_mpte10_loc[3];
+ uint32_t hw_digctl_mpte11_loc; /* 0x5b0 */
+ uint32_t reserved_hw_digctl_mpte11_loc[3];
+ uint32_t hw_digctl_mpte12_loc; /* 0x5c0 */
+ uint32_t reserved_hw_digctl_mpte12_loc[3];
+ uint32_t hw_digctl_mpte13_loc; /* 0x5d0 */
+ uint32_t reserved_hw_digctl_mpte13_loc[3];
+ uint32_t hw_digctl_mpte14_loc; /* 0x5e0 */
+ uint32_t reserved_hw_digctl_mpte14_loc[3];
+ uint32_t hw_digctl_mpte15_loc; /* 0x5f0 */
+ uint32_t reserved_hw_digctl_mpte15_loc[3];
+};
+#endif
+
+#endif /* __MX28_REGS_DIGCTL_H__ */
#ifndef __ASSEMBLY__
struct mx28_gpmi_regs {
- mx28_reg(hw_gpmi_ctrl0)
- mx28_reg(hw_gpmi_compare)
- mx28_reg(hw_gpmi_eccctrl)
- mx28_reg(hw_gpmi_ecccount)
- mx28_reg(hw_gpmi_payload)
- mx28_reg(hw_gpmi_auxiliary)
- mx28_reg(hw_gpmi_ctrl1)
- mx28_reg(hw_gpmi_timing0)
- mx28_reg(hw_gpmi_timing1)
+ mx28_reg_32(hw_gpmi_ctrl0)
+ mx28_reg_32(hw_gpmi_compare)
+ mx28_reg_32(hw_gpmi_eccctrl)
+ mx28_reg_32(hw_gpmi_ecccount)
+ mx28_reg_32(hw_gpmi_payload)
+ mx28_reg_32(hw_gpmi_auxiliary)
+ mx28_reg_32(hw_gpmi_ctrl1)
+ mx28_reg_32(hw_gpmi_timing0)
+ mx28_reg_32(hw_gpmi_timing1)
uint32_t reserved[4];
- mx28_reg(hw_gpmi_data)
- mx28_reg(hw_gpmi_stat)
- mx28_reg(hw_gpmi_debug)
- mx28_reg(hw_gpmi_version)
+ mx28_reg_32(hw_gpmi_data)
+ mx28_reg_32(hw_gpmi_stat)
+ mx28_reg_32(hw_gpmi_debug)
+ mx28_reg_32(hw_gpmi_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_i2c_regs {
- mx28_reg(hw_i2c_ctrl0)
- mx28_reg(hw_i2c_timing0)
- mx28_reg(hw_i2c_timing1)
- mx28_reg(hw_i2c_timing2)
- mx28_reg(hw_i2c_ctrl1)
- mx28_reg(hw_i2c_stat)
- mx28_reg(hw_i2c_queuectrl)
- mx28_reg(hw_i2c_queuestat)
- mx28_reg(hw_i2c_queuecmd)
- mx28_reg(hw_i2c_queuedata)
- mx28_reg(hw_i2c_data)
- mx28_reg(hw_i2c_debug0)
- mx28_reg(hw_i2c_debug1)
- mx28_reg(hw_i2c_version)
+ mx28_reg_32(hw_i2c_ctrl0)
+ mx28_reg_32(hw_i2c_timing0)
+ mx28_reg_32(hw_i2c_timing1)
+ mx28_reg_32(hw_i2c_timing2)
+ mx28_reg_32(hw_i2c_ctrl1)
+ mx28_reg_32(hw_i2c_stat)
+ mx28_reg_32(hw_i2c_queuectrl)
+ mx28_reg_32(hw_i2c_queuestat)
+ mx28_reg_32(hw_i2c_queuecmd)
+ mx28_reg_32(hw_i2c_queuedata)
+ mx28_reg_32(hw_i2c_data)
+ mx28_reg_32(hw_i2c_debug0)
+ mx28_reg_32(hw_i2c_debug1)
+ mx28_reg_32(hw_i2c_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_ocotp_regs {
- mx28_reg(hw_ocotp_ctrl) /* 0x0 */
- mx28_reg(hw_ocotp_data) /* 0x10 */
- mx28_reg(hw_ocotp_cust0) /* 0x20 */
- mx28_reg(hw_ocotp_cust1) /* 0x30 */
- mx28_reg(hw_ocotp_cust2) /* 0x40 */
- mx28_reg(hw_ocotp_cust3) /* 0x50 */
- mx28_reg(hw_ocotp_crypto0) /* 0x60 */
- mx28_reg(hw_ocotp_crypto1) /* 0x70 */
- mx28_reg(hw_ocotp_crypto2) /* 0x80 */
- mx28_reg(hw_ocotp_crypto3) /* 0x90 */
- mx28_reg(hw_ocotp_hwcap0) /* 0xa0 */
- mx28_reg(hw_ocotp_hwcap1) /* 0xb0 */
- mx28_reg(hw_ocotp_hwcap2) /* 0xc0 */
- mx28_reg(hw_ocotp_hwcap3) /* 0xd0 */
- mx28_reg(hw_ocotp_hwcap4) /* 0xe0 */
- mx28_reg(hw_ocotp_hwcap5) /* 0xf0 */
- mx28_reg(hw_ocotp_swcap) /* 0x100 */
- mx28_reg(hw_ocotp_custcap) /* 0x110 */
- mx28_reg(hw_ocotp_lock) /* 0x120 */
- mx28_reg(hw_ocotp_ops0) /* 0x130 */
- mx28_reg(hw_ocotp_ops1) /* 0x140 */
- mx28_reg(hw_ocotp_ops2) /* 0x150 */
- mx28_reg(hw_ocotp_ops3) /* 0x160 */
- mx28_reg(hw_ocotp_un0) /* 0x170 */
- mx28_reg(hw_ocotp_un1) /* 0x180 */
- mx28_reg(hw_ocotp_un2) /* 0x190 */
- mx28_reg(hw_ocotp_rom0) /* 0x1a0 */
- mx28_reg(hw_ocotp_rom1) /* 0x1b0 */
- mx28_reg(hw_ocotp_rom2) /* 0x1c0 */
- mx28_reg(hw_ocotp_rom3) /* 0x1d0 */
- mx28_reg(hw_ocotp_rom4) /* 0x1e0 */
- mx28_reg(hw_ocotp_rom5) /* 0x1f0 */
- mx28_reg(hw_ocotp_rom6) /* 0x200 */
- mx28_reg(hw_ocotp_rom7) /* 0x210 */
- mx28_reg(hw_ocotp_srk0) /* 0x220 */
- mx28_reg(hw_ocotp_srk1) /* 0x230 */
- mx28_reg(hw_ocotp_srk2) /* 0x240 */
- mx28_reg(hw_ocotp_srk3) /* 0x250 */
- mx28_reg(hw_ocotp_srk4) /* 0x260 */
- mx28_reg(hw_ocotp_srk5) /* 0x270 */
- mx28_reg(hw_ocotp_srk6) /* 0x280 */
- mx28_reg(hw_ocotp_srk7) /* 0x290 */
- mx28_reg(hw_ocotp_version) /* 0x2a0 */
+ mx28_reg_32(hw_ocotp_ctrl) /* 0x0 */
+ mx28_reg_32(hw_ocotp_data) /* 0x10 */
+ mx28_reg_32(hw_ocotp_cust0) /* 0x20 */
+ mx28_reg_32(hw_ocotp_cust1) /* 0x30 */
+ mx28_reg_32(hw_ocotp_cust2) /* 0x40 */
+ mx28_reg_32(hw_ocotp_cust3) /* 0x50 */
+ mx28_reg_32(hw_ocotp_crypto0) /* 0x60 */
+ mx28_reg_32(hw_ocotp_crypto1) /* 0x70 */
+ mx28_reg_32(hw_ocotp_crypto2) /* 0x80 */
+ mx28_reg_32(hw_ocotp_crypto3) /* 0x90 */
+ mx28_reg_32(hw_ocotp_hwcap0) /* 0xa0 */
+ mx28_reg_32(hw_ocotp_hwcap1) /* 0xb0 */
+ mx28_reg_32(hw_ocotp_hwcap2) /* 0xc0 */
+ mx28_reg_32(hw_ocotp_hwcap3) /* 0xd0 */
+ mx28_reg_32(hw_ocotp_hwcap4) /* 0xe0 */
+ mx28_reg_32(hw_ocotp_hwcap5) /* 0xf0 */
+ mx28_reg_32(hw_ocotp_swcap) /* 0x100 */
+ mx28_reg_32(hw_ocotp_custcap) /* 0x110 */
+ mx28_reg_32(hw_ocotp_lock) /* 0x120 */
+ mx28_reg_32(hw_ocotp_ops0) /* 0x130 */
+ mx28_reg_32(hw_ocotp_ops1) /* 0x140 */
+ mx28_reg_32(hw_ocotp_ops2) /* 0x150 */
+ mx28_reg_32(hw_ocotp_ops3) /* 0x160 */
+ mx28_reg_32(hw_ocotp_un0) /* 0x170 */
+ mx28_reg_32(hw_ocotp_un1) /* 0x180 */
+ mx28_reg_32(hw_ocotp_un2) /* 0x190 */
+ mx28_reg_32(hw_ocotp_rom0) /* 0x1a0 */
+ mx28_reg_32(hw_ocotp_rom1) /* 0x1b0 */
+ mx28_reg_32(hw_ocotp_rom2) /* 0x1c0 */
+ mx28_reg_32(hw_ocotp_rom3) /* 0x1d0 */
+ mx28_reg_32(hw_ocotp_rom4) /* 0x1e0 */
+ mx28_reg_32(hw_ocotp_rom5) /* 0x1f0 */
+ mx28_reg_32(hw_ocotp_rom6) /* 0x200 */
+ mx28_reg_32(hw_ocotp_rom7) /* 0x210 */
+ mx28_reg_32(hw_ocotp_srk0) /* 0x220 */
+ mx28_reg_32(hw_ocotp_srk1) /* 0x230 */
+ mx28_reg_32(hw_ocotp_srk2) /* 0x240 */
+ mx28_reg_32(hw_ocotp_srk3) /* 0x250 */
+ mx28_reg_32(hw_ocotp_srk4) /* 0x260 */
+ mx28_reg_32(hw_ocotp_srk5) /* 0x270 */
+ mx28_reg_32(hw_ocotp_srk6) /* 0x280 */
+ mx28_reg_32(hw_ocotp_srk7) /* 0x290 */
+ mx28_reg_32(hw_ocotp_version) /* 0x2a0 */
};
#endif
#ifndef __ASSEMBLY__
struct mx28_pinctrl_regs {
- mx28_reg(hw_pinctrl_ctrl) /* 0x0 */
+ mx28_reg_32(hw_pinctrl_ctrl) /* 0x0 */
uint32_t reserved1[60];
- mx28_reg(hw_pinctrl_muxsel0) /* 0x100 */
- mx28_reg(hw_pinctrl_muxsel1) /* 0x110 */
- mx28_reg(hw_pinctrl_muxsel2) /* 0x120 */
- mx28_reg(hw_pinctrl_muxsel3) /* 0x130 */
- mx28_reg(hw_pinctrl_muxsel4) /* 0x140 */
- mx28_reg(hw_pinctrl_muxsel5) /* 0x150 */
- mx28_reg(hw_pinctrl_muxsel6) /* 0x160 */
- mx28_reg(hw_pinctrl_muxsel7) /* 0x170 */
- mx28_reg(hw_pinctrl_muxsel8) /* 0x180 */
- mx28_reg(hw_pinctrl_muxsel9) /* 0x190 */
- mx28_reg(hw_pinctrl_muxsel10) /* 0x1a0 */
- mx28_reg(hw_pinctrl_muxsel11) /* 0x1b0 */
- mx28_reg(hw_pinctrl_muxsel12) /* 0x1c0 */
- mx28_reg(hw_pinctrl_muxsel13) /* 0x1d0 */
+ mx28_reg_32(hw_pinctrl_muxsel0) /* 0x100 */
+ mx28_reg_32(hw_pinctrl_muxsel1) /* 0x110 */
+ mx28_reg_32(hw_pinctrl_muxsel2) /* 0x120 */
+ mx28_reg_32(hw_pinctrl_muxsel3) /* 0x130 */
+ mx28_reg_32(hw_pinctrl_muxsel4) /* 0x140 */
+ mx28_reg_32(hw_pinctrl_muxsel5) /* 0x150 */
+ mx28_reg_32(hw_pinctrl_muxsel6) /* 0x160 */
+ mx28_reg_32(hw_pinctrl_muxsel7) /* 0x170 */
+ mx28_reg_32(hw_pinctrl_muxsel8) /* 0x180 */
+ mx28_reg_32(hw_pinctrl_muxsel9) /* 0x190 */
+ mx28_reg_32(hw_pinctrl_muxsel10) /* 0x1a0 */
+ mx28_reg_32(hw_pinctrl_muxsel11) /* 0x1b0 */
+ mx28_reg_32(hw_pinctrl_muxsel12) /* 0x1c0 */
+ mx28_reg_32(hw_pinctrl_muxsel13) /* 0x1d0 */
uint32_t reserved2[72];
- mx28_reg(hw_pinctrl_drive0) /* 0x300 */
- mx28_reg(hw_pinctrl_drive1) /* 0x310 */
- mx28_reg(hw_pinctrl_drive2) /* 0x320 */
- mx28_reg(hw_pinctrl_drive3) /* 0x330 */
- mx28_reg(hw_pinctrl_drive4) /* 0x340 */
- mx28_reg(hw_pinctrl_drive5) /* 0x350 */
- mx28_reg(hw_pinctrl_drive6) /* 0x360 */
- mx28_reg(hw_pinctrl_drive7) /* 0x370 */
- mx28_reg(hw_pinctrl_drive8) /* 0x380 */
- mx28_reg(hw_pinctrl_drive9) /* 0x390 */
- mx28_reg(hw_pinctrl_drive10) /* 0x3a0 */
- mx28_reg(hw_pinctrl_drive11) /* 0x3b0 */
- mx28_reg(hw_pinctrl_drive12) /* 0x3c0 */
- mx28_reg(hw_pinctrl_drive13) /* 0x3d0 */
- mx28_reg(hw_pinctrl_drive14) /* 0x3e0 */
- mx28_reg(hw_pinctrl_drive15) /* 0x3f0 */
- mx28_reg(hw_pinctrl_drive16) /* 0x400 */
- mx28_reg(hw_pinctrl_drive17) /* 0x410 */
- mx28_reg(hw_pinctrl_drive18) /* 0x420 */
- mx28_reg(hw_pinctrl_drive19) /* 0x430 */
+ mx28_reg_32(hw_pinctrl_drive0) /* 0x300 */
+ mx28_reg_32(hw_pinctrl_drive1) /* 0x310 */
+ mx28_reg_32(hw_pinctrl_drive2) /* 0x320 */
+ mx28_reg_32(hw_pinctrl_drive3) /* 0x330 */
+ mx28_reg_32(hw_pinctrl_drive4) /* 0x340 */
+ mx28_reg_32(hw_pinctrl_drive5) /* 0x350 */
+ mx28_reg_32(hw_pinctrl_drive6) /* 0x360 */
+ mx28_reg_32(hw_pinctrl_drive7) /* 0x370 */
+ mx28_reg_32(hw_pinctrl_drive8) /* 0x380 */
+ mx28_reg_32(hw_pinctrl_drive9) /* 0x390 */
+ mx28_reg_32(hw_pinctrl_drive10) /* 0x3a0 */
+ mx28_reg_32(hw_pinctrl_drive11) /* 0x3b0 */
+ mx28_reg_32(hw_pinctrl_drive12) /* 0x3c0 */
+ mx28_reg_32(hw_pinctrl_drive13) /* 0x3d0 */
+ mx28_reg_32(hw_pinctrl_drive14) /* 0x3e0 */
+ mx28_reg_32(hw_pinctrl_drive15) /* 0x3f0 */
+ mx28_reg_32(hw_pinctrl_drive16) /* 0x400 */
+ mx28_reg_32(hw_pinctrl_drive17) /* 0x410 */
+ mx28_reg_32(hw_pinctrl_drive18) /* 0x420 */
+ mx28_reg_32(hw_pinctrl_drive19) /* 0x430 */
uint32_t reserved3[112];
- mx28_reg(hw_pinctrl_pull0) /* 0x600 */
- mx28_reg(hw_pinctrl_pull1) /* 0x610 */
- mx28_reg(hw_pinctrl_pull2) /* 0x620 */
- mx28_reg(hw_pinctrl_pull3) /* 0x630 */
- mx28_reg(hw_pinctrl_pull4) /* 0x640 */
- mx28_reg(hw_pinctrl_pull5) /* 0x650 */
- mx28_reg(hw_pinctrl_pull6) /* 0x660 */
+ mx28_reg_32(hw_pinctrl_pull0) /* 0x600 */
+ mx28_reg_32(hw_pinctrl_pull1) /* 0x610 */
+ mx28_reg_32(hw_pinctrl_pull2) /* 0x620 */
+ mx28_reg_32(hw_pinctrl_pull3) /* 0x630 */
+ mx28_reg_32(hw_pinctrl_pull4) /* 0x640 */
+ mx28_reg_32(hw_pinctrl_pull5) /* 0x650 */
+ mx28_reg_32(hw_pinctrl_pull6) /* 0x660 */
uint32_t reserved4[36];
- mx28_reg(hw_pinctrl_dout0) /* 0x700 */
- mx28_reg(hw_pinctrl_dout1) /* 0x710 */
- mx28_reg(hw_pinctrl_dout2) /* 0x720 */
- mx28_reg(hw_pinctrl_dout3) /* 0x730 */
- mx28_reg(hw_pinctrl_dout4) /* 0x740 */
+ mx28_reg_32(hw_pinctrl_dout0) /* 0x700 */
+ mx28_reg_32(hw_pinctrl_dout1) /* 0x710 */
+ mx28_reg_32(hw_pinctrl_dout2) /* 0x720 */
+ mx28_reg_32(hw_pinctrl_dout3) /* 0x730 */
+ mx28_reg_32(hw_pinctrl_dout4) /* 0x740 */
uint32_t reserved5[108];
- mx28_reg(hw_pinctrl_din0) /* 0x900 */
- mx28_reg(hw_pinctrl_din1) /* 0x910 */
- mx28_reg(hw_pinctrl_din2) /* 0x920 */
- mx28_reg(hw_pinctrl_din3) /* 0x930 */
- mx28_reg(hw_pinctrl_din4) /* 0x940 */
+ mx28_reg_32(hw_pinctrl_din0) /* 0x900 */
+ mx28_reg_32(hw_pinctrl_din1) /* 0x910 */
+ mx28_reg_32(hw_pinctrl_din2) /* 0x920 */
+ mx28_reg_32(hw_pinctrl_din3) /* 0x930 */
+ mx28_reg_32(hw_pinctrl_din4) /* 0x940 */
uint32_t reserved6[108];
- mx28_reg(hw_pinctrl_doe0) /* 0xb00 */
- mx28_reg(hw_pinctrl_doe1) /* 0xb10 */
- mx28_reg(hw_pinctrl_doe2) /* 0xb20 */
- mx28_reg(hw_pinctrl_doe3) /* 0xb30 */
- mx28_reg(hw_pinctrl_doe4) /* 0xb40 */
+ mx28_reg_32(hw_pinctrl_doe0) /* 0xb00 */
+ mx28_reg_32(hw_pinctrl_doe1) /* 0xb10 */
+ mx28_reg_32(hw_pinctrl_doe2) /* 0xb20 */
+ mx28_reg_32(hw_pinctrl_doe3) /* 0xb30 */
+ mx28_reg_32(hw_pinctrl_doe4) /* 0xb40 */
uint32_t reserved7[300];
- mx28_reg(hw_pinctrl_pin2irq0) /* 0x1000 */
- mx28_reg(hw_pinctrl_pin2irq1) /* 0x1010 */
- mx28_reg(hw_pinctrl_pin2irq2) /* 0x1020 */
- mx28_reg(hw_pinctrl_pin2irq3) /* 0x1030 */
- mx28_reg(hw_pinctrl_pin2irq4) /* 0x1040 */
+ mx28_reg_32(hw_pinctrl_pin2irq0) /* 0x1000 */
+ mx28_reg_32(hw_pinctrl_pin2irq1) /* 0x1010 */
+ mx28_reg_32(hw_pinctrl_pin2irq2) /* 0x1020 */
+ mx28_reg_32(hw_pinctrl_pin2irq3) /* 0x1030 */
+ mx28_reg_32(hw_pinctrl_pin2irq4) /* 0x1040 */
uint32_t reserved8[44];
- mx28_reg(hw_pinctrl_irqen0) /* 0x1100 */
- mx28_reg(hw_pinctrl_irqen1) /* 0x1110 */
- mx28_reg(hw_pinctrl_irqen2) /* 0x1120 */
- mx28_reg(hw_pinctrl_irqen3) /* 0x1130 */
- mx28_reg(hw_pinctrl_irqen4) /* 0x1140 */
+ mx28_reg_32(hw_pinctrl_irqen0) /* 0x1100 */
+ mx28_reg_32(hw_pinctrl_irqen1) /* 0x1110 */
+ mx28_reg_32(hw_pinctrl_irqen2) /* 0x1120 */
+ mx28_reg_32(hw_pinctrl_irqen3) /* 0x1130 */
+ mx28_reg_32(hw_pinctrl_irqen4) /* 0x1140 */
uint32_t reserved9[44];
- mx28_reg(hw_pinctrl_irqlevel0) /* 0x1200 */
- mx28_reg(hw_pinctrl_irqlevel1) /* 0x1210 */
- mx28_reg(hw_pinctrl_irqlevel2) /* 0x1220 */
- mx28_reg(hw_pinctrl_irqlevel3) /* 0x1230 */
- mx28_reg(hw_pinctrl_irqlevel4) /* 0x1240 */
+ mx28_reg_32(hw_pinctrl_irqlevel0) /* 0x1200 */
+ mx28_reg_32(hw_pinctrl_irqlevel1) /* 0x1210 */
+ mx28_reg_32(hw_pinctrl_irqlevel2) /* 0x1220 */
+ mx28_reg_32(hw_pinctrl_irqlevel3) /* 0x1230 */
+ mx28_reg_32(hw_pinctrl_irqlevel4) /* 0x1240 */
uint32_t reserved10[44];
- mx28_reg(hw_pinctrl_irqpol0) /* 0x1300 */
- mx28_reg(hw_pinctrl_irqpol1) /* 0x1310 */
- mx28_reg(hw_pinctrl_irqpol2) /* 0x1320 */
- mx28_reg(hw_pinctrl_irqpol3) /* 0x1330 */
- mx28_reg(hw_pinctrl_irqpol4) /* 0x1340 */
+ mx28_reg_32(hw_pinctrl_irqpol0) /* 0x1300 */
+ mx28_reg_32(hw_pinctrl_irqpol1) /* 0x1310 */
+ mx28_reg_32(hw_pinctrl_irqpol2) /* 0x1320 */
+ mx28_reg_32(hw_pinctrl_irqpol3) /* 0x1330 */
+ mx28_reg_32(hw_pinctrl_irqpol4) /* 0x1340 */
uint32_t reserved11[44];
- mx28_reg(hw_pinctrl_irqstat0) /* 0x1400 */
- mx28_reg(hw_pinctrl_irqstat1) /* 0x1410 */
- mx28_reg(hw_pinctrl_irqstat2) /* 0x1420 */
- mx28_reg(hw_pinctrl_irqstat3) /* 0x1430 */
- mx28_reg(hw_pinctrl_irqstat4) /* 0x1440 */
+ mx28_reg_32(hw_pinctrl_irqstat0) /* 0x1400 */
+ mx28_reg_32(hw_pinctrl_irqstat1) /* 0x1410 */
+ mx28_reg_32(hw_pinctrl_irqstat2) /* 0x1420 */
+ mx28_reg_32(hw_pinctrl_irqstat3) /* 0x1430 */
+ mx28_reg_32(hw_pinctrl_irqstat4) /* 0x1440 */
uint32_t reserved12[380];
- mx28_reg(hw_pinctrl_emi_odt_ctrl) /* 0x1a40 */
+ mx28_reg_32(hw_pinctrl_emi_odt_ctrl) /* 0x1a40 */
uint32_t reserved13[76];
- mx28_reg(hw_pinctrl_emi_ds_ctrl) /* 0x1b80 */
+ mx28_reg_32(hw_pinctrl_emi_ds_ctrl) /* 0x1b80 */
};
#endif
#ifndef __ASSEMBLY__
struct mx28_power_regs {
- mx28_reg(hw_power_ctrl)
- mx28_reg(hw_power_5vctrl)
- mx28_reg(hw_power_minpwr)
- mx28_reg(hw_power_charge)
+ mx28_reg_32(hw_power_ctrl)
+ mx28_reg_32(hw_power_5vctrl)
+ mx28_reg_32(hw_power_minpwr)
+ mx28_reg_32(hw_power_charge)
uint32_t hw_power_vdddctrl;
uint32_t reserved_vddd[3];
uint32_t hw_power_vddactrl;
uint32_t reserved_misc[3];
uint32_t hw_power_dclimits;
uint32_t reserved_dclimits[3];
- mx28_reg(hw_power_loopctrl)
+ mx28_reg_32(hw_power_loopctrl)
uint32_t hw_power_sts;
uint32_t reserved_sts[3];
- mx28_reg(hw_power_speed)
+ mx28_reg_32(hw_power_speed)
uint32_t hw_power_battmonitor;
uint32_t reserved_battmonitor[3];
uint32_t reserved[4];
- mx28_reg(hw_power_reset)
- mx28_reg(hw_power_debug)
- mx28_reg(hw_power_thermal)
- mx28_reg(hw_power_usb1ctrl)
- mx28_reg(hw_power_special)
- mx28_reg(hw_power_version)
- mx28_reg(hw_power_anaclkctrl)
- mx28_reg(hw_power_refctrl)
+ mx28_reg_32(hw_power_reset)
+ mx28_reg_32(hw_power_debug)
+ mx28_reg_32(hw_power_thermal)
+ mx28_reg_32(hw_power_usb1ctrl)
+ mx28_reg_32(hw_power_special)
+ mx28_reg_32(hw_power_version)
+ mx28_reg_32(hw_power_anaclkctrl)
+ mx28_reg_32(hw_power_refctrl)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_rtc_regs {
- mx28_reg(hw_rtc_ctrl)
- mx28_reg(hw_rtc_stat)
- mx28_reg(hw_rtc_milliseconds)
- mx28_reg(hw_rtc_seconds)
- mx28_reg(hw_rtc_rtc_alarm)
- mx28_reg(hw_rtc_watchdog)
- mx28_reg(hw_rtc_persistent0)
- mx28_reg(hw_rtc_persistent1)
- mx28_reg(hw_rtc_persistent2)
- mx28_reg(hw_rtc_persistent3)
- mx28_reg(hw_rtc_persistent4)
- mx28_reg(hw_rtc_persistent5)
- mx28_reg(hw_rtc_debug)
- mx28_reg(hw_rtc_version)
+ mx28_reg_32(hw_rtc_ctrl)
+ mx28_reg_32(hw_rtc_stat)
+ mx28_reg_32(hw_rtc_milliseconds)
+ mx28_reg_32(hw_rtc_seconds)
+ mx28_reg_32(hw_rtc_rtc_alarm)
+ mx28_reg_32(hw_rtc_watchdog)
+ mx28_reg_32(hw_rtc_persistent0)
+ mx28_reg_32(hw_rtc_persistent1)
+ mx28_reg_32(hw_rtc_persistent2)
+ mx28_reg_32(hw_rtc_persistent3)
+ mx28_reg_32(hw_rtc_persistent4)
+ mx28_reg_32(hw_rtc_persistent5)
+ mx28_reg_32(hw_rtc_debug)
+ mx28_reg_32(hw_rtc_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_ssp_regs {
- mx28_reg(hw_ssp_ctrl0)
- mx28_reg(hw_ssp_cmd0)
- mx28_reg(hw_ssp_cmd1)
- mx28_reg(hw_ssp_xfer_size)
- mx28_reg(hw_ssp_block_size)
- mx28_reg(hw_ssp_compref)
- mx28_reg(hw_ssp_compmask)
- mx28_reg(hw_ssp_timing)
- mx28_reg(hw_ssp_ctrl1)
- mx28_reg(hw_ssp_data)
- mx28_reg(hw_ssp_sdresp0)
- mx28_reg(hw_ssp_sdresp1)
- mx28_reg(hw_ssp_sdresp2)
- mx28_reg(hw_ssp_sdresp3)
- mx28_reg(hw_ssp_ddr_ctrl)
- mx28_reg(hw_ssp_dll_ctrl)
- mx28_reg(hw_ssp_status)
- mx28_reg(hw_ssp_dll_sts)
- mx28_reg(hw_ssp_debug)
- mx28_reg(hw_ssp_version)
+ mx28_reg_32(hw_ssp_ctrl0)
+ mx28_reg_32(hw_ssp_cmd0)
+ mx28_reg_32(hw_ssp_cmd1)
+ mx28_reg_32(hw_ssp_xfer_size)
+ mx28_reg_32(hw_ssp_block_size)
+ mx28_reg_32(hw_ssp_compref)
+ mx28_reg_32(hw_ssp_compmask)
+ mx28_reg_32(hw_ssp_timing)
+ mx28_reg_32(hw_ssp_ctrl1)
+ mx28_reg_32(hw_ssp_data)
+ mx28_reg_32(hw_ssp_sdresp0)
+ mx28_reg_32(hw_ssp_sdresp1)
+ mx28_reg_32(hw_ssp_sdresp2)
+ mx28_reg_32(hw_ssp_sdresp3)
+ mx28_reg_32(hw_ssp_ddr_ctrl)
+ mx28_reg_32(hw_ssp_dll_ctrl)
+ mx28_reg_32(hw_ssp_status)
+ mx28_reg_32(hw_ssp_dll_sts)
+ mx28_reg_32(hw_ssp_debug)
+ mx28_reg_32(hw_ssp_version)
};
#endif
#ifndef __ASSEMBLY__
struct mx28_timrot_regs {
- mx28_reg(hw_timrot_rotctrl)
- mx28_reg(hw_timrot_rotcount)
- mx28_reg(hw_timrot_timctrl0)
- mx28_reg(hw_timrot_running_count0)
- mx28_reg(hw_timrot_fixed_count0)
- mx28_reg(hw_timrot_match_count0)
- mx28_reg(hw_timrot_timctrl1)
- mx28_reg(hw_timrot_running_count1)
- mx28_reg(hw_timrot_fixed_count1)
- mx28_reg(hw_timrot_match_count1)
- mx28_reg(hw_timrot_timctrl2)
- mx28_reg(hw_timrot_running_count2)
- mx28_reg(hw_timrot_fixed_count2)
- mx28_reg(hw_timrot_match_count2)
- mx28_reg(hw_timrot_timctrl3)
- mx28_reg(hw_timrot_running_count3)
- mx28_reg(hw_timrot_fixed_count3)
- mx28_reg(hw_timrot_match_count3)
- mx28_reg(hw_timrot_version)
+ mx28_reg_32(hw_timrot_rotctrl)
+ mx28_reg_32(hw_timrot_rotcount)
+ mx28_reg_32(hw_timrot_timctrl0)
+ mx28_reg_32(hw_timrot_running_count0)
+ mx28_reg_32(hw_timrot_fixed_count0)
+ mx28_reg_32(hw_timrot_match_count0)
+ mx28_reg_32(hw_timrot_timctrl1)
+ mx28_reg_32(hw_timrot_running_count1)
+ mx28_reg_32(hw_timrot_fixed_count1)
+ mx28_reg_32(hw_timrot_match_count1)
+ mx28_reg_32(hw_timrot_timctrl2)
+ mx28_reg_32(hw_timrot_running_count2)
+ mx28_reg_32(hw_timrot_fixed_count2)
+ mx28_reg_32(hw_timrot_match_count2)
+ mx28_reg_32(hw_timrot_timctrl3)
+ mx28_reg_32(hw_timrot_running_count3)
+ mx28_reg_32(hw_timrot_fixed_count3)
+ mx28_reg_32(hw_timrot_match_count3)
+ mx28_reg_32(hw_timrot_version)
};
#endif
#define __REGS_USBPHY_H__
struct mx28_usbphy_regs {
- mx28_reg(hw_usbphy_pwd)
- mx28_reg(hw_usbphy_tx)
- mx28_reg(hw_usbphy_rx)
- mx28_reg(hw_usbphy_ctrl)
- mx28_reg(hw_usbphy_status)
- mx28_reg(hw_usbphy_debug)
- mx28_reg(hw_usbphy_debug0_status)
- mx28_reg(hw_usbphy_debug1)
- mx28_reg(hw_usbphy_version)
- mx28_reg(hw_usbphy_ip)
+ mx28_reg_32(hw_usbphy_pwd)
+ mx28_reg_32(hw_usbphy_tx)
+ mx28_reg_32(hw_usbphy_rx)
+ mx28_reg_32(hw_usbphy_ctrl)
+ mx28_reg_32(hw_usbphy_status)
+ mx28_reg_32(hw_usbphy_debug)
+ mx28_reg_32(hw_usbphy_debug0_status)
+ mx28_reg_32(hw_usbphy_debug1)
+ mx28_reg_32(hw_usbphy_version)
+ mx28_reg_32(hw_usbphy_ip)
};
#define USBPHY_PWD_RXPWDRX (1 << 20)
#ifndef __MX28_H__
#define __MX28_H__
-int mx28_reset_block(struct mx28_register *reg);
-int mx28_wait_mask_set(struct mx28_register *reg, uint32_t mask, int timeout);
-int mx28_wait_mask_clr(struct mx28_register *reg, uint32_t mask, int timeout);
+int mx28_reset_block(struct mx28_register_32 *reg);
+int mx28_wait_mask_set(struct mx28_register_32 *reg,
+ uint32_t mask,
+ int timeout);
+int mx28_wait_mask_clr(struct mx28_register_32 *reg,
+ uint32_t mask,
+ int timeout);
int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int));
#define MXC_EHCI_IPPUE_DOWN (1 << 8)
#define MXC_EHCI_IPPUE_UP (1 << 9)
+/*
+ * CSPI register definitions
+ */
+#define MXC_CSPI
+#define MXC_CSPICTRL_EN (1 << 0)
+#define MXC_CSPICTRL_MODE (1 << 1)
+#define MXC_CSPICTRL_XCH (1 << 2)
+#define MXC_CSPICTRL_SMC (1 << 3)
+#define MXC_CSPICTRL_POL (1 << 4)
+#define MXC_CSPICTRL_PHA (1 << 5)
+#define MXC_CSPICTRL_SSCTL (1 << 6)
+#define MXC_CSPICTRL_SSPOL (1 << 7)
+#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 24)
+#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0x1f) << 8)
+#define MXC_CSPICTRL_DATARATE(x) (((x) & 0x7) << 16)
+#define MXC_CSPICTRL_TC (1 << 8)
+#define MXC_CSPICTRL_RXOVF (1 << 6)
+#define MXC_CSPICTRL_MAXBITS 0x1f
+
+#define MXC_CSPIPERIOD_32KHZ (1 << 15)
+#define MAX_SPI_BYTES 4
+
+#define MXC_SPI_BASE_ADDRESSES \
+ 0x43fa4000, \
+ 0x50010000, \
+ 0x53f84000,
+
#endif /* __ASM_ARCH_MX31_IMX_REGS_H */
void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs);
int mxc_mmc_init(bd_t *bis);
+u32 get_cpu_rev(void);
#endif
#define IPU_CONF_IC_EN (1<<1)
#define IPU_CONF_SCI_EN (1<<0)
+/*
+ * CSPI register definitions
+ */
+#define MXC_CSPI
+#define MXC_CSPICTRL_EN (1 << 0)
+#define MXC_CSPICTRL_MODE (1 << 1)
+#define MXC_CSPICTRL_XCH (1 << 2)
+#define MXC_CSPICTRL_SMC (1 << 3)
+#define MXC_CSPICTRL_POL (1 << 4)
+#define MXC_CSPICTRL_PHA (1 << 5)
+#define MXC_CSPICTRL_SSCTL (1 << 6)
+#define MXC_CSPICTRL_SSPOL (1 << 7)
+#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 12)
+#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0xfff) << 20)
+#define MXC_CSPICTRL_DATARATE(x) (((x) & 0x7) << 16)
+#define MXC_CSPICTRL_TC (1 << 7)
+#define MXC_CSPICTRL_RXOVF (1 << 6)
+#define MXC_CSPICTRL_MAXBITS 0xfff
+#define MXC_CSPIPERIOD_32KHZ (1 << 15)
+#define MAX_SPI_BYTES 4
+
+#define MXC_SPI_BASE_ADDRESSES \
+ 0x43fa4000, \
+ 0x50010000,
+
#define GPIO_PORT_NUM 3
#define GPIO_NUM_PIN 32
#define CS0_64M_CS1_32M_CS2_32M 2
#define CS0_32M_CS1_32M_CS2_32M_CS3_32M 3
+/*
+ * CSPI register definitions
+ */
+#define MXC_ECSPI
+#define MXC_CSPICTRL_EN (1 << 0)
+#define MXC_CSPICTRL_MODE (1 << 1)
+#define MXC_CSPICTRL_XCH (1 << 2)
+#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 12)
+#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0xfff) << 20)
+#define MXC_CSPICTRL_PREDIV(x) (((x) & 0xF) << 12)
+#define MXC_CSPICTRL_POSTDIV(x) (((x) & 0xF) << 8)
+#define MXC_CSPICTRL_SELCHAN(x) (((x) & 0x3) << 18)
+#define MXC_CSPICTRL_MAXBITS 0xfff
+#define MXC_CSPICTRL_TC (1 << 7)
+#define MXC_CSPICTRL_RXOVF (1 << 6)
+#define MXC_CSPIPERIOD_32KHZ (1 << 15)
+#define MAX_SPI_BYTES 32
+
+/* Bit position inside CTRL register to be associated with SS */
+#define MXC_CSPICTRL_CHAN 18
+
+/* Bit position inside CON register to be associated with SS */
+#define MXC_CSPICON_POL 4
+#define MXC_CSPICON_PHA 0
+#define MXC_CSPICON_SSPOL 12
+#define MXC_SPI_BASE_ADDRESSES \
+ CSPI1_BASE_ADDR, \
+ CSPI2_BASE_ADDR, \
+ CSPI3_BASE_ADDR,
+
/*
* Number of GPIO pins per port
*/
u32 imx_get_uartclk(void);
u32 imx_get_fecclk(void);
unsigned int mxc_get_clock(enum mxc_clock clk);
+void enable_usboh3_clk(unsigned char enable);
#endif /* __ASM_ARCH_CLOCK_H */
#define KPP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x38000)
#define WDOG1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x3C000)
#define WDOG2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x40000)
-#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
#define ANATOP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x48000)
+#define USB_PHY0_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x49000)
+#define USB_PHY1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4a000)
+#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
#define SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
#define EPIT1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x50000)
#define EPIT2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x54000)
#define CHIP_REV_1_0 0x10
#define IRAM_SIZE 0x00040000
#define IMX_IIM_BASE OCOTP_BASE_ADDR
+#define FEC_QUIRK_ENET_MAC
+
+#define GPIO_NUMBER(port, index) ((((port)-1)*32)+((index)&31))
+#define GPIO_TO_PORT(number) (((number)/32)+1)
+#define GPIO_TO_INDEX(number) ((number)&31)
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
#include <asm/types.h>
u32 gpr10;
};
+/* ECSPI registers */
+struct cspi_regs {
+ u32 rxdata;
+ u32 txdata;
+ u32 ctrl;
+ u32 cfg;
+ u32 intr;
+ u32 dma;
+ u32 stat;
+ u32 period;
+};
+
+/*
+ * CSPI register definitions
+ */
+#define MXC_ECSPI
+#define MXC_CSPICTRL_EN (1 << 0)
+#define MXC_CSPICTRL_MODE (1 << 1)
+#define MXC_CSPICTRL_XCH (1 << 2)
+#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 12)
+#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0xfff) << 20)
+#define MXC_CSPICTRL_PREDIV(x) (((x) & 0xF) << 12)
+#define MXC_CSPICTRL_POSTDIV(x) (((x) & 0xF) << 8)
+#define MXC_CSPICTRL_SELCHAN(x) (((x) & 0x3) << 18)
+#define MXC_CSPICTRL_MAXBITS 0xfff
+#define MXC_CSPICTRL_TC (1 << 7)
+#define MXC_CSPICTRL_RXOVF (1 << 6)
+#define MXC_CSPIPERIOD_32KHZ (1 << 15)
+#define MAX_SPI_BYTES 32
+
+/* Bit position inside CTRL register to be associated with SS */
+#define MXC_CSPICTRL_CHAN 18
+
+/* Bit position inside CON register to be associated with SS */
+#define MXC_CSPICON_POL 4
+#define MXC_CSPICON_PHA 0
+#define MXC_CSPICON_SSPOL 12
+#define MXC_SPI_BASE_ADDRESSES \
+ ECSPI1_BASE_ADDR, \
+ ECSPI2_BASE_ADDR, \
+ ECSPI3_BASE_ADDR, \
+ ECSPI4_BASE_ADDR, \
+ ECSPI5_BASE_ADDR
+
struct iim_regs {
u32 ctrl;
u32 ctrl_set;
u32 opacr4;
};
+struct anatop_regs {
+ u32 pll_sys; /* 0x000 */
+ u32 pll_sys_set; /* 0x004 */
+ u32 pll_sys_clr; /* 0x008 */
+ u32 pll_sys_tog; /* 0x00c */
+ u32 usb1_pll_480_ctrl; /* 0x010 */
+ u32 usb1_pll_480_ctrl_set; /* 0x014 */
+ u32 usb1_pll_480_ctrl_clr; /* 0x018 */
+ u32 usb1_pll_480_ctrl_tog; /* 0x01c */
+ u32 usb2_pll_480_ctrl; /* 0x020 */
+ u32 usb2_pll_480_ctrl_set; /* 0x024 */
+ u32 usb2_pll_480_ctrl_clr; /* 0x028 */
+ u32 usb2_pll_480_ctrl_tog; /* 0x02c */
+ u32 pll_528; /* 0x030 */
+ u32 pll_528_set; /* 0x034 */
+ u32 pll_528_clr; /* 0x038 */
+ u32 pll_528_tog; /* 0x03c */
+ u32 pll_528_ss; /* 0x040 */
+ u32 rsvd0[3];
+ u32 pll_528_num; /* 0x050 */
+ u32 rsvd1[3];
+ u32 pll_528_denom; /* 0x060 */
+ u32 rsvd2[3];
+ u32 pll_audio; /* 0x070 */
+ u32 pll_audio_set; /* 0x074 */
+ u32 pll_audio_clr; /* 0x078 */
+ u32 pll_audio_tog; /* 0x07c */
+ u32 pll_audio_num; /* 0x080 */
+ u32 rsvd3[3];
+ u32 pll_audio_denom; /* 0x090 */
+ u32 rsvd4[3];
+ u32 pll_video; /* 0x0a0 */
+ u32 pll_video_set; /* 0x0a4 */
+ u32 pll_video_clr; /* 0x0a8 */
+ u32 pll_video_tog; /* 0x0ac */
+ u32 pll_video_num; /* 0x0b0 */
+ u32 rsvd5[3];
+ u32 pll_video_denom; /* 0x0c0 */
+ u32 rsvd6[3];
+ u32 pll_mlb; /* 0x0d0 */
+ u32 pll_mlb_set; /* 0x0d4 */
+ u32 pll_mlb_clr; /* 0x0d8 */
+ u32 pll_mlb_tog; /* 0x0dc */
+ u32 pll_enet; /* 0x0e0 */
+ u32 pll_enet_set; /* 0x0e4 */
+ u32 pll_enet_clr; /* 0x0e8 */
+ u32 pll_enet_tog; /* 0x0ec */
+ u32 pfd_480; /* 0x0f0 */
+ u32 pfd_480_set; /* 0x0f4 */
+ u32 pfd_480_clr; /* 0x0f8 */
+ u32 pfd_480_tog; /* 0x0fc */
+ u32 pfd_528; /* 0x100 */
+ u32 pfd_528_set; /* 0x104 */
+ u32 pfd_528_clr; /* 0x108 */
+ u32 pfd_528_tog; /* 0x10c */
+ u32 reg_1p1; /* 0x110 */
+ u32 reg_1p1_set; /* 0x114 */
+ u32 reg_1p1_clr; /* 0x118 */
+ u32 reg_1p1_tog; /* 0x11c */
+ u32 reg_3p0; /* 0x120 */
+ u32 reg_3p0_set; /* 0x124 */
+ u32 reg_3p0_clr; /* 0x128 */
+ u32 reg_3p0_tog; /* 0x12c */
+ u32 reg_2p5; /* 0x130 */
+ u32 reg_2p5_set; /* 0x134 */
+ u32 reg_2p5_clr; /* 0x138 */
+ u32 reg_2p5_tog; /* 0x13c */
+ u32 reg_core; /* 0x140 */
+ u32 reg_core_set; /* 0x144 */
+ u32 reg_core_clr; /* 0x148 */
+ u32 reg_core_tog; /* 0x14c */
+ u32 ana_misc0; /* 0x150 */
+ u32 ana_misc0_set; /* 0x154 */
+ u32 ana_misc0_clr; /* 0x158 */
+ u32 ana_misc0_tog; /* 0x15c */
+ u32 ana_misc1; /* 0x160 */
+ u32 ana_misc1_set; /* 0x164 */
+ u32 ana_misc1_clr; /* 0x168 */
+ u32 ana_misc1_tog; /* 0x16c */
+ u32 ana_misc2; /* 0x170 */
+ u32 ana_misc2_set; /* 0x174 */
+ u32 ana_misc2_clr; /* 0x178 */
+ u32 ana_misc2_tog; /* 0x17c */
+ u32 tempsense0; /* 0x180 */
+ u32 tempsense0_set; /* 0x184 */
+ u32 tempsense0_clr; /* 0x188 */
+ u32 tempsense0_tog; /* 0x18c */
+ u32 tempsense1; /* 0x190 */
+ u32 tempsense1_set; /* 0x194 */
+ u32 tempsense1_clr; /* 0x198 */
+ u32 tempsense1_tog; /* 0x19c */
+ u32 usb1_vbus_detect; /* 0x1a0 */
+ u32 usb1_vbus_detect_set; /* 0x1a4 */
+ u32 usb1_vbus_detect_clr; /* 0x1a8 */
+ u32 usb1_vbus_detect_tog; /* 0x1ac */
+ u32 usb1_chrg_detect; /* 0x1b0 */
+ u32 usb1_chrg_detect_set; /* 0x1b4 */
+ u32 usb1_chrg_detect_clr; /* 0x1b8 */
+ u32 usb1_chrg_detect_tog; /* 0x1bc */
+ u32 usb1_vbus_det_stat; /* 0x1c0 */
+ u32 usb1_vbus_det_stat_set; /* 0x1c4 */
+ u32 usb1_vbus_det_stat_clr; /* 0x1c8 */
+ u32 usb1_vbus_det_stat_tog; /* 0x1cc */
+ u32 usb1_chrg_det_stat; /* 0x1d0 */
+ u32 usb1_chrg_det_stat_set; /* 0x1d4 */
+ u32 usb1_chrg_det_stat_clr; /* 0x1d8 */
+ u32 usb1_chrg_det_stat_tog; /* 0x1dc */
+ u32 usb1_loopback; /* 0x1e0 */
+ u32 usb1_loopback_set; /* 0x1e4 */
+ u32 usb1_loopback_clr; /* 0x1e8 */
+ u32 usb1_loopback_tog; /* 0x1ec */
+ u32 usb1_misc; /* 0x1f0 */
+ u32 usb1_misc_set; /* 0x1f4 */
+ u32 usb1_misc_clr; /* 0x1f8 */
+ u32 usb1_misc_tog; /* 0x1fc */
+ u32 usb2_vbus_detect; /* 0x200 */
+ u32 usb2_vbus_detect_set; /* 0x204 */
+ u32 usb2_vbus_detect_clr; /* 0x208 */
+ u32 usb2_vbus_detect_tog; /* 0x20c */
+ u32 usb2_chrg_detect; /* 0x210 */
+ u32 usb2_chrg_detect_set; /* 0x214 */
+ u32 usb2_chrg_detect_clr; /* 0x218 */
+ u32 usb2_chrg_detect_tog; /* 0x21c */
+ u32 usb2_vbus_det_stat; /* 0x220 */
+ u32 usb2_vbus_det_stat_set; /* 0x224 */
+ u32 usb2_vbus_det_stat_clr; /* 0x228 */
+ u32 usb2_vbus_det_stat_tog; /* 0x22c */
+ u32 usb2_chrg_det_stat; /* 0x230 */
+ u32 usb2_chrg_det_stat_set; /* 0x234 */
+ u32 usb2_chrg_det_stat_clr; /* 0x238 */
+ u32 usb2_chrg_det_stat_tog; /* 0x23c */
+ u32 usb2_loopback; /* 0x240 */
+ u32 usb2_loopback_set; /* 0x244 */
+ u32 usb2_loopback_clr; /* 0x248 */
+ u32 usb2_loopback_tog; /* 0x24c */
+ u32 usb2_misc; /* 0x250 */
+ u32 usb2_misc_set; /* 0x254 */
+ u32 usb2_misc_clr; /* 0x258 */
+ u32 usb2_misc_tog; /* 0x25c */
+ u32 digprog; /* 0x260 */
+};
+
#endif /* __ASSEMBLER__*/
#endif /* __ASM_ARCH_MX6_IMX_REGS_H__ */
#define OSC_FREQ_SHIFT 30
#define OSC_FREQ_MASK (3U << OSC_FREQ_SHIFT)
-/* CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 */
+/*
+ * CLK_RST_CONTROLLER_CLK_SOURCE_x_OUT_0 - the mask here is normally 8 bits
+ * but can be 16. We could use knowledge we have to restrict the mask in
+ * the 8-bit cases (the divider_bits value returned by
+ * get_periph_clock_source()) but it does not seem worth it since the code
+ * already checks the ranges of values it is writing, in clk_get_divider().
+ */
#define OUT_CLK_DIVISOR_SHIFT 0
-#define OUT_CLK_DIVISOR_MASK (255 << OUT_CLK_DIVISOR_SHIFT)
+#define OUT_CLK_DIVISOR_MASK (0xffff << OUT_CLK_DIVISOR_SHIFT)
#define OUT_CLK_SOURCE_SHIFT 30
#define OUT_CLK_SOURCE_MASK (3U << OUT_CLK_SOURCE_SHIFT)
PERIPH_ID_CRAM2,
PERIPH_ID_COUNT,
+ PERIPH_ID_NONE = -1,
};
/* Converts a clock number to a clock register: 0=L, 1=H, 2=U */
*/
void clock_ll_start_uart(enum periph_id periph_id);
+/**
+ * Decode a peripheral ID from a device tree node.
+ *
+ * This works by looking up the peripheral's 'clocks' node and reading out
+ * the second cell, which is the clock number / peripheral ID.
+ *
+ * @param blob FDT blob to use
+ * @param node Node to look at
+ * @return peripheral ID, or PERIPH_ID_NONE if none
+ */
+enum periph_id clock_decode_periph_id(const void *blob, int node);
+
/*
* Checks that clocks are valid and prints a warning if not
*
#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300)
#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
#define TEGRA2_SPI_BASE (NV_PA_APB_MISC_BASE + 0xC380)
-#define NV_PA_PMC_BASE 0x7000E400
+#define TEGRA2_PMC_BASE (NV_PA_APB_MISC_BASE + 0xE400)
#define NV_PA_CSITE_BASE 0x70040000
+#define TEGRA_USB1_BASE 0xC5000000
+#define TEGRA_USB3_BASE 0xC5008000
#define TEGRA2_SDRC_CS0 NV_PA_SDRAM_BASE
#define LOW_LEVEL_SRAM_STACK 0x4000FFFC
unsigned int cntr_1us;
};
#else /* __ASSEMBLY__ */
-#define PRM_RSTCTRL NV_PA_PMC_BASE
+#define PRM_RSTCTRL TEGRA2_PMC_BASE
#endif
#endif /* TEGRA2_H */
--- /dev/null
+/*
+ * NVIDIA Tegra2 I2C controller
+ *
+ * Copyright 2010-2011 NVIDIA Corporation
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _TEGRA_I2C_H_
+#define _TEGRA_I2C_H_
+
+#include <asm/types.h>
+
+enum {
+ I2C_TIMEOUT_USEC = 10000, /* Wait time for completion */
+ I2C_FIFO_DEPTH = 8, /* I2C fifo depth */
+};
+
+enum i2c_transaction_flags {
+ I2C_IS_WRITE = 0x1, /* for I2C write operation */
+ I2C_IS_10_BIT_ADDRESS = 0x2, /* for 10-bit I2C slave address */
+ I2C_USE_REPEATED_START = 0x4, /* for repeat start */
+ I2C_NO_ACK = 0x8, /* for slave that won't generate ACK */
+ I2C_SOFTWARE_CONTROLLER = 0x10, /* for I2C transfer using GPIO */
+ I2C_NO_STOP = 0x20,
+};
+
+/* Contians the I2C transaction details */
+struct i2c_trans_info {
+ /* flags to indicate the transaction details */
+ enum i2c_transaction_flags flags;
+ u32 address; /* I2C slave device address */
+ u32 num_bytes; /* number of bytes to be transferred */
+ /*
+ * Send/receive buffer. For the I2C send operation this buffer should
+ * be filled with the data to be sent to the slave device. For the I2C
+ * receive operation this buffer is filled with the data received from
+ * the slave device.
+ */
+ u8 *buf;
+ int is_10bit_address;
+};
+
+struct i2c_control {
+ u32 tx_fifo;
+ u32 rx_fifo;
+ u32 packet_status;
+ u32 fifo_control;
+ u32 fifo_status;
+ u32 int_mask;
+ u32 int_status;
+};
+
+struct dvc_ctlr {
+ u32 ctrl1; /* 00: DVC_CTRL_REG1 */
+ u32 ctrl2; /* 04: DVC_CTRL_REG2 */
+ u32 ctrl3; /* 08: DVC_CTRL_REG3 */
+ u32 status; /* 0C: DVC_STATUS_REG */
+ u32 ctrl; /* 10: DVC_I2C_CTRL_REG */
+ u32 addr_data; /* 14: DVC_I2C_ADDR_DATA_REG */
+ u32 reserved_0[2]; /* 18: */
+ u32 req; /* 20: DVC_REQ_REGISTER */
+ u32 addr_data3; /* 24: DVC_I2C_ADDR_DATA_REG_3 */
+ u32 reserved_1[6]; /* 28: */
+ u32 cnfg; /* 40: DVC_I2C_CNFG */
+ u32 cmd_addr0; /* 44: DVC_I2C_CMD_ADDR0 */
+ u32 cmd_addr1; /* 48: DVC_I2C_CMD_ADDR1 */
+ u32 cmd_data1; /* 4C: DVC_I2C_CMD_DATA1 */
+ u32 cmd_data2; /* 50: DVC_I2C_CMD_DATA2 */
+ u32 reserved_2[2]; /* 54: */
+ u32 i2c_status; /* 5C: DVC_I2C_STATUS */
+ struct i2c_control control; /* 60 ~ 78 */
+};
+
+struct i2c_ctlr {
+ u32 cnfg; /* 00: I2C_I2C_CNFG */
+ u32 cmd_addr0; /* 04: I2C_I2C_CMD_ADDR0 */
+ u32 cmd_addr1; /* 08: I2C_I2C_CMD_DATA1 */
+ u32 cmd_data1; /* 0C: I2C_I2C_CMD_DATA2 */
+ u32 cmd_data2; /* 10: DVC_I2C_CMD_DATA2 */
+ u32 reserved_0[2]; /* 14: */
+ u32 status; /* 1C: I2C_I2C_STATUS */
+ u32 sl_cnfg; /* 20: I2C_I2C_SL_CNFG */
+ u32 sl_rcvd; /* 24: I2C_I2C_SL_RCVD */
+ u32 sl_status; /* 28: I2C_I2C_SL_STATUS */
+ u32 sl_addr1; /* 2C: I2C_I2C_SL_ADDR1 */
+ u32 sl_addr2; /* 30: I2C_I2C_SL_ADDR2 */
+ u32 reserved_1[2]; /* 34: */
+ u32 sl_delay_count; /* 3C: I2C_I2C_SL_DELAY_COUNT */
+ u32 reserved_2[4]; /* 40: */
+ struct i2c_control control; /* 50 ~ 68 */
+};
+
+/* bit fields definitions for IO Packet Header 1 format */
+#define PKT_HDR1_PROTOCOL_SHIFT 4
+#define PKT_HDR1_PROTOCOL_MASK (0xf << PKT_HDR1_PROTOCOL_SHIFT)
+#define PKT_HDR1_CTLR_ID_SHIFT 12
+#define PKT_HDR1_CTLR_ID_MASK (0xf << PKT_HDR1_CTLR_ID_SHIFT)
+#define PKT_HDR1_PKT_ID_SHIFT 16
+#define PKT_HDR1_PKT_ID_MASK (0xff << PKT_HDR1_PKT_ID_SHIFT)
+#define PROTOCOL_TYPE_I2C 1
+
+/* bit fields definitions for IO Packet Header 2 format */
+#define PKT_HDR2_PAYLOAD_SIZE_SHIFT 0
+#define PKT_HDR2_PAYLOAD_SIZE_MASK (0xfff << PKT_HDR2_PAYLOAD_SIZE_SHIFT)
+
+/* bit fields definitions for IO Packet Header 3 format */
+#define PKT_HDR3_READ_MODE_SHIFT 19
+#define PKT_HDR3_READ_MODE_MASK (1 << PKT_HDR3_READ_MODE_SHIFT)
+#define PKT_HDR3_SLAVE_ADDR_SHIFT 0
+#define PKT_HDR3_SLAVE_ADDR_MASK (0x3ff << PKT_HDR3_SLAVE_ADDR_SHIFT)
+
+#define DVC_CTRL_REG3_I2C_HW_SW_PROG_SHIFT 26
+#define DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK \
+ (1 << DVC_CTRL_REG3_I2C_HW_SW_PROG_SHIFT)
+
+/* I2C_CNFG */
+#define I2C_CNFG_NEW_MASTER_FSM_SHIFT 11
+#define I2C_CNFG_NEW_MASTER_FSM_MASK (1 << I2C_CNFG_NEW_MASTER_FSM_SHIFT)
+#define I2C_CNFG_PACKET_MODE_SHIFT 10
+#define I2C_CNFG_PACKET_MODE_MASK (1 << I2C_CNFG_PACKET_MODE_SHIFT)
+
+/* I2C_SL_CNFG */
+#define I2C_SL_CNFG_NEWSL_SHIFT 2
+#define I2C_SL_CNFG_NEWSL_MASK (1 << I2C_SL_CNFG_NEWSL_SHIFT)
+
+/* I2C_FIFO_STATUS */
+#define TX_FIFO_FULL_CNT_SHIFT 0
+#define TX_FIFO_FULL_CNT_MASK (0xf << TX_FIFO_FULL_CNT_SHIFT)
+#define TX_FIFO_EMPTY_CNT_SHIFT 4
+#define TX_FIFO_EMPTY_CNT_MASK (0xf << TX_FIFO_EMPTY_CNT_SHIFT)
+
+/* I2C_INTERRUPT_STATUS */
+#define I2C_INT_XFER_COMPLETE_SHIFT 7
+#define I2C_INT_XFER_COMPLETE_MASK (1 << I2C_INT_XFER_COMPLETE_SHIFT)
+#define I2C_INT_NO_ACK_SHIFT 3
+#define I2C_INT_NO_ACK_MASK (1 << I2C_INT_NO_ACK_SHIFT)
+#define I2C_INT_ARBITRATION_LOST_SHIFT 2
+#define I2C_INT_ARBITRATION_LOST_MASK (1 << I2C_INT_ARBITRATION_LOST_SHIFT)
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+#ifndef _TEGRA_USB_H_
+#define _TEGRA_USB_H_
+
+
+/* USB Controller (USBx_CONTROLLER_) regs */
+struct usb_ctlr {
+ /* 0x000 */
+ uint id;
+ uint reserved0;
+ uint host;
+ uint device;
+
+ /* 0x010 */
+ uint txbuf;
+ uint rxbuf;
+ uint reserved1[2];
+
+ /* 0x020 */
+ uint reserved2[56];
+
+ /* 0x100 */
+ u16 cap_length;
+ u16 hci_version;
+ uint hcs_params;
+ uint hcc_params;
+ uint reserved3[5];
+
+ /* 0x120 */
+ uint dci_version;
+ uint dcc_params;
+ uint reserved4[6];
+
+ /* 0x140 */
+ uint usb_cmd;
+ uint usb_sts;
+ uint usb_intr;
+ uint frindex;
+
+ /* 0x150 */
+ uint reserved5;
+ uint periodic_list_base;
+ uint async_list_addr;
+ uint async_tt_sts;
+
+ /* 0x160 */
+ uint burst_size;
+ uint tx_fill_tuning;
+ uint reserved6; /* is this port_sc1 on some controllers? */
+ uint icusb_ctrl;
+
+ /* 0x170 */
+ uint ulpi_viewport;
+ uint reserved7;
+ uint endpt_nak;
+ uint endpt_nak_enable;
+
+ /* 0x180 */
+ uint reserved;
+ uint port_sc1;
+ uint reserved8[6];
+
+ /* 0x1a0 */
+ uint reserved9;
+ uint otgsc;
+ uint usb_mode;
+ uint endpt_setup_stat;
+
+ /* 0x1b0 */
+ uint reserved10[20];
+
+ /* 0x200 */
+ uint reserved11[0x80];
+
+ /* 0x400 */
+ uint susp_ctrl;
+ uint phy_vbus_sensors;
+ uint phy_vbus_wakeup_id;
+ uint phy_alt_vbus_sys;
+
+ /* 0x410 */
+ uint usb1_legacy_ctrl;
+ uint reserved12[3];
+
+ /* 0x420 */
+ uint reserved13[56];
+
+ /* 0x500 */
+ uint reserved14[64 * 3];
+
+ /* 0x800 */
+ uint utmip_pll_cfg0;
+ uint utmip_pll_cfg1;
+ uint utmip_xcvr_cfg0;
+ uint utmip_bias_cfg0;
+
+ /* 0x810 */
+ uint utmip_hsrx_cfg0;
+ uint utmip_hsrx_cfg1;
+ uint utmip_fslsrx_cfg0;
+ uint utmip_fslsrx_cfg1;
+
+ /* 0x820 */
+ uint utmip_tx_cfg0;
+ uint utmip_misc_cfg0;
+ uint utmip_misc_cfg1;
+ uint utmip_debounce_cfg0;
+
+ /* 0x830 */
+ uint utmip_bat_chrg_cfg0;
+ uint utmip_spare_cfg0;
+ uint utmip_xcvr_cfg1;
+ uint utmip_bias_cfg1;
+};
+
+
+/* USB1_LEGACY_CTRL */
+#define USB1_NO_LEGACY_MODE 1
+
+#define VBUS_SENSE_CTL_SHIFT 1
+#define VBUS_SENSE_CTL_MASK (3 << VBUS_SENSE_CTL_SHIFT)
+#define VBUS_SENSE_CTL_VBUS_WAKEUP 0
+#define VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP 1
+#define VBUS_SENSE_CTL_AB_SESS_VLD 2
+#define VBUS_SENSE_CTL_A_SESS_VLD 3
+
+/* USBx_IF_USB_SUSP_CTRL_0 */
+#define UTMIP_PHY_ENB (1 << 12)
+#define UTMIP_RESET (1 << 11)
+#define USB_PHY_CLK_VALID (1 << 7)
+
+/* USBx_UTMIP_MISC_CFG1 */
+#define UTMIP_PLLU_STABLE_COUNT_SHIFT 6
+#define UTMIP_PLLU_STABLE_COUNT_MASK \
+ (0xfff << UTMIP_PLLU_STABLE_COUNT_SHIFT)
+#define UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT 18
+#define UTMIP_PLL_ACTIVE_DLY_COUNT_MASK \
+ (0x1f << UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT)
+#define UTMIP_PHY_XTAL_CLOCKEN (1 << 30)
+
+/* USBx_UTMIP_PLL_CFG1_0 */
+#define UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT 27
+#define UTMIP_PLLU_ENABLE_DLY_COUNT_MASK \
+ (0xf << UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT)
+#define UTMIP_XTAL_FREQ_COUNT_SHIFT 0
+#define UTMIP_XTAL_FREQ_COUNT_MASK 0xfff
+
+/* USBx_UTMIP_BIAS_CFG1_0 */
+#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3
+#define UTMIP_BIAS_PDTRK_COUNT_MASK \
+ (0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT)
+
+#define UTMIP_DEBOUNCE_CFG0_SHIFT 0
+#define UTMIP_DEBOUNCE_CFG0_MASK 0xffff
+
+/* USBx_UTMIP_TX_CFG0_0 */
+#define UTMIP_FS_PREAMBLE_J (1 << 19)
+
+/* USBx_UTMIP_BAT_CHRG_CFG0_0 */
+#define UTMIP_PD_CHRG 1
+
+/* USBx_UTMIP_XCVR_CFG0_0 */
+#define UTMIP_XCVR_LSBIAS_SE (1 << 21)
+
+/* USBx_UTMIP_SPARE_CFG0_0 */
+#define FUSE_SETUP_SEL (1 << 3)
+
+/* USBx_UTMIP_HSRX_CFG0_0 */
+#define UTMIP_IDLE_WAIT_SHIFT 15
+#define UTMIP_IDLE_WAIT_MASK (0x1f << UTMIP_IDLE_WAIT_SHIFT)
+#define UTMIP_ELASTIC_LIMIT_SHIFT 10
+#define UTMIP_ELASTIC_LIMIT_MASK \
+ (0x1f << UTMIP_ELASTIC_LIMIT_SHIFT)
+
+/* USBx_UTMIP_HSRX_CFG0_1 */
+#define UTMIP_HS_SYNC_START_DLY_SHIFT 1
+#define UTMIP_HS_SYNC_START_DLY_MASK \
+ (0xf << UTMIP_HS_SYNC_START_DLY_SHIFT)
+
+/* USBx_CONTROLLER_2_USB2D_ICUSB_CTRL_0 */
+#define IC_ENB1 (1 << 3)
+
+/* SB2_CONTROLLER_2_USB2D_PORTSC1_0 */
+#define PTS_SHIFT 30
+#define PTS_MASK (3U << PTS_SHIFT)
+#define PTS_UTMI 0
+#define PTS_RESERVED 1
+#define PTS_ULP 2
+#define PTS_ICUSB_SER 3
+
+#define STS (1 << 29)
+
+/* USBx_UTMIP_XCVR_CFG0_0 */
+#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
+#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
+#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
+
+/* USBx_UTMIP_XCVR_CFG1_0 */
+#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
+#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
+#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
+
+/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */
+#define VBUS_VLD_STS (1 << 26)
+
+
+/* Change the USB host port into host mode */
+void usb_set_host_mode(void);
+
+/* Setup USB on the board */
+int board_usb_init(const void *blob);
+
+/**
+ * Start up the given port number (ports are numbered from 0 on each board).
+ * This returns values for the appropriate hccr and hcor addresses to use for
+ * USB EHCI operations.
+ *
+ * @param portnum port number to start
+ * @param hccr returns start address of EHCI HCCR registers
+ * @param hcor returns start address of EHCI HCOR registers
+ * @return 0 if ok, -1 on error (generally invalid port number)
+ */
+int tegrausb_start_port(unsigned portnum, u32 *hccr, u32 *hcor);
+
+/**
+ * Stop the current port
+ *
+ * @return 0 if ok, -1 if no port was active
+ */
+int tegrausb_stop_port(void);
+
+#endif /* _TEGRA_USB_H_ */
--- /dev/null
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef ARM_BOOTM_H
+#define ARM_BOOTM_H
+
+#ifdef CONFIG_USB_DEVICE
+extern void udc_disconnect(void);
+#endif
+
+#endif
/* SPL common function s*/
void spl_parse_image_header(const struct image_header *header);
void omap_rev_string(void);
+void spl_board_prepare_for_linux(void);
+int spl_start_uboot(void);
/* NAND SPL functions */
void spl_nand_load_image(void);
/* MMC SPL functions */
void spl_mmc_load_image(void);
+/* YMODEM SPL functions */
+void spl_ymodem_load_image(void);
+
#ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void);
#endif
COBJS-y += board.o
COBJS-y += bootm.o
-COBJS-y += cache.o
-COBJS-y += cache-cp15.o
COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
COBJS-y += interrupts.o
COBJS-y += reset.o
SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
endif
+COBJS-y += cache.o
+COBJS-y += cache-cp15.o
+
SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \
$(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
ulong reg;
#endif
+ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
+
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
/* compiler optimization barrier needed for GCC >= 3.4 */
}
}
+#ifdef CONFIG_OF_CONTROL
+ /* For now, put this check after the console is ready */
+ if (fdtdec_prepare_fdt()) {
+ panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
+ "doc/README.fdt-control");
+ }
+#endif
+
debug("monitor len: %08lX\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
gd = id;
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
+ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
monitor_flash_len = _end_ofs;
-/*
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ * - Added prep subcommand support
+ * - Reorganized source - modeled after powerpc version
+ *
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
#include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>
+#include <asm/bootm.h>
DECLARE_GLOBAL_DATA_PTR;
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
- defined (CONFIG_CMDLINE_TAG) || \
- defined (CONFIG_INITRD_TAG) || \
- defined (CONFIG_SERIAL_TAG) || \
- defined (CONFIG_REVISION_TAG)
-static void setup_start_tag (bd_t *bd);
-
-# ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags (bd_t *bd);
-# endif
-static void setup_commandline_tag (bd_t *bd, char *commandline);
-
-# ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag (bd_t *bd, ulong initrd_start,
- ulong initrd_end);
-# endif
-static void setup_end_tag (bd_t *bd);
-
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+ defined(CONFIG_CMDLINE_TAG) || \
+ defined(CONFIG_INITRD_TAG) || \
+ defined(CONFIG_SERIAL_TAG) || \
+ defined(CONFIG_REVISION_TAG)
static struct tag *params;
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
-
-static ulong get_sp(void);
-#if defined(CONFIG_OF_LIBFDT)
-static int bootm_linux_fdt(int machid, bootm_headers_t *images);
#endif
+static ulong get_sp(void)
+{
+ ulong ret;
+
+ asm("mov %0, sp" : "=r"(ret) : );
+ return ret;
+}
+
void arch_lmb_reserve(struct lmb *lmb)
{
ulong sp;
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
}
-static void announce_and_cleanup(void)
-{
- printf("\nStarting kernel ...\n\n");
-
-#ifdef CONFIG_USB_DEVICE
- {
- extern void udc_disconnect(void);
- udc_disconnect();
- }
-#endif
- cleanup_before_linux();
-}
-
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
-{
- bd_t *bd = gd->bd;
- char *s;
- int machid = bd->bi_arch_number;
- void (*kernel_entry)(int zero, int arch, uint params);
-
-#ifdef CONFIG_CMDLINE_TAG
- char *commandline = getenv ("bootargs");
-#endif
-
- if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
- return 1;
-
- s = getenv ("machid");
- if (s) {
- machid = simple_strtoul (s, NULL, 16);
- printf ("Using machid 0x%x from environment\n", machid);
- }
-
- show_boot_progress (15);
-
#ifdef CONFIG_OF_LIBFDT
- if (images->ft_len)
- return bootm_linux_fdt(machid, images);
-#endif
-
- kernel_entry = (void (*)(int, int, uint))images->ep;
-
- debug ("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong) kernel_entry);
-
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
- defined (CONFIG_CMDLINE_TAG) || \
- defined (CONFIG_INITRD_TAG) || \
- defined (CONFIG_SERIAL_TAG) || \
- defined (CONFIG_REVISION_TAG)
- setup_start_tag (bd);
-#ifdef CONFIG_SERIAL_TAG
- setup_serial_tag (¶ms);
-#endif
-#ifdef CONFIG_REVISION_TAG
- setup_revision_tag (¶ms);
-#endif
-#ifdef CONFIG_SETUP_MEMORY_TAGS
- setup_memory_tags (bd);
-#endif
-#ifdef CONFIG_CMDLINE_TAG
- setup_commandline_tag (bd, commandline);
-#endif
-#ifdef CONFIG_INITRD_TAG
- if (images->rd_start && images->rd_end)
- setup_initrd_tag (bd, images->rd_start, images->rd_end);
-#endif
- setup_end_tag(bd);
-#endif
-
- announce_and_cleanup();
-
- kernel_entry(0, machid, bd->bi_boot_params);
- /* does not return */
-
- return 1;
-}
-
-#if defined(CONFIG_OF_LIBFDT)
static int fixup_memory_node(void *blob)
{
bd_t *bd = gd->bd;
return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
}
+#endif
-static int bootm_linux_fdt(int machid, bootm_headers_t *images)
+static void announce_and_cleanup(void)
{
- ulong rd_len;
- void (*kernel_entry)(int zero, int dt_machid, void *dtblob);
- ulong of_size = images->ft_len;
- char **of_flat_tree = &images->ft_addr;
- ulong *initrd_start = &images->initrd_start;
- ulong *initrd_end = &images->initrd_end;
- struct lmb *lmb = &images->lmb;
- int ret;
-
- kernel_entry = (void (*)(int, int, void *))images->ep;
-
- boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
-
- rd_len = images->rd_end - images->rd_start;
- ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
- initrd_start, initrd_end);
- if (ret)
- return ret;
-
- ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
- if (ret)
- return ret;
-
- debug("## Transferring control to Linux (at address %08lx) ...\n",
- (ulong) kernel_entry);
-
- fdt_chosen(*of_flat_tree, 1);
-
- fixup_memory_node(*of_flat_tree);
-
- fdt_fixup_ethernet(*of_flat_tree);
-
- fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
-
- announce_and_cleanup();
-
- kernel_entry(0, machid, *of_flat_tree);
- /* does not return */
+ printf("\nStarting kernel ...\n\n");
+ bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
+#ifdef CONFIG_BOOTSTAGE_REPORT
+ bootstage_report();
+#endif
- return 1;
-}
+#ifdef CONFIG_USB_DEVICE
+ udc_disconnect();
#endif
+ cleanup_before_linux();
+}
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
- defined (CONFIG_CMDLINE_TAG) || \
- defined (CONFIG_INITRD_TAG) || \
- defined (CONFIG_SERIAL_TAG) || \
- defined (CONFIG_REVISION_TAG)
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+ defined(CONFIG_CMDLINE_TAG) || \
+ defined(CONFIG_INITRD_TAG) || \
+ defined(CONFIG_SERIAL_TAG) || \
+ defined(CONFIG_REVISION_TAG)
static void setup_start_tag (bd_t *bd)
{
- params = (struct tag *) bd->bi_boot_params;
+ params = (struct tag *)bd->bi_boot_params;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params = tag_next (params);
}
-
+#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
-static void setup_memory_tags (bd_t *bd)
+static void setup_memory_tags(bd_t *bd)
{
int i;
params = tag_next (params);
}
}
-#endif /* CONFIG_SETUP_MEMORY_TAGS */
-
+#endif
-static void setup_commandline_tag (bd_t *bd, char *commandline)
+#ifdef CONFIG_CMDLINE_TAG
+static void setup_commandline_tag(bd_t *bd, char *commandline)
{
char *p;
params = tag_next (params);
}
-
+#endif
#ifdef CONFIG_INITRD_TAG
-static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
+static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
params = tag_next (params);
}
-#endif /* CONFIG_INITRD_TAG */
+#endif
#ifdef CONFIG_SERIAL_TAG
-void setup_serial_tag (struct tag **tmp)
+void setup_serial_tag(struct tag **tmp)
{
struct tag *params = *tmp;
struct tag_serialnr serialnr;
params->u.revision.rev = rev;
params = tag_next (params);
}
-#endif /* CONFIG_REVISION_TAG */
+#endif
-static void setup_end_tag (bd_t *bd)
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+ defined(CONFIG_CMDLINE_TAG) || \
+ defined(CONFIG_INITRD_TAG) || \
+ defined(CONFIG_SERIAL_TAG) || \
+ defined(CONFIG_REVISION_TAG)
+static void setup_end_tag(bd_t *bd)
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}
-#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+#endif
-static ulong get_sp(void)
+#ifdef CONFIG_OF_LIBFDT
+static int create_fdt(bootm_headers_t *images)
{
- ulong ret;
+ ulong of_size = images->ft_len;
+ char **of_flat_tree = &images->ft_addr;
+ ulong *initrd_start = &images->initrd_start;
+ ulong *initrd_end = &images->initrd_end;
+ struct lmb *lmb = &images->lmb;
+ ulong rd_len;
+ int ret;
- asm("mov %0, sp" : "=r"(ret) : );
- return ret;
+ debug("using: FDT\n");
+
+ boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
+ rd_len = images->rd_end - images->rd_start;
+ ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
+ initrd_start, initrd_end);
+ if (ret)
+ return ret;
+
+ ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+ if (ret)
+ return ret;
+
+ fdt_chosen(*of_flat_tree, 1);
+ fixup_memory_node(*of_flat_tree);
+ fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
+
+ return 0;
+}
+#endif
+
+/* Subcommand: PREP */
+static void boot_prep_linux(bootm_headers_t *images)
+{
+#ifdef CONFIG_CMDLINE_TAG
+ char *commandline = getenv("bootargs");
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+ if (images->ft_len) {
+ debug("using: FDT\n");
+ if (create_fdt(images)) {
+ printf("FDT creation failed! hanging...");
+ hang();
+ }
+ } else
+#endif
+ {
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+ defined(CONFIG_CMDLINE_TAG) || \
+ defined(CONFIG_INITRD_TAG) || \
+ defined(CONFIG_SERIAL_TAG) || \
+ defined(CONFIG_REVISION_TAG)
+ debug("using: ATAGS\n");
+ setup_start_tag(gd->bd);
+#ifdef CONFIG_SERIAL_TAG
+ setup_serial_tag(¶ms);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+ setup_commandline_tag(gd->bd, commandline);
+#endif
+#ifdef CONFIG_REVISION_TAG
+ setup_revision_tag(¶ms);
+#endif
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+ setup_memory_tags(gd->bd);
+#endif
+#ifdef CONFIG_INITRD_TAG
+ if (images->rd_start && images->rd_end)
+ setup_initrd_tag(gd->bd, images->rd_start,
+ images->rd_end);
+#endif
+ setup_end_tag(gd->bd);
+#else /* all tags */
+ printf("FDT and ATAGS support not compiled in - hanging\n");
+ hang();
+#endif /* all tags */
+ }
+}
+
+/* Subcommand: GO */
+static void boot_jump_linux(bootm_headers_t *images)
+{
+ unsigned long machid = gd->bd->bi_arch_number;
+ char *s;
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))images->ep;
+
+ s = getenv("machid");
+ if (s) {
+ strict_strtoul(s, 16, &machid);
+ printf("Using machid 0x%lx from environment\n", machid);
+ }
+
+ debug("## Transferring control to Linux (at address %08lx)" \
+ "...\n", (ulong) kernel_entry);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+ announce_and_cleanup();
+ kernel_entry(0, machid, gd->bd->bi_boot_params);
+}
+
+/* Main Entry point for arm bootm implementation
+ *
+ * Modeled after the powerpc implementation
+ * DIFFERENCE: Instead of calling prep and go at the end
+ * they are called if subcommand is equal 0.
+ */
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+ /* No need for those on ARM */
+ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
+ return -1;
+
+ if (flag & BOOTM_STATE_OS_PREP) {
+ boot_prep_linux(images);
+ return 0;
+ }
+
+ if (flag & BOOTM_STATE_OS_GO) {
+ boot_jump_linux(images);
+ return 0;
+ }
+
+ boot_prep_linux(images);
+ boot_jump_linux(images);
+ return 0;
+}
+
+#ifdef CONFIG_CMD_BOOTZ
+
+struct zimage_header {
+ uint32_t code[9];
+ uint32_t zi_magic;
+ uint32_t zi_start;
+ uint32_t zi_end;
+};
+
+#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
+
+int bootz_setup(void *image, void **start, void **end)
+{
+ struct zimage_header *zi = (struct zimage_header *)image;
+
+ if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
+ puts("Bad Linux ARM zImage magic!\n");
+ return 1;
+ }
+
+ *start = (void *)zi->zi_start;
+ *end = (void *)zi->zi_end;
+
+ debug("Kernel image @ 0x%08x [ 0x%08x - 0x%08x ]\n",
+ (uint32_t)image, (uint32_t)*start, (uint32_t)*end);
+
+ return 0;
}
+#endif /* CONFIG_CMD_BOOTZ */
#include <stdio_dev.h>
#include <version.h>
#include <net.h>
+#include <atmel_mci.h>
#ifdef CONFIG_BITBANGMII
#include <miiphy.h>
#include <asm/sections.h>
#include <asm/arch/mmu.h>
+#include <asm/arch/hardware.h>
#ifndef CONFIG_IDENT_STRING
#define CONFIG_IDENT_STRING ""
#endif
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+#include <mmc.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
unsigned long monitor_flash_len;
int board_postclk_init(void) __attribute__((weak, alias("__do_nothing")));
int board_early_init_r(void) __attribute__((weak, alias("__do_nothing")));
+/* provide cpu_mmc_init, to overwrite provide board_mmc_init */
+int cpu_mmc_init(bd_t *bd)
+{
+ /* This calls the atmel_mci_init in gen_atmel_mci.c */
+ return atmel_mci_init((void *)ATMEL_BASE_MMCI);
+}
+
#ifdef CONFIG_SYS_DMA_ALLOC_LEN
#include <asm/arch/cacheflush.h>
#include <asm/io.h>
eth_initialize(gd->bd);
#endif
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+ mmc_initialize(gd->bd);
+#endif
for (;;) {
main_loop();
}
theKernel = (void *)images->ep;
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
params = params_start = (struct tag *)gd->bd->bi_boot_params;
params = setup_start_tag(params);
*/
{
ulong pram = 0;
- uchar memsz[32];
+ char memsz[32];
#ifdef CONFIG_PRAM
pram = getenv_ulong("pram", 10, CONFIG_PRAM);
debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) kernel);
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* Linux Kernel Parameters (passing board info data):
#endif
struct irq_action *act = vecs + irqs;
- intc->iar = mask << irqs;
-
#ifdef DEBUG_INT
printf
("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n",
act->handler (act->arg);
act->count++;
+ intc->iar = mask << irqs;
+
#ifdef DEBUG_INT
printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
intc->ier, intc->iar, intc->mer);
}
#endif
#endif
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On Microblaze it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On Microblaze it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
if (ret)
return 1;
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
if (!of_flat_tree && argc > 3)
of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16);
urb_priv.actual_length = 0;
pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (usb_pipeint(pipe)) {
info("Root-Hub submit IRQ: NOT implemented");
#ifdef DEBUG
ohci_dump_roothub (&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
len = min_t(int, len, leni);
urb_priv.actual_length = transfer_len;
pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
#else
- wait_ms(1);
+ mdelay(1);
#endif
return stat;
urb_priv.actual_length = 0;
pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_common_message: pipesize for pipe %lx is zero",
return -1;
}
- wait_ms(10);
+ mdelay(10);
/* ohci_dump_status(&gohci); */
/* allow more time for a BULK device to react - some are slow */
break;
}
if (--timeout) {
- udelay(250); /* wait_ms(1); */
+ udelay(250); /* mdelay(1); */
} else {
err("CTL:TIMEOUT ");
stat = USB_ST_CRC_ERR;
#ifdef DEBUG
pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* free TDs in urb_priv */
urb_priv.actual_length = 0;
pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_control_message: pipesize for pipe %lx is zero",
writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
info("USB HC TakeOver from SMM");
while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms (10);
+ mdelay (10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
#ifdef DEBUG
ohci_dump (ohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* FIXME: be optimistic, hope that bug won't repeat often. */
/* Make some non-interrupt context restart the controller. */
}
if (ints & OHCI_INTR_WDH) {
- wait_ms(1);
+ mdelay(1);
writel (OHCI_INTR_WDH, ®s->intrdisable);
stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
writel (OHCI_INTR_WDH, ®s->intrenable);
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
writel (OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
writel (OHCI_INTR_SF, ®s->intrenable);
/* FIXME this is a second HC reset; why?? */
writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
- wait_ms (10);
+ mdelay (10);
if (hc_start (&gohci) < 0)
goto errout;
#ifdef DEBUG
ohci_dump (&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
ohci_inited = 1;
return 0;
/* find kernel entry point */
theKernel = (void (*)(int, char **, char **, int *))images->ep;
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
#ifdef DEBUG
printf ("## Transferring control to Linux (at address %08lx) ...\n",
/* find kernel entry point */
theKernel = (void (*)(int, char **, char **, int *))images->ep;
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
debug ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong) theKernel);
*/
#include <asm/arch-ag101/ag101.h>
+#include <linux/linkage.h>
.text
#ifndef CONFIG_SKIP_TRUNOFF_WATCHDOG
-.globl turnoff_watchdog
-turnoff_watchdog:
+ENTRY(turnoff_watchdog)
#define WD_CR 0xC
#define WD_ENABLE 0x1
ret
+ENDPROC(turnoff_watchdog)
#endif
j tlb_not_present
j tlb_misc
j tlb_vlpt_miss
- j cache_parity_error
+ j machine_error
j debug
j general_exception
+ j syscall
j internal_interrupt ! H0I
j internal_interrupt ! H1I
j internal_interrupt ! H2I
j internal_interrupt ! H3I
j internal_interrupt ! H4I
j internal_interrupt ! H5I
+ j software_interrupt ! S0I
.balign 16
bal do_interruption
.align 5
-cache_parity_error:
+machine_error:
SAVE_ALL
move $r0, $sp ! To get the kernel stack
li $r1, 5 ! Determine interruption type
bal do_interruption
.align 5
-internal_interrupt:
+syscall:
SAVE_ALL
move $r0, $sp ! To get the kernel stack
li $r1, 8 ! Determine interruption type
bal do_interruption
+ .align 5
+internal_interrupt:
+ SAVE_ALL
+ move $r0, $sp ! To get the kernel stack
+ li $r1, 9 ! Determine interruption type
+ bal do_interruption
+
+ .align 5
+software_interrupt:
+ SAVE_ALL
+ move $r0, $sp ! To get the kernel stack
+ li $r1, 10 ! Determine interruption type
+ bal do_interruption
+
.align 5
/*
--- /dev/null
+/*
+ * U-boot - linkage.h
+ *
+ * Copyright (c) 2005-2007 Analog Devices 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 St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#endif
NDS32_REG d1hi;
NDS32_REG d1lo;
NDS32_REG r[26]; /* r0 - r25 */
+ NDS32_REG p0; /* r26 - used by OS */
+ NDS32_REG p1; /* r27 - used by OS */
NDS32_REG fp; /* r28 */
NDS32_REG gp; /* r29 */
NDS32_REG lp; /* r30 */
env_relocate();
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
+ puts("PCI: ");
nds32_pci_init();
#endif
printf("Using machid 0x%x from environment\n", machid);
}
- show_boot_progress(15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
debug("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)theKernel);
printf("D1H: %08lx D1L: %08lx D0H: %08lx D0L: %08lx\n",
regs->d1hi, regs->d1lo, regs->d0hi, regs->d0lo);
printf("r27: %08lx r26: %08lx r25: %08lx r24: %08lx\n",
- regs->r[27], regs->r[26], regs->r[25], regs->r[24]);
+ regs->p1, regs->p0, regs->r[25], regs->r[24]);
printf("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n",
regs->r[23], regs->r[22], regs->r[21], regs->r[20]);
printf("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n",
}
if (--timeout) {
- wait_ms(1);
+ mdelay(1);
if (!urb_finished)
dbg("\%");
writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
info("USB HC TakeOver from SMM");
while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms (10);
+ mdelay (10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
writel (OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
writel (OHCI_INTR_SF, ®s->intrenable);
}
if (--timeout) {
- wait_ms(1);
+ mdelay(1);
if (!urb_finished)
dbg("\%");
writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
info("USB HC TakeOver from SMM");
while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms (10);
+ mdelay (10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
writel (OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
writel (OHCI_INTR_SF, ®s->intrenable);
*/
{
ulong pram = 0;
- uchar memsz[32];
+ char memsz[32];
#ifdef CONFIG_PRAM
pram = getenv_ulong("pram", 10, CONFIG_PRAM);
pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
#endif
#endif
- sprintf((char *) memsz, "%ldk",
- (bd->bi_memsize / 1024) - pram);
- setenv("mem", (char *) memsz);
+ sprintf(memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
+ setenv("mem", memsz);
}
#endif
void hang(void)
{
puts("### ERROR ### Please RESET the board ###\n");
- show_boot_progress(-30);
+ bootstage_error(BOOTSTAGE_ID_NEED_RESET);
for (;;)
;
}
debug ("## Transferring control to Linux (at address %08lx) ...\n",
(ulong)kernel);
- show_boot_progress (15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
-PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__
+PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_LIBS += -lrt
LIB = $(obj)lib$(CPU).o
-COBJS := cpu.o start.o os.o
+COBJS := cpu.o os.o start.o state.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
* MA 02111-1307 USA
*/
+#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <stdlib.h>
#include <termios.h>
-#include <unistd.h>
#include <time.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <unistd.h>
#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <linux/types.h>
+#include <asm/getopt.h>
+#include <asm/sections.h>
+#include <asm/state.h>
#include <os.h>
/* Operating System Interface */
return write(fd, buf, count);
}
-int os_open(const char *pathname, int flags)
+off_t os_lseek(int fd, off_t offset, int whence)
+{
+ if (whence == OS_SEEK_SET)
+ whence = SEEK_SET;
+ else if (whence == OS_SEEK_CUR)
+ whence = SEEK_CUR;
+ else if (whence == OS_SEEK_END)
+ whence = SEEK_END;
+ else
+ os_exit(1);
+ return lseek(fd, offset, whence);
+}
+
+int os_open(const char *pathname, int os_flags)
{
- return open(pathname, flags);
+ int flags;
+
+ switch (os_flags & OS_O_MASK) {
+ case OS_O_RDONLY:
+ default:
+ flags = O_RDONLY;
+ break;
+
+ case OS_O_WRONLY:
+ flags = O_WRONLY;
+ break;
+
+ case OS_O_RDWR:
+ flags = O_RDWR;
+ break;
+ }
+
+ if (os_flags & OS_O_CREAT)
+ flags |= O_CREAT;
+
+ return open(pathname, flags, 0777);
}
int os_close(int fd)
return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
#endif
}
+
+static char *short_opts;
+static struct option *long_opts;
+
+int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
+{
+ struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
+ size_t num_options = __u_boot_sandbox_option_count();
+ size_t i;
+
+ int hidden_short_opt;
+ size_t si;
+
+ int c;
+
+ if (short_opts || long_opts)
+ return 1;
+
+ state->argc = argc;
+ state->argv = argv;
+
+ /* dynamically construct the arguments to the system getopt_long */
+ short_opts = os_malloc(sizeof(*short_opts) * num_options * 2 + 1);
+ long_opts = os_malloc(sizeof(*long_opts) * num_options);
+ if (!short_opts || !long_opts)
+ return 1;
+
+ /*
+ * getopt_long requires "val" to be unique (since that is what the
+ * func returns), so generate unique values automatically for flags
+ * that don't have a short option. pick 0x100 as that is above the
+ * single byte range (where ASCII/ISO-XXXX-X charsets live).
+ */
+ hidden_short_opt = 0x100;
+ si = 0;
+ for (i = 0; i < num_options; ++i) {
+ long_opts[i].name = sb_opt[i]->flag;
+ long_opts[i].has_arg = sb_opt[i]->has_arg ?
+ required_argument : no_argument;
+ long_opts[i].flag = NULL;
+
+ if (sb_opt[i]->flag_short) {
+ short_opts[si++] = long_opts[i].val = sb_opt[i]->flag_short;
+ if (long_opts[i].has_arg == required_argument)
+ short_opts[si++] = ':';
+ } else
+ long_opts[i].val = sb_opt[i]->flag_short = hidden_short_opt++;
+ }
+ short_opts[si] = '\0';
+
+ /* we need to handle output ourselves since u-boot provides printf */
+ opterr = 0;
+
+ /*
+ * walk all of the options the user gave us on the command line,
+ * figure out what u-boot option structure they belong to (via
+ * the unique short val key), and call the appropriate callback.
+ */
+ while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
+ for (i = 0; i < num_options; ++i) {
+ if (sb_opt[i]->flag_short == c) {
+ if (sb_opt[i]->callback(state, optarg)) {
+ state->parse_err = sb_opt[i]->flag;
+ return 0;
+ }
+ break;
+ }
+ }
+ if (i == num_options) {
+ /*
+ * store the faulting flag for later display. we have to
+ * store the flag itself as the getopt parsing itself is
+ * tricky: need to handle the following flags (assume all
+ * of the below are unknown):
+ * -a optopt='a' optind=<next>
+ * -abbbb optopt='a' optind=<this>
+ * -aaaaa optopt='a' optind=<this>
+ * --a optopt=0 optind=<this>
+ * as you can see, it is impossible to determine the exact
+ * faulting flag without doing the parsing ourselves, so
+ * we just report the specific flag that failed.
+ */
+ if (optopt) {
+ static char parse_err[3] = { '-', 0, '\0', };
+ parse_err[1] = optopt;
+ state->parse_err = parse_err;
+ } else
+ state->parse_err = argv[optind - 1];
+ break;
+ }
+ }
+
+ return 0;
+}
/*
- * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
* See file CREDITS for list of people who contributed to this
* project.
*
*/
#include <common.h>
+#include <asm/getopt.h>
+#include <asm/sections.h>
+#include <asm/state.h>
+
+#include <os.h>
+
+int sandbox_early_getopt_check(void)
+{
+ struct sandbox_state *state = state_get_current();
+ struct sb_cmdline_option **sb_opt = __u_boot_sandbox_option_start;
+ size_t num_options = __u_boot_sandbox_option_count();
+ size_t i;
+ int max_arg_len, max_noarg_len;
+
+ /* parse_err will be a string of the faulting option */
+ if (!state->parse_err)
+ return 0;
+
+ if (strcmp(state->parse_err, "help")) {
+ printf("u-boot: error: failed while parsing option: %s\n"
+ "\ttry running with --help for more information.\n",
+ state->parse_err);
+ os_exit(1);
+ }
+
+ printf(
+ "u-boot, a command line test interface to U-Boot\n\n"
+ "Usage: u-boot [options]\n"
+ "Options:\n");
+
+ max_arg_len = 0;
+ for (i = 0; i < num_options; ++i)
+ max_arg_len = max(strlen(sb_opt[i]->flag), max_arg_len);
+ max_noarg_len = max_arg_len + 7;
+
+ for (i = 0; i < num_options; ++i) {
+ struct sb_cmdline_option *opt = sb_opt[i];
+
+ /* first output the short flag if it has one */
+ if (opt->flag_short >= 0x100)
+ printf(" ");
+ else
+ printf(" -%c, ", opt->flag_short);
+
+ /* then the long flag */
+ if (opt->has_arg)
+ printf("--%-*s", max_noarg_len, opt->flag);
+ else
+ printf("--%-*s <arg> ", max_arg_len, opt->flag);
+
+ /* finally the help text */
+ printf(" %s\n", opt->help);
+ }
+
+ os_exit(0);
+}
+
+static int sb_cmdline_cb_help(struct sandbox_state *state, const char *arg)
+{
+ /* just flag to sandbox_early_getopt_check to show usage */
+ return 1;
+}
+SB_CMDLINE_OPT_SHORT(help, 'h', 0, "Display help");
+
+int sandbox_main_loop_init(void)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /* Execute command if required */
+ if (state->cmd) {
+ /* TODO: redo this when cmd tidy-up series lands */
+#ifdef CONFIG_SYS_HUSH_PARSER
+ run_command(state->cmd, 0);
+#else
+ parse_string_outer(state->cmd, FLAG_PARSE_SEMICOLON |
+ FLAG_EXIT_FROM_LOOP);
+#endif
+ os_exit(state->exit_type);
+ }
+
+ return 0;
+}
+
+static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg)
+{
+ state->cmd = arg;
+ return 0;
+}
+SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
int main(int argc, char *argv[])
{
+ struct sandbox_state *state;
+ int err;
+
+ err = state_init();
+ if (err)
+ return err;
+
+ state = state_get_current();
+ if (os_parse_args(state, argc, argv))
+ return 1;
+
/*
* Do pre- and post-relocation init, then start up U-Boot. This will
* never return.
/*
- * (C) Copyright 2000-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
* See file CREDITS for list of people who contributed to this
* project.
*
* MA 02111-1307 USA
*/
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- cpu/pxa/start.o (.text)
- *(.text)
- }
+#include <common.h>
+#include <asm/state.h>
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+/* Main state record for the sandbox */
+static struct sandbox_state main_state;
+static struct sandbox_state *state; /* Pointer to current state record */
- . = ALIGN(4);
- .data : { *(.data) }
+void state_record_exit(enum exit_type_id exit_type)
+{
+ state->exit_type = exit_type;
+}
- . = ALIGN(4);
- .got : { *(.got) }
+struct sandbox_state *state_get_current(void)
+{
+ assert(state);
+ return state;
+}
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
+int state_init(void)
+{
+ state = &main_state;
- . = ALIGN(4);
- __bss_start = .;
- .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
- __bss_end__ = .;
+ /*
+ * Example of how to use GPIOs:
+ *
+ * sandbox_gpio_set_direction(170, 0);
+ * sandbox_gpio_set_value(170, 0);
+ */
+ return 0;
}
/*
- * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
SECTIONS
{
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
- __bss_start = .;
+ __u_boot_cmd_start = .;
+ _u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+ __u_boot_sandbox_option_start = .;
+ _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+ __u_boot_sandbox_option_end = .;
+
+ __bss_start = .;
}
INSERT BEFORE .data;
--- /dev/null
+/*
+ * Code for setting up command line flags like `./u-boot --help`
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __SANDBOX_GETOPT_H
+#define __SANDBOX_GETOPT_H
+
+struct sandbox_state;
+
+/*
+ * Internal structure for storing details about the flag.
+ * Most people should not have to dig around in this as
+ * it only gets parsed by the core sandbox code. End
+ * consumer code should focus on the macros below and
+ * the callback function.
+ */
+struct sb_cmdline_option {
+ /* The long flag name: "help" for "--help" */
+ const char *flag;
+ /* The (optional) short flag name: "h" for "-h" */
+ int flag_short;
+ /* The help string shown to the user when processing --help */
+ const char *help;
+ /* Whether this flag takes an argument */
+ int has_arg;
+ /* Callback into the end consumer code with the option */
+ int (*callback)(struct sandbox_state *state, const char *opt);
+};
+
+/*
+ * Internal macro to expand the lower macros into the necessary
+ * magic junk that makes this all work.
+ */
+#define _SB_CMDLINE_OPT(f, s, ha, h) \
+ static struct sb_cmdline_option sb_cmdline_option_##f = { \
+ .flag = #f, \
+ .flag_short = s, \
+ .help = h, \
+ .has_arg = ha, \
+ .callback = sb_cmdline_cb_##f, \
+ }; \
+ /* Ppointer to the struct in a special section for the linker script */ \
+ static __attribute__((section(".u_boot_sandbox_getopt"), used)) \
+ struct sb_cmdline_option *sb_cmdline_option_##f##_ptr = \
+ &sb_cmdline_option_##f
+
+/**
+ * Macros for end code to declare new command line flags.
+ *
+ * @param f The long flag name e.g. help
+ * @param ha Does the flag have an argument e.g. 0/1
+ * @param h The help string displayed when showing --help
+ *
+ * This invocation:
+ * SB_CMDLINE_OPT(foo, 0, "The foo arg");
+ * Will create a new flag named "--foo" (no short option) that takes
+ * no argument. If the user specifies "--foo", then the callback func
+ * sb_cmdline_cb_foo() will automatically be called.
+ */
+#define SB_CMDLINE_OPT(f, ha, h) _SB_CMDLINE_OPT(f, 0, ha, h)
+/*
+ * Same as above, but @s is used to specify a short flag e.g.
+ * SB_CMDLINE_OPT(foo, 'f', 0, "The foo arg");
+ */
+#define SB_CMDLINE_OPT_SHORT(f, s, ha, h) _SB_CMDLINE_OPT(f, s, ha, h)
+
+#endif
unsigned long fb_base; /* base address of frame buffer */
u8 *ram_buf; /* emulated RAM buffer */
phys_size_t ram_size; /* RAM size */
+ const void *fdt_blob; /* Our device tree, NULL if none */
void **jt; /* jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
} gd_t;
--- /dev/null
+/*
+ * This is the interface to the sandbox GPIO driver for test code which
+ * wants to change the GPIO values reported to U-Boot.
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+#ifndef __ASM_SANDBOX_GPIO_H
+#define __ASM_SANDBOX_GPIO_H
+
+/*
+ * We use the generic interface, and add a back-channel.
+ *
+ * The back-channel functions are declared in this file. They should not be used
+ * except in test code.
+ *
+ * Test code can, for example, call sandbox_gpio_set_value() to set the value of
+ * a simulated GPIO. From then on, normal code in U-Boot will see this new
+ * value when it calls gpio_get_value().
+ *
+ * NOTE: DO NOT use the functions in this file except in test code!
+ */
+#include <asm-generic/gpio.h>
+
+/**
+ * Return the simulated value of a GPIO (used only in sandbox test code)
+ *
+ * @param gp GPIO number
+ * @return -1 on error, 0 if GPIO is low, >0 if high
+ */
+int sandbox_gpio_get_value(unsigned gp);
+
+/**
+ * Set the simulated value of a GPIO (used only in sandbox test code)
+ *
+ * @param gp GPIO number
+ * @param value value to set (0 for low, non-zero for high)
+ * @return -1 on error, 0 if ok
+ */
+int sandbox_gpio_set_value(unsigned gp, int value);
+
+/**
+ * Return the simulated direction of a GPIO (used only in sandbox test code)
+ *
+ * @param gp GPIO number
+ * @return -1 on error, 0 if GPIO is input, >0 if output
+ */
+int sandbox_gpio_get_direction(unsigned gp);
+
+/**
+ * Set the simulated direction of a GPIO (used only in sandbox test code)
+ *
+ * @param gp GPIO number
+ * @param output 0 to set as input, 1 to set as output
+ * @return -1 on error, 0 if ok
+ */
+int sandbox_gpio_set_direction(unsigned gp, int output);
+
+/* Display information about each GPIO */
+void gpio_info(void);
+
+#define gpio_status() gpio_info()
+
+#endif
--- /dev/null
+/*
+ * decls for symbols defined in the linker script
+ *
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __SANDBOX_SECTIONS_H
+#define __SANDBOX_SECTIONS_H
+
+struct sb_cmdline_option;
+
+extern struct sb_cmdline_option *__u_boot_sandbox_option_start[],
+ *__u_boot_sandbox_option_end[];
+
+static inline size_t __u_boot_sandbox_option_count(void)
+{
+ return __u_boot_sandbox_option_end - __u_boot_sandbox_option_start;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
+ * 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
+ */
+
+#ifndef __SANDBOX_STATE_H
+#define __SANDBOX_STATE_H
+
+#include <config.h>
+
+/* How we exited U-Boot */
+enum exit_type_id {
+ STATE_EXIT_NORMAL,
+ STATE_EXIT_COLD_REBOOT,
+ STATE_EXIT_POWER_OFF,
+};
+
+/* The complete state of the test system */
+struct sandbox_state {
+ const char *cmd; /* Command to execute */
+ enum exit_type_id exit_type; /* How we exited U-Boot */
+ const char *parse_err; /* Error to report from parsing */
+ int argc; /* Program arguments */
+ char **argv;
+};
+
+/**
+ * Record the exit type to be reported by the test program.
+ *
+ * @param exit_type Exit type to record
+ */
+void state_record_exit(enum exit_type_id exit_type);
+
+/**
+ * Gets a pointer to the current state.
+ *
+ * @return pointer to state
+ */
+struct sandbox_state *state_get_current(void);
+
+/**
+ * Initialize the test system state
+ */
+int state_init(void);
+
+#endif
int board_init(void);
int dram_init(void);
+/* start.c */
+int sandbox_early_getopt_check(void);
+int sandbox_main_loop_init(void);
+
#endif /* _U_BOOT_SANDBOX_H_ */
env_init, /* initialize environment */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
+ sandbox_early_getopt_check, /* process command line flags (err/help) */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
memset((void *)gd, 0, sizeof(gd_t));
+#if defined(CONFIG_OF_EMBED)
+ /* Get a pointer to the FDT */
+ gd->fdt_blob = _binary_dt_dtb_start;
+#elif defined(CONFIG_OF_SEPARATE)
+ /* FDT is at end of image */
+ gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
+#endif
+
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0)
hang();
post_run(NULL, POST_RAM | post_bootmode_get(0));
#endif
+ sandbox_main_loop_init();
+
/*
* For now, run the main loop. Later we might let this be done
* in the main program.
--- /dev/null
+/*
+ * Renesas SuperH MMCIF driver.
+ *
+ * Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ */
+#ifndef _SH_MMC_H_
+#define _SH_MMC_H_
+
+int mmcif_mmc_init(void);
+
+#endif /* _SH_MMC_H_ */
+
#include <version.h>
#include <watchdog.h>
#include <net.h>
+#include <mmc.h>
#include <environment.h>
#ifdef CONFIG_BITBANGMII
unsigned long long get_ticks (void)
{
unsigned long tcnt = 0 - readl(TCNT0);
- unsigned long ticks;
- if (last_tcnt > tcnt) { /* overflow */
+ if (last_tcnt > tcnt) /* overflow */
overflow_ticks++;
- ticks = (0xffffffff - last_tcnt) + tcnt;
- } else {
- ticks = tcnt;
- }
last_tcnt = tcnt;
return (overflow_ticks << 32) | tcnt;
out16r(usb_base_addr + USBCMD, USBCMD_GRESET | USBCMD_RS);
/* Turn off all interrupts */
out16r(usb_base_addr + USBINTR, 0);
- wait_ms(50);
+ mdelay(50);
out16r(usb_base_addr + USBCMD, 0);
- wait_ms(10);
+ mdelay(10);
}
void start_hc(void)
status = (status & 0xfff5) | USBPORTSC_PR;
out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
status);
- wait_ms(10);
+ mdelay(10);
status = (status & 0xfff5) & ~USBPORTSC_PR;
out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
status);
status = (status & 0xfff5) | USBPORTSC_PE;
out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
status);
- wait_ms(10);
+ mdelay(10);
status = (status & 0xfff5) | 0xa;
out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
status);
{
puts("### ERROR ### Please RESET the board ###\n");
#ifdef CONFIG_SHOW_BOOT_PROGRESS
- show_boot_progress(-30);
+ bootstage_error(BOOTSTAGE_ID_NEED_RESET);
#endif
for (;;) ;
}
{
int m = 0;
long u;
- long temp;
- temp = readw(&sc520_mmcr->swtmrmilli);
- temp = readw(&sc520_mmcr->swtmrmicro);
+ readw(&sc520_mmcr->swtmrmilli);
+ readw(&sc520_mmcr->swtmrmicro);
do {
m += readw(&sc520_mmcr->swtmrmilli);
int board_eth_init(bd_t *bis)
{
- return pci_eth_init(bis);
+ int ret;
+ ret = pci_eth_init(bis);
+ if (!ret)
+ ret = mv6436x_eth_initialize(bis);
+ return ret;
}
void db64360_eth0_disable(void);
bool network_start(bd_t *bis);
+int mv6436x_eth_initialize(bd_t *);
#endif /* __EVB64360_ETH_H__ */
return;
}
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf (dev->name, "mv_enet%d", devnum);
#ifdef DEBUG
int board_eth_init(bd_t *bis)
{
- return pci_eth_init(bis);
+ int ret;
+ ret = pci_eth_init(bis);
+ if (!ret)
+ ret = mv6446x_eth_initialize(bis);
+ return ret;
}
void db64460_eth0_disable(void);
bool network_start(bd_t *bis);
+int mv6446x_eth_initialize(bd_t *);
+
#endif /* __EVB64460_ETH_H__ */
return;
}
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf (dev->name, "mv_enet%d", devnum);
#ifdef DEBUG
void show_boot_progress(int val)
{
switch (val) {
- case 15: /* booting Linux */
+ case BOOTSTAGE_ID_RUN_OS: /* booting Linux */
set_leds(BOTH_LEDS, NEITHER_LED);
break;
- case 64: /* Ethernet initialization */
+ case BOOTSTAGE_ID_NET_ETH_START: /* Ethernet initialization */
set_leds(GREEN_LED, GREEN_LED);
break;
default:
display_out_pos = 0; /* reset output position */
/* we want to flush status 15 now */
- if (status == 15)
+ if (status == BOOTSTAGE_ID_RUN_OS)
display_flush();
}
#endif
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_ACTUX1;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_ACTUX2;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_ACTUX3;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_ACTUX4;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
#include <common.h>
#include <errno.h>
+#include <hush.h>
#include <linux/mtd/nand.h>
#include <nand.h>
#include <miiphy.h>
size_t size;
};
-static struct fit_images_info images[10];
+static struct fit_images_info imgs[10];
struct menu_display {
char title[50];
{
struct menu *m;
int i;
- char *choice = NULL;
+ void *choice = NULL;
char key[2];
int ret;
char *s;
sprintf(key, "%d", 1);
menu_default_set(m, key);
- if (menu_get_choice(m, (void **)&choice) != 1)
+ if (menu_get_choice(m, &choice) != 1)
debug("Problem picking a choice!\n");
menu_destroy(m);
sprintf(s, "%lx", i);
ret = setenv("header_addr", s);
if (ret == 0)
- ret = run_command2("run img_writeheader", 0);
+ ret = run_command("run img_writeheader", 0);
if (ret != 0)
break;
}
* img_writeramdisk: write ramdisk to ubi volume
*/
- while (images[count].type != IH_TYPE_INVALID) {
+ while (imgs[count].type != IH_TYPE_INVALID) {
printf("Installing %s\n",
- genimg_get_type_name(images[count].type));
- sprintf(s, "%p", images[count].data);
+ genimg_get_type_name(imgs[count].type));
+ sprintf(s, "%p", imgs[count].data);
setenv("img_addr_r", s);
- sprintf(s, "%lx", (unsigned long)images[count].size);
+ sprintf(s, "%lx", (unsigned long)imgs[count].size);
setenv("filesize", s);
- switch (images[count].subtype) {
+ switch (imgs[count].subtype) {
case FIT_SUBTYPE_DF_ENV_IMAGE:
- ret = run_command2("run img_writedfenv", 0);
+ ret = run_command("run img_writedfenv", 0);
break;
case FIT_SUBTYPE_RAMDISK_IMAGE:
t = getenv("img_volume");
if (ret != 0)
break;
- ret = run_command2("run img_writeramdisk", 0);
+ ret = run_command("run img_writeramdisk", 0);
break;
case FIT_SUBTYPE_SPL_IMAGE:
- ret = run_command2("run img_writespl", 0);
+ ret = run_command("run img_writespl", 0);
break;
case FIT_SUBTYPE_UBL_HEADER:
ret = ait_writeublheader();
break;
case FIT_SUBTYPE_UBOOT_IMAGE:
- ret = run_command2("run img_writeuboot", 0);
+ ret = run_command("run img_writeuboot", 0);
break;
default:
/* not supported type */
count++;
}
/* now save dvn_* and img_volume env vars to new values */
- if (ret == 0)
- ret = run_command2("run savenewvers", 0);
+ if (ret == 0) {
+ t = getenv("x_dvn_boot_vers");
+ if (t)
+ setenv("dvn_boot_vers", t);
+
+ t = getenv("x_dvn_app_vers");
+ if (t)
+ setenv("dvn_boot_vers", t);
+
+ setenv("x_dvn_boot_vers", NULL);
+ setenv("x_dvn_app_vers", NULL);
+ ret = run_command("run savenewvers", 0);
+ }
return ret;
}
break;
case '2':
/* cancel, back to main */
+ setenv("x_dvn_boot_vers", NULL);
+ setenv("x_dvn_app_vers", NULL);
break;
}
int found_uboot = -1;
int found_ramdisk = -1;
- memset(images, 0, sizeof(images));
+ memset(imgs, 0, sizeof(imgs));
s = getenv("fit_addr_r");
fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \
CONFIG_BOARD_IMG_ADDR_R;
fit_image_print(addr, noffset, "");
fit_image_get_type(addr, noffset,
- &images[count].type);
+ &imgs[count].type);
/* Mandatory properties */
ret = fit_get_desc(addr, noffset, &desc);
printf("Description: ");
if (ret) {
printf("unavailable\n");
} else {
- images[count].subtype = ait_subtype_nr(subtype);
+ imgs[count].subtype = ait_subtype_nr(subtype);
printf("%s %d\n", subtype,
- images[count].subtype);
+ imgs[count].subtype);
}
- sprintf(images[count].desc, "%s", desc);
+ sprintf(imgs[count].desc, "%s", desc);
ret = fit_image_get_data(addr, noffset,
- &images[count].data,
- &images[count].size);
+ &imgs[count].data,
+ &imgs[count].size);
printf("Data Size: ");
if (ret)
printf("unavailable\n");
else
- genimg_print_size(images[count].size);
- printf("Data @ %p\n", images[count].data);
+ genimg_print_size(imgs[count].size);
+ printf("Data @ %p\n", imgs[count].data);
count++;
}
}
for (i = 0; i < count; i++) {
- if (images[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE)
+ if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE)
found_uboot = i;
- if (images[i].type == IH_TYPE_RAMDISK) {
+ if (imgs[i].type == IH_TYPE_RAMDISK) {
found_ramdisk = i;
- images[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE;
+ imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE;
}
}
if (found_uboot >= 0) {
s = getenv("dvn_boot_vers");
if (s) {
- ret = strcmp(s, images[found_uboot].desc);
+ ret = strcmp(s, imgs[found_uboot].desc);
if (ret != 0) {
- setenv("dvn_boot_vers",
- images[found_uboot].desc);
+ setenv("x_dvn_boot_vers",
+ imgs[found_uboot].desc);
} else {
found_uboot = -1;
printf("no new uboot version\n");
}
} else {
- setenv("dvn_boot_vers", images[found_uboot].desc);
+ setenv("dvn_boot_vers", imgs[found_uboot].desc);
}
}
if (found_ramdisk >= 0) {
s = getenv("dvn_app_vers");
if (s) {
- ret = strcmp(s, images[found_ramdisk].desc);
+ ret = strcmp(s, imgs[found_ramdisk].desc);
if (ret != 0) {
- setenv("dvn_app_vers",
- images[found_ramdisk].desc);
+ setenv("x_dvn_app_vers",
+ imgs[found_ramdisk].desc);
} else {
found_ramdisk = -1;
printf("no new ramdisk version\n");
}
} else {
- setenv("dvn_app_vers", images[found_ramdisk].desc);
+ setenv("dvn_app_vers", imgs[found_ramdisk].desc);
}
}
if ((found_uboot == -1) && (found_ramdisk == -1))
break;
case '2':
/* load image */
- ret = run_command2("run load_img", 0);
+ ret = run_command("run load_img", 0);
printf("ret: %d\n", ret);
if (ret)
return MENU_UPDATE;
{
int ret;
- run_command2("run saveparms", 0);
+ run_command("run saveparms", 0);
ret = ait_menu_show(&ait_main, bootdelay);
- run_command2("run restoreparms", 0);
+ run_command("run restoreparms", 0);
if (ret == MENU_EXIT_BOOTCMD)
return 0;
void menu_display_statusline(struct menu *m)
{
- printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n",
- getenv("dvn_boot_vers"), getenv("dvn_app_vers"));
+ char *s1, *s2;
+
+ s1 = getenv("x_dvn_boot_vers");
+ if (!s1)
+ s1 = getenv("dvn_boot_vers");
+
+ s2 = getenv("x_dvn_app_vers");
+ if (!s2)
+ s2 = getenv("dvn_app_vers");
+
+ printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n", s1, s2);
return;
}
#endif
UBL_CONFIG = $(SRCTREE)/board/$(BOARDDIR)/ublimage.cfg
ifndef CONFIG_SPL_BUILD
ALL-y += $(obj)u-boot.ubl
+else
+# as SPL_TEXT_BASE is not page-aligned, we need for some
+# linkers the -n flag (Do not page align data), to prevent
+# the following error message:
+# arm-linux-ld: u-boot-spl: Not enough room for program headers, try linking
+# with -N
+LDFLAGS_u-boot-spl += -n
endif
ENTRY(_start)
SECTIONS
{
- . = 0x00000000;
+ . = CONFIG_SPL_TEXT_BASE;
. = ALIGN(4);
.text :
int misc_init_r (void)
{
-#ifdef CONFIG_PCI
- pci_init();
-#endif
setenv("verify", "n");
return (0);
}
* ARM Ltd.
* Philippe Robin, <philippe.robin@arm.com>
*
+ * (C) Copyright 2011
+ * Linaro
+ * Linus Walleij <linus.walleij@linaro.org>
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-
#include <common.h>
#include <pci.h>
+#include <asm/io.h>
+#include "integrator-sc.h"
+#include "pci_v3.h"
+
+#define INTEGRATOR_BOOT_ROM_BASE 0x20000000
+#define INTEGRATOR_HDR0_SDRAM_BASE 0x80000000
+
+/*
+ * These are in the physical addresses on the CPU side, i.e.
+ * where we read and write stuff - you don't want to try to
+ * move these around
+ */
+#define PHYS_PCI_MEM_BASE 0x40000000
+#define PHYS_PCI_IO_BASE 0x60000000 /* PCI I/O space base */
+#define PHYS_PCI_CONFIG_BASE 0x61000000
+#define PHYS_PCI_V3_BASE 0x62000000 /* V360EPC registers */
+#define SZ_256M 0x10000000
+
+/*
+ * These are in the PCI BUS address space
+ * Set to 0x00000000 in the Linux kernel, 0x40000000 in Boot monitor
+ * we follow the example of the kernel, because that is the address
+ * range that devices actually use - what would they be doing at
+ * 0x40000000?
+ */
+#define PCI_BUS_NONMEM_START 0x00000000
+#define PCI_BUS_NONMEM_SIZE SZ_256M
+
+#define PCI_BUS_PREMEM_START (PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE)
+#define PCI_BUS_PREMEM_SIZE SZ_256M
+
+#if PCI_BUS_NONMEM_START & 0x000fffff
+#error PCI_BUS_NONMEM_START must be megabyte aligned
+#endif
+#if PCI_BUS_PREMEM_START & 0x000fffff
+#error PCI_BUS_PREMEM_START must be megabyte aligned
+#endif
/*
* Initialize PCI Devices, report devices found.
*/
#ifndef CONFIG_PCI_PNP
+#define PCI_ENET0_IOADDR 0x60000000 /* First card in PCI I/O space */
+#define PCI_ENET0_MEMADDR 0x40000000 /* First card in PCI memory space */
static struct pci_config_table pci_integrator_config_table[] = {
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
#endif /* CONFIG_PCI_PNP */
/* V3 access routines */
-#define _V3Write16(o,v) (*(volatile unsigned short *)(PCI_V3_BASE + (unsigned int)(o)) = (unsigned short)(v))
-#define _V3Read16(o) (*(volatile unsigned short *)(PCI_V3_BASE + (unsigned int)(o)))
-
-#define _V3Write32(o,v) (*(volatile unsigned int *)(PCI_V3_BASE + (unsigned int)(o)) = (unsigned int)(v))
-#define _V3Read32(o) (*(volatile unsigned int *)(PCI_V3_BASE + (unsigned int)(o)))
-
-/* Compute address necessary to access PCI config space for the given */
-/* bus and device. */
-#define PCI_CONFIG_ADDRESS( __bus, __devfn, __offset ) ({ \
- unsigned int __address, __devicebit; \
- unsigned short __mapaddress; \
- unsigned int __dev = PCI_DEV (__devfn); /* FIXME to check!! (slot?) */ \
- \
- if (__bus == 0) { \
- /* local bus segment so need a type 0 config cycle */ \
- /* build the PCI configuration "address" with one-hot in A31-A11 */ \
- __address = PCI_CONFIG_BASE; \
- __address |= ((__devfn & 0x07) << 8); \
- __address |= __offset & 0xFF; \
- __mapaddress = 0x000A; /* 101=>config cycle, 0=>A1=A0=0 */ \
- __devicebit = (1 << (__dev + 11)); \
- \
- if ((__devicebit & 0xFF000000) != 0) { \
- /* high order bits are handled by the MAP register */ \
- __mapaddress |= (__devicebit >> 16); \
- } else { \
- /* low order bits handled directly in the address */ \
- __address |= __devicebit; \
- } \
- } else { /* bus !=0 */ \
- /* not the local bus segment so need a type 1 config cycle */ \
- /* A31-A24 are don't care (so clear to 0) */ \
- __mapaddress = 0x000B; /* 101=>config cycle, 1=>A1&A0 from PCI_CFG */ \
- __address = PCI_CONFIG_BASE; \
- __address |= ((__bus & 0xFF) << 16); /* bits 23..16 = bus number */ \
- __address |= ((__dev & 0x1F) << 11); /* bits 15..11 = device number */ \
- __address |= ((__devfn & 0x07) << 8); /* bits 10..8 = function number */ \
- __address |= __offset & 0xFF; /* bits 7..0 = register number */ \
- } \
- _V3Write16 (V3_LB_MAP1, __mapaddress); \
- __address; \
-})
-
-/* _V3OpenConfigWindow - open V3 configuration window */
-#define _V3OpenConfigWindow() { \
- /* Set up base0 to see all 512Mbytes of memory space (not */ \
- /* prefetchable), this frees up base1 for re-use by configuration*/ \
- /* memory */ \
- \
- _V3Write32 (V3_LB_BASE0, ((INTEGRATOR_PCI_BASE & 0xFFF00000) | \
- 0x90 | V3_LB_BASE_M_ENABLE)); \
- /* Set up base1 to point into configuration space, note that MAP1 */ \
- /* register is set up by pciMakeConfigAddress(). */ \
- \
- _V3Write32 (V3_LB_BASE1, ((CPU_PCI_CNFG_ADRS & 0xFFF00000) | \
- 0x40 | V3_LB_BASE_M_ENABLE)); \
+#define v3_writeb(o, v) __raw_writeb(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
+#define v3_readb(o) (__raw_readb(PHYS_PCI_V3_BASE + (unsigned int)(o)))
+
+#define v3_writew(o, v) __raw_writew(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
+#define v3_readw(o) (__raw_readw(PHYS_PCI_V3_BASE + (unsigned int)(o)))
+
+#define v3_writel(o, v) __raw_writel(v, PHYS_PCI_V3_BASE + (unsigned int)(o))
+#define v3_readl(o) (__raw_readl(PHYS_PCI_V3_BASE + (unsigned int)(o)))
+
+static unsigned long v3_open_config_window(pci_dev_t bdf, int offset)
+{
+ unsigned int address, mapaddress;
+ unsigned int busnr = PCI_BUS(bdf);
+ unsigned int devfn = PCI_FUNC(bdf);
+
+ /*
+ * Trap out illegal values
+ */
+ if (offset > 255)
+ BUG();
+ if (busnr > 255)
+ BUG();
+ if (devfn > 255)
+ BUG();
+
+ if (busnr == 0) {
+ /*
+ * Linux calls the thing U-Boot calls "DEV" "SLOT"
+ * instead, but it's the same 5 bits
+ */
+ int slot = PCI_DEV(bdf);
+
+ /*
+ * local bus segment so need a type 0 config cycle
+ *
+ * build the PCI configuration "address" with one-hot in
+ * A31-A11
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 are 0 (0)
+ */
+ address = PCI_FUNC(bdf) << 8;
+ mapaddress = V3_LB_MAP_TYPE_CONFIG;
+
+ if (slot > 12)
+ /*
+ * high order bits are handled by the MAP register
+ */
+ mapaddress |= 1 << (slot - 5);
+ else
+ /*
+ * low order bits handled directly in the address
+ */
+ address |= 1 << (slot + 11);
+ } else {
+ /*
+ * not the local bus segment so need a type 1 config cycle
+ *
+ * address:
+ * 23:16 = bus number
+ * 15:11 = slot number (7:3 of devfn)
+ * 10:8 = func number (2:0 of devfn)
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 from host bus (1)
+ */
+ mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
+ address = (busnr << 16) | (devfn << 8);
+ }
+
+ /*
+ * Set up base0 to see all 512Mbytes of memory space (not
+ * prefetchable), this frees up base1 for re-use by
+ * configuration memory
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
+
+ /*
+ * Set up base1/map1 to point into configuration space.
+ */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
+ V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, mapaddress);
+
+ return PHYS_PCI_CONFIG_BASE + address + offset;
}
-/* _V3CloseConfigWindow - close V3 configuration window */
-#define _V3CloseConfigWindow() { \
- /* Reassign base1 for use by prefetchable PCI memory */ \
- _V3Write32 (V3_LB_BASE1, (((INTEGRATOR_PCI_BASE + 0x10000000) & 0xFFF00000) \
- | 0x84 | V3_LB_BASE_M_ENABLE)); \
- _V3Write16 (V3_LB_MAP1, \
- (((INTEGRATOR_PCI_BASE + 0x10000000) & 0xFFF00000) >> 16) | 0x0006); \
- \
- /* And shrink base0 back to a 256M window (NOTE: MAP0 already correct) */ \
- \
- _V3Write32 (V3_LB_BASE0, ((INTEGRATOR_PCI_BASE & 0xFFF00000) | \
- 0x80 | V3_LB_BASE_M_ENABLE)); \
+static void v3_close_config_window(void)
+{
+ /*
+ * Reassign base1 for use by prefetchable PCI memory
+ */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+ /*
+ * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
}
-static int pci_integrator_read_byte (struct pci_controller *hose, pci_dev_t dev,
- int offset, unsigned char *val)
+static int pci_integrator_read_byte(struct pci_controller *hose, pci_dev_t bdf,
+ int offset, unsigned char *val)
{
- _V3OpenConfigWindow ();
- *val = *(volatile unsigned char *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset);
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ *val = __raw_readb(addr);
+ v3_close_config_window();
return 0;
}
-static int pci_integrator_read__word (struct pci_controller *hose,
- pci_dev_t dev, int offset,
- unsigned short *val)
+static int pci_integrator_read__word(struct pci_controller *hose,
+ pci_dev_t bdf, int offset,
+ unsigned short *val)
{
- _V3OpenConfigWindow ();
- *val = *(volatile unsigned short *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset);
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ *val = __raw_readw(addr);
+ v3_close_config_window();
return 0;
}
-static int pci_integrator_read_dword (struct pci_controller *hose,
- pci_dev_t dev, int offset,
- unsigned int *val)
+static int pci_integrator_read_dword(struct pci_controller *hose,
+ pci_dev_t bdf, int offset,
+ unsigned int *val)
{
- _V3OpenConfigWindow ();
- *val = *(volatile unsigned short *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset);
- *val |= (*(volatile unsigned int *)
- PCI_CONFIG_ADDRESS (PCI_BUS (dev), PCI_FUNC (dev),
- (offset + 2))) << 16;
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ *val = __raw_readl(addr);
+ v3_close_config_window();
return 0;
}
-static int pci_integrator_write_byte (struct pci_controller *hose,
- pci_dev_t dev, int offset,
- unsigned char val)
+static int pci_integrator_write_byte(struct pci_controller *hose,
+ pci_dev_t bdf, int offset,
+ unsigned char val)
{
- _V3OpenConfigWindow ();
- *(volatile unsigned char *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset) = val;
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ __raw_writeb((u8)val, addr);
+ __raw_readb(addr);
+ v3_close_config_window();
return 0;
}
-static int pci_integrator_write_word (struct pci_controller *hose,
- pci_dev_t dev, int offset,
- unsigned short val)
+static int pci_integrator_write_word(struct pci_controller *hose,
+ pci_dev_t bdf, int offset,
+ unsigned short val)
{
- _V3OpenConfigWindow ();
- *(volatile unsigned short *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset) = val;
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ __raw_writew((u8)val, addr);
+ __raw_readw(addr);
+ v3_close_config_window();
return 0;
}
-static int pci_integrator_write_dword (struct pci_controller *hose,
- pci_dev_t dev, int offset,
- unsigned int val)
+static int pci_integrator_write_dword(struct pci_controller *hose,
+ pci_dev_t bdf, int offset,
+ unsigned int val)
{
- _V3OpenConfigWindow ();
- *(volatile unsigned short *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- offset) = (val & 0xFFFF);
- *(volatile unsigned short *) PCI_CONFIG_ADDRESS (PCI_BUS (dev),
- PCI_FUNC (dev),
- (offset + 2)) = ((val >> 16) & 0xFFFF);
- _V3CloseConfigWindow ();
+ unsigned long addr;
+ addr = v3_open_config_window(bdf, offset);
+ __raw_writel((u8)val, addr);
+ __raw_readl(addr);
+ v3_close_config_window();
return 0;
}
-/******************************
- * PCI initialisation
- ******************************/
struct pci_controller integrator_hose = {
#ifndef CONFIG_PCI_PNP
#endif
};
-void pci_init_board (void)
+void pci_init_board(void)
{
- volatile int i, j;
struct pci_controller *hose = &integrator_hose;
+ u16 val;
/* setting this register will take the V3 out of reset */
+ __raw_writel(SC_PCI_PCIEN, SC_PCI);
- *(volatile unsigned int *) (INTEGRATOR_SC_PCIENABLE) = 1;
-
- /* wait a few usecs to settle the device and the PCI bus */
+ /* Wait for 230 ms (from spec) before accessing any V3 registers */
+ mdelay(230);
- for (i = 0; i < 100; i++)
- j = i + 1;
-
- /* Now write the Base I/O Address Word to V3_BASE + 0x6C */
-
- *(volatile unsigned short *) (V3_BASE + V3_LB_IO_BASE) =
- (unsigned short) (V3_BASE >> 16);
+ /* Now write the Base I/O Address Word to PHYS_PCI_V3_BASE + 0x6E */
+ v3_writew(V3_LB_IO_BASE, (PHYS_PCI_V3_BASE >> 16));
+ /* Wait for the mailbox to settle */
do {
- *(volatile unsigned char *) (V3_BASE + V3_MAIL_DATA) = 0xAA;
- *(volatile unsigned char *) (V3_BASE + V3_MAIL_DATA + 4) =
- 0x55;
- } while (*(volatile unsigned char *) (V3_BASE + V3_MAIL_DATA) != 0xAA
- || *(volatile unsigned char *) (V3_BASE + V3_MAIL_DATA +
- 4) != 0x55);
+ v3_writeb(V3_MAIL_DATA, 0xAA);
+ v3_writeb(V3_MAIL_DATA + 4, 0x55);
+ } while (v3_readb(V3_MAIL_DATA) != 0xAA ||
+ v3_readb(V3_MAIL_DATA + 4) != 0x55);
/* Make sure that V3 register access is not locked, if it is, unlock it */
+ if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
+ v3_writew(V3_SYSTEM, 0xA05F);
- if ((*(volatile unsigned short *) (V3_BASE + V3_SYSTEM) &
- V3_SYSTEM_M_LOCK)
- == V3_SYSTEM_M_LOCK)
- *(volatile unsigned short *) (V3_BASE + V3_SYSTEM) = 0xA05F;
-
- /* Ensure that the slave accesses from PCI are disabled while we */
- /* setup windows */
-
- *(volatile unsigned short *) (V3_BASE + V3_PCI_CMD) &=
- ~(V3_COMMAND_M_MEM_EN | V3_COMMAND_M_IO_EN);
+ /*
+ * Ensure that the slave accesses from PCI are disabled while we
+ * setup memory windows
+ */
+ val = v3_readw(V3_PCI_CMD);
+ val &= ~(V3_COMMAND_M_MEM_EN | V3_COMMAND_M_IO_EN);
+ v3_writew(V3_PCI_CMD, val);
/* Clear RST_OUT to 0; keep the PCI bus in reset until we've finished */
-
- *(volatile unsigned short *) (V3_BASE + V3_SYSTEM) &=
- ~V3_SYSTEM_M_RST_OUT;
+ val = v3_readw(V3_SYSTEM);
+ val &= ~V3_SYSTEM_M_RST_OUT;
+ v3_writew(V3_SYSTEM, val);
/* Make all accesses from PCI space retry until we're ready for them */
+ val = v3_readw(V3_PCI_CFG);
+ val |= V3_PCI_CFG_M_RETRY_EN;
+ v3_writew(V3_PCI_CFG, val);
- *(volatile unsigned short *) (V3_BASE + V3_PCI_CFG) |=
- V3_PCI_CFG_M_RETRY_EN;
-
- /* Set up any V3 PCI Configuration Registers that we absolutely have to */
- /* LB_CFG controls Local Bus protocol. */
- /* Enable LocalBus byte strobes for READ accesses too. */
- /* set bit 7 BE_IMODE and bit 6 BE_OMODE */
-
- *(volatile unsigned short *) (V3_BASE + V3_LB_CFG) |= 0x0C0;
-
- /* PCI_CMD controls overall PCI operation. */
- /* Enable PCI bus master. */
-
- *(volatile unsigned short *) (V3_BASE + V3_PCI_CMD) |= 0x04;
+ /*
+ * Set up any V3 PCI Configuration Registers that we absolutely have to.
+ * LB_CFG controls Local Bus protocol.
+ * Enable LocalBus byte strobes for READ accesses too.
+ * set bit 7 BE_IMODE and bit 6 BE_OMODE
+ */
+ val = v3_readw(V3_LB_CFG);
+ val |= 0x0C0;
+ v3_writew(V3_LB_CFG, val);
- /* PCI_MAP0 controls where the PCI to CPU memory window is on Local Bus */
+ /* PCI_CMD controls overall PCI operation. Enable PCI bus master. */
+ val = v3_readw(V3_PCI_CMD);
+ val |= V3_COMMAND_M_MASTER_EN;
+ v3_writew(V3_PCI_CMD, val);
- *(volatile unsigned int *) (V3_BASE + V3_PCI_MAP0) =
- (INTEGRATOR_BOOT_ROM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_512M |
- V3_PCI_MAP_M_REG_EN |
- V3_PCI_MAP_M_ENABLE);
+ /*
+ * PCI_MAP0 controls where the PCI to CPU memory window is on
+ * Local Bus
+ */
+ v3_writel(V3_PCI_MAP0,
+ (INTEGRATOR_BOOT_ROM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_512MB |
+ V3_PCI_MAP_M_REG_EN |
+ V3_PCI_MAP_M_ENABLE));
/* PCI_BASE0 is the PCI address of the start of the window */
-
- *(volatile unsigned int *) (V3_BASE + V3_PCI_BASE0) =
- INTEGRATOR_BOOT_ROM_BASE;
+ v3_writel(V3_PCI_BASE0, INTEGRATOR_BOOT_ROM_BASE);
/* PCI_MAP1 is LOCAL address of the start of the window */
-
- *(volatile unsigned int *) (V3_BASE + V3_PCI_MAP1) =
- (INTEGRATOR_HDR0_SDRAM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_1024M |
- V3_PCI_MAP_M_REG_EN |
- V3_PCI_MAP_M_ENABLE);
+ v3_writel(V3_PCI_MAP1,
+ (INTEGRATOR_HDR0_SDRAM_BASE) | (V3_PCI_MAP_M_ADR_SIZE_1GB |
+ V3_PCI_MAP_M_REG_EN |
+ V3_PCI_MAP_M_ENABLE));
/* PCI_BASE1 is the PCI address of the start of the window */
+ v3_writel(V3_PCI_BASE1, INTEGRATOR_HDR0_SDRAM_BASE);
- *(volatile unsigned int *) (V3_BASE + V3_PCI_BASE1) =
- INTEGRATOR_HDR0_SDRAM_BASE;
-
- /* Set up the windows from local bus memory into PCI configuration, */
- /* I/O and Memory. */
- /* PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this. */
-
- *(volatile unsigned short *) (V3_BASE + V3_LB_BASE2) =
- ((CPU_PCI_IO_ADRS >> 24) << 8) | V3_LB_BASE_M_ENABLE;
- *(volatile unsigned short *) (V3_BASE + V3_LB_MAP2) = 0;
+ /*
+ * Set up memory the windows from local bus memory into PCI
+ * configuration, I/O and Memory regions.
+ * PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this.
+ */
+ v3_writew(V3_LB_BASE2,
+ v3_addr_to_lb_map(PHYS_PCI_IO_BASE) | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP2, 0);
/* PCI Configuration, use LB_BASE1/LB_MAP1. */
- /* PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1 */
- /* Map first 256Mbytes as non-prefetchable via BASE0/MAP0 */
- /* (INTEGRATOR_PCI_BASE == PCI_MEM_BASE) */
-
- *(volatile unsigned int *) (V3_BASE + V3_LB_BASE0) =
- INTEGRATOR_PCI_BASE | (0x80 | V3_LB_BASE_M_ENABLE);
-
- *(volatile unsigned short *) (V3_BASE + V3_LB_MAP0) =
- ((INTEGRATOR_PCI_BASE >> 20) << 0x4) | 0x0006;
+ /*
+ * PCI Memory use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1
+ * Map first 256Mbytes as non-prefetchable via BASE0/MAP0
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP0,
+ v3_addr_to_lb_map(PCI_BUS_NONMEM_START) | V3_LB_MAP_TYPE_MEM);
/* Map second 256 Mbytes as prefetchable via BASE1/MAP1 */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+ /* Dump PCI to local address space mappings */
+ debug("LB_BASE0 = %08x\n", v3_readl(V3_LB_BASE0));
+ debug("LB_MAP0 = %04x\n", v3_readw(V3_LB_MAP0));
+ debug("LB_BASE1 = %08x\n", v3_readl(V3_LB_BASE1));
+ debug("LB_MAP1 = %04x\n", v3_readw(V3_LB_MAP1));
+ debug("LB_BASE2 = %04x\n", v3_readw(V3_LB_BASE2));
+ debug("LB_MAP2 = %04x\n", v3_readw(V3_LB_MAP2));
+ debug("LB_IO_BASE = %04x\n", v3_readw(V3_LB_IO_BASE));
- *(volatile unsigned int *) (V3_BASE + V3_LB_BASE1) =
- INTEGRATOR_PCI_BASE | (0x84 | V3_LB_BASE_M_ENABLE);
-
- *(volatile unsigned short *) (V3_BASE + V3_LB_MAP1) =
- (((INTEGRATOR_PCI_BASE + 0x10000000) >> 20) << 4) | 0x0006;
-
- /* Allow accesses to PCI Configuration space */
- /* and set up A1, A0 for type 1 config cycles */
-
- *(volatile unsigned short *) (V3_BASE + V3_PCI_CFG) =
- ((*(volatile unsigned short *) (V3_BASE + V3_PCI_CFG)) &
- ~(V3_PCI_CFG_M_RETRY_EN | V3_PCI_CFG_M_AD_LOW1)) |
- V3_PCI_CFG_M_AD_LOW0;
-
- /* now we can allow in PCI MEMORY accesses */
-
- *(volatile unsigned short *) (V3_BASE + V3_PCI_CMD) =
- (*(volatile unsigned short *) (V3_BASE + V3_PCI_CMD)) |
- V3_COMMAND_M_MEM_EN;
+ /*
+ * Allow accesses to PCI Configuration space and set up A1, A0 for
+ * type 1 config cycles
+ */
+ val = v3_readw(V3_PCI_CFG);
+ val &= ~(V3_PCI_CFG_M_RETRY_EN | V3_PCI_CFG_M_AD_LOW1);
+ val |= V3_PCI_CFG_M_AD_LOW0;
+ v3_writew(V3_PCI_CFG, val);
- /* Set RST_OUT to take the PCI bus is out of reset, PCI devices can */
- /* initialise and lock the V3 system register so that no one else */
- /* can play with it */
+ /* now we can allow incoming PCI MEMORY accesses */
+ val = v3_readw(V3_PCI_CMD);
+ val |= V3_COMMAND_M_MEM_EN;
+ v3_writew(V3_PCI_CMD, val);
- *(volatile unsigned short *) (V3_BASE + V3_SYSTEM) =
- (*(volatile unsigned short *) (V3_BASE + V3_SYSTEM)) |
- V3_SYSTEM_M_RST_OUT;
+ /*
+ * Set RST_OUT to take the PCI bus is out of reset, PCI devices can
+ * now initialise.
+ */
+ val = v3_readw(V3_SYSTEM);
+ val |= V3_SYSTEM_M_RST_OUT;
+ v3_writew(V3_SYSTEM, val);
- *(volatile unsigned short *) (V3_BASE + V3_SYSTEM) =
- (*(volatile unsigned short *) (V3_BASE + V3_SYSTEM)) |
- V3_SYSTEM_M_LOCK;
+ /* Lock the V3 system register so that no one else can play with it */
+ val = v3_readw(V3_SYSTEM);
+ val |= V3_SYSTEM_M_LOCK;
+ v3_writew(V3_SYSTEM, val);
/*
- * Register the hose
+ * Configure and register the PCI hose
*/
hose->first_busno = 0;
hose->last_busno = 0xff;
- /* System memory space */
- pci_set_region (hose->regions + 0,
- 0x00000000, 0x40000000, 0x01000000,
- PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+ /* System memory space, window 0 256 MB non-prefetchable */
+ pci_set_region(hose->regions + 0,
+ PCI_BUS_NONMEM_START, PHYS_PCI_MEM_BASE,
+ SZ_256M,
+ PCI_REGION_MEM);
- /* PCI Memory - config space */
- pci_set_region (hose->regions + 1,
- 0x00000000, 0x62000000, 0x01000000, PCI_REGION_MEM);
-
- /* PCI V3 regs */
- pci_set_region (hose->regions + 2,
- 0x00000000, 0x61000000, 0x00080000, PCI_REGION_MEM);
+ /* System memory space, window 1 256 MB prefetchable */
+ pci_set_region(hose->regions + 1,
+ PCI_BUS_PREMEM_START, PHYS_PCI_MEM_BASE + SZ_256M,
+ SZ_256M,
+ PCI_REGION_MEM |
+ PCI_REGION_PREFETCH);
/* PCI I/O space */
- pci_set_region (hose->regions + 3,
- 0x00000000, 0x60000000, 0x00010000, PCI_REGION_IO);
+ pci_set_region(hose->regions + 2,
+ 0x00000000, PHYS_PCI_IO_BASE, 0x01000000,
+ PCI_REGION_IO);
+
+ /* PCI Memory - config space */
+ pci_set_region(hose->regions + 3,
+ 0x00000000, PHYS_PCI_CONFIG_BASE, 0x01000000,
+ PCI_REGION_MEM);
+ /* PCI V3 regs */
+ pci_set_region(hose->regions + 4,
+ 0x00000000, PHYS_PCI_V3_BASE, 0x01000000,
+ PCI_REGION_MEM);
- pci_set_ops (hose,
- pci_integrator_read_byte,
- pci_integrator_read__word,
- pci_integrator_read_dword,
- pci_integrator_write_byte,
- pci_integrator_write_word, pci_integrator_write_dword);
+ hose->region_count = 5;
- hose->region_count = 4;
+ pci_set_ops(hose,
+ pci_integrator_read_byte,
+ pci_integrator_read__word,
+ pci_integrator_read_dword,
+ pci_integrator_write_byte,
+ pci_integrator_write_word,
+ pci_integrator_write_dword);
- pci_register_hose (hose);
+ pci_register_hose(hose);
- pciauto_config_init (hose);
- pciauto_config_device (hose, 0);
+ pciauto_config_init(hose);
+ pciauto_config_device(hose, 0);
- hose->last_busno = pci_hose_scan (hose);
+ hose->last_busno = pci_hose_scan(hose);
}
--- /dev/null
+/*
+ * arch/arm/include/asm/hardware/pci_v3.h
+ *
+ * Internal header file PCI V3 chip
+ *
+ * Copyright (C) ARM Limited
+ * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef ASM_ARM_HARDWARE_PCI_V3_H
+#define ASM_ARM_HARDWARE_PCI_V3_H
+
+/* -------------------------------------------------------------------------------
+ * V3 Local Bus to PCI Bridge definitions
+ * -------------------------------------------------------------------------------
+ * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ * All V3 register names are prefaced by V3_ to avoid clashing with any other
+ * PCI definitions. Their names match the user's manual.
+ *
+ * I'm assuming that I20 is disabled.
+ *
+ */
+#define V3_PCI_VENDOR 0x00000000
+#define V3_PCI_DEVICE 0x00000002
+#define V3_PCI_CMD 0x00000004
+#define V3_PCI_STAT 0x00000006
+#define V3_PCI_CC_REV 0x00000008
+#define V3_PCI_HDR_CFG 0x0000000C
+#define V3_PCI_IO_BASE 0x00000010
+#define V3_PCI_BASE0 0x00000014
+#define V3_PCI_BASE1 0x00000018
+#define V3_PCI_SUB_VENDOR 0x0000002C
+#define V3_PCI_SUB_ID 0x0000002E
+#define V3_PCI_ROM 0x00000030
+#define V3_PCI_BPARAM 0x0000003C
+#define V3_PCI_MAP0 0x00000040
+#define V3_PCI_MAP1 0x00000044
+#define V3_PCI_INT_STAT 0x00000048
+#define V3_PCI_INT_CFG 0x0000004C
+#define V3_LB_BASE0 0x00000054
+#define V3_LB_BASE1 0x00000058
+#define V3_LB_MAP0 0x0000005E
+#define V3_LB_MAP1 0x00000062
+#define V3_LB_BASE2 0x00000064
+#define V3_LB_MAP2 0x00000066
+#define V3_LB_SIZE 0x00000068
+#define V3_LB_IO_BASE 0x0000006E
+#define V3_FIFO_CFG 0x00000070
+#define V3_FIFO_PRIORITY 0x00000072
+#define V3_FIFO_STAT 0x00000074
+#define V3_LB_ISTAT 0x00000076
+#define V3_LB_IMASK 0x00000077
+#define V3_SYSTEM 0x00000078
+#define V3_LB_CFG 0x0000007A
+#define V3_PCI_CFG 0x0000007C
+#define V3_DMA_PCI_ADR0 0x00000080
+#define V3_DMA_PCI_ADR1 0x00000090
+#define V3_DMA_LOCAL_ADR0 0x00000084
+#define V3_DMA_LOCAL_ADR1 0x00000094
+#define V3_DMA_LENGTH0 0x00000088
+#define V3_DMA_LENGTH1 0x00000098
+#define V3_DMA_CSR0 0x0000008B
+#define V3_DMA_CSR1 0x0000009B
+#define V3_DMA_CTLB_ADR0 0x0000008C
+#define V3_DMA_CTLB_ADR1 0x0000009C
+#define V3_DMA_DELAY 0x000000E0
+#define V3_MAIL_DATA 0x000000C0
+#define V3_PCI_MAIL_IEWR 0x000000D0
+#define V3_PCI_MAIL_IERD 0x000000D2
+#define V3_LB_MAIL_IEWR 0x000000D4
+#define V3_LB_MAIL_IERD 0x000000D6
+#define V3_MAIL_WR_STAT 0x000000D8
+#define V3_MAIL_RD_STAT 0x000000DA
+#define V3_QBA_MAP 0x000000DC
+
+/* PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN (1 << 9)
+#define V3_COMMAND_M_SERR_EN (1 << 8)
+#define V3_COMMAND_M_PAR_EN (1 << 6)
+#define V3_COMMAND_M_MASTER_EN (1 << 2)
+#define V3_COMMAND_M_MEM_EN (1 << 1)
+#define V3_COMMAND_M_IO_EN (1 << 0)
+
+/* SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT (1 << 15)
+#define V3_SYSTEM_M_LOCK (1 << 14)
+
+/* PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_I2O_EN (1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS (1 << 14)
+#define V3_PCI_CFG_M_IO_DIS (1 << 13)
+#define V3_PCI_CFG_M_EN3V (1 << 12)
+#define V3_PCI_CFG_M_RETRY_EN (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1 (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0 (1 << 8)
+
+/* PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH (1 << 3)
+#define V3_PCI_BASE_M_TYPE (3 << 1)
+#define V3_PCI_BASE_M_IO (1 << 0)
+
+/* PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE (3 << 10)
+#define V3_PCI_MAP_M_SWAP (3 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0
+#define V3_PCI_MAP_M_REG_EN (1 << 1)
+#define V3_PCI_MAP_M_ENABLE (1 << 0)
+
+#define V3_PCI_MAP_M_ADR_SIZE_1MB (0 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_2MB (1 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_4MB (2 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_8MB (3 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_16MB (4 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_32MB (5 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_64MB (6 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_128MB (7 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_256MB (8 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_512MB (9 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_1GB (10 << 4)
+#define V3_PCI_MAP_M_ADR_SIZE_2GB (11 << 4)
+
+/*
+ * LB_BASE0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_ADR_BASE 0xfff00000
+#define V3_LB_BASE_SWAP (3 << 8)
+#define V3_LB_BASE_ADR_SIZE (15 << 4)
+#define V3_LB_BASE_PREFETCH (1 << 3)
+#define V3_LB_BASE_ENABLE (1 << 0)
+
+#define V3_LB_BASE_ADR_SIZE_1MB (0 << 4)
+#define V3_LB_BASE_ADR_SIZE_2MB (1 << 4)
+#define V3_LB_BASE_ADR_SIZE_4MB (2 << 4)
+#define V3_LB_BASE_ADR_SIZE_8MB (3 << 4)
+#define V3_LB_BASE_ADR_SIZE_16MB (4 << 4)
+#define V3_LB_BASE_ADR_SIZE_32MB (5 << 4)
+#define V3_LB_BASE_ADR_SIZE_64MB (6 << 4)
+#define V3_LB_BASE_ADR_SIZE_128MB (7 << 4)
+#define V3_LB_BASE_ADR_SIZE_256MB (8 << 4)
+#define V3_LB_BASE_ADR_SIZE_512MB (9 << 4)
+#define V3_LB_BASE_ADR_SIZE_1GB (10 << 4)
+#define V3_LB_BASE_ADR_SIZE_2GB (11 << 4)
+
+#define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE)
+
+/*
+ * LB_MAP0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_MAP_ADR 0xfff0
+#define V3_LB_MAP_TYPE (7 << 1)
+#define V3_LB_MAP_AD_LOW_EN (1 << 0)
+
+#define V3_LB_MAP_TYPE_IACK (0 << 1)
+#define V3_LB_MAP_TYPE_IO (1 << 1)
+#define V3_LB_MAP_TYPE_MEM (3 << 1)
+#define V3_LB_MAP_TYPE_CONFIG (5 << 1)
+#define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1)
+
+/* PCI MAP register bits (PCI -> Local bus) */
+#define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR)
+
+/*
+ * LB_BASE2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_BASE2_ADR_BASE 0xff00
+#define V3_LB_BASE2_SWAP (3 << 6)
+#define V3_LB_BASE2_ENABLE (1 << 0)
+
+#define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE)
+
+/*
+ * LB_MAP2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_MAP2_MAP_ADR 0xff00
+
+#define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR)
+
+#endif
ulong get_board_rev(void){
return readl((u32 *)SYS_ID);
}
+
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+ulong get_tbclk (void)
+{
+ return (ulong)CONFIG_SYS_HZ;
+}
void show_boot_progress(int status)
{
switch (status) {
- case 1:
+ case BOOTSTAGE_ID_CHECK_MAGIC:
stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_ON);
break;
- case 2:
+ case BOOTSTAGE_ID_CHECK_HEADER:
stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_OFF);
break;
- case 3:
+ case BOOTSTAGE_ID_CHECK_CHECKSUM:
stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_ON);
break;
- case 4:
+ case BOOTSTAGE_ID_CHECK_ARCH:
stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_OFF);
break;
- case 5:
- case 6:
+ case BOOTSTAGE_ID_CHECK_IMAGETYPE:
+ case BOOTSTAGE_ID_DECOMP_IMAGE:
stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_ON);
break;
- case 7:
- case 8:
+ case BOOTSTAGE_ID_KERNEL_LOADED:
+ case BOOTSTAGE_ID_CHECK_BOOT_OS:
stamp_led_set(STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_OFF);
break;
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
+ case BOOTSTAGE_ID_BOOT_OS_RETURNED:
+ case BOOTSTAGE_ID_RD_MAGIC:
+ case BOOTSTAGE_ID_RD_HDR_CHECKSUM:
+ case BOOTSTAGE_ID_RD_CHECKSUM:
+ case BOOTSTAGE_ID_RAMDISK:
+ case BOOTSTAGE_ID_NO_RAMDISK:
+ case BOOTSTAGE_ID_RUN_OS:
stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_OFF);
break;
default:
#include <i2c.h>
#include <net.h>
#include <netdev.h>
+#include <spi.h>
+#include <spi_flash.h>
#include <asm/arch/hardware.h>
#include <asm/arch/emif_defs.h>
#include <asm/arch/emac_defs.h>
#include <asm/arch/pinmux_defs.h>
#include <asm/io.h>
#include <asm/arch/davinci_misc.h>
+#include <asm/errno.h>
#include <hwconfig.h>
DECLARE_GLOBAL_DATA_PTR;
#endif
#endif /* CONFIG_DRIVER_TI_EMAC */
+#define CFG_MAC_ADDR_SPI_BUS 0
+#define CFG_MAC_ADDR_SPI_CS 0
+#define CFG_MAC_ADDR_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#define CFG_MAC_ADDR_SPI_MODE SPI_MODE_3
+
+#define CFG_MAC_ADDR_OFFSET (flash->size - SZ_64K)
+
+#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
+static int get_mac_addr(u8 *addr)
+{
+ struct spi_flash *flash;
+ int ret;
+
+ flash = spi_flash_probe(CFG_MAC_ADDR_SPI_BUS, CFG_MAC_ADDR_SPI_CS,
+ CFG_MAC_ADDR_SPI_MAX_HZ, CFG_MAC_ADDR_SPI_MODE);
+ if (!flash) {
+ printf("Error - unable to probe SPI flash.\n");
+ return -1;
+ }
+
+ ret = spi_flash_read(flash, CFG_MAC_ADDR_OFFSET, 6, addr);
+ if (ret) {
+ printf("Error - unable to read MAC address from SPI flash.\n");
+ return -1;
+ }
+
+ return ret;
+}
+#endif
+
void dsp_lpsc_on(unsigned domain, unsigned int id)
{
dv_reg_p mdstat, mdctl, ptstat, ptcmd;
int misc_init_r(void)
{
dspwake();
+
+#if defined(CONFIG_MAC_ADDR_IN_SPIFLASH) || defined(CONFIG_MAC_ADDR_IN_EEPROM)
+
+ uchar env_enetaddr[6];
+ int enetaddr_found;
+
+ enetaddr_found = eth_getenv_enetaddr("ethaddr", env_enetaddr);
+
+#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
+ int spi_mac_read;
+ uchar buff[6];
+
+ spi_mac_read = get_mac_addr(buff);
+
+ /*
+ * MAC address not present in the environment
+ * try and read the MAC address from SPI flash
+ * and set it.
+ */
+ if (!enetaddr_found) {
+ if (!spi_mac_read) {
+ if (is_valid_ether_addr(buff)) {
+ if (eth_setenv_enetaddr("ethaddr", buff)) {
+ printf("Warning: Failed to "
+ "set MAC address from SPI flash\n");
+ }
+ } else {
+ printf("Warning: Invalid "
+ "MAC address read from SPI flash\n");
+ }
+ }
+ } else {
+ /*
+ * MAC address present in environment compare it with
+ * the MAC address in SPI flash and warn on mismatch
+ */
+ if (!spi_mac_read && is_valid_ether_addr(buff) &&
+ memcmp(env_enetaddr, buff, 6))
+ printf("Warning: MAC address in SPI flash don't match "
+ "with the MAC address in the environment\n");
+ printf("Default using MAC address from environment\n");
+ }
+#endif
+ uint8_t enetaddr[8];
+ int eeprom_mac_read;
+
+ /* Read Ethernet MAC address from EEPROM */
+ eeprom_mac_read = dvevm_read_mac_address(enetaddr);
+
+ /*
+ * MAC address not present in the environment
+ * try and read the MAC address from EEPROM flash
+ * and set it.
+ */
+ if (!enetaddr_found) {
+ if (eeprom_mac_read)
+ /* Set Ethernet MAC address from EEPROM */
+ davinci_sync_env_enetaddr(enetaddr);
+ } else {
+ /*
+ * MAC address present in environment compare it with
+ * the MAC address in EEPROM and warn on mismatch
+ */
+ if (eeprom_mac_read && memcmp(enetaddr, env_enetaddr, 6))
+ printf("Warning: MAC address in EEPROM don't match "
+ "with the MAC address in the environment\n");
+ printf("Default using MAC address from environment\n");
+ }
+
+#endif
return 0;
}
u32 get_board_rev(void)
{
-#ifdef DAVINCI_DM6467TEVM
+#ifdef CONFIG_DAVINCI_DM6467TEVM
return REV_DM6467TEVM;
#else
return REV_DM6467EVM;
#include <asm/arch/emac_defs.h>
#include <asm/io.h>
#include <asm/arch/davinci_misc.h>
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
#include <asm/arch/da8xx-fb.h>
DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
- struct davinci_gpio *gpio6_base =
- (struct davinci_gpio *)DAVINCI_GPIO_BANK67;
-
/* PinMux for GPIO */
if (davinci_configure_pin_mux(gpio_pins, ARRAY_SIZE(gpio_pins)) != 0)
return 1;
/* Set the RESETOUTn low */
- writel((readl(&gpio6_base->set_data) & ~(1 << 15)),
- &gpio6_base->set_data);
- writel((readl(&gpio6_base->dir) & ~(1 << 15)), &gpio6_base->dir);
+ gpio_direction_output(111, 0);
/* Set U0_SW0 low for UART0 as console*/
- writel((readl(&gpio6_base->set_data) & ~(1 << 10)),
- &gpio6_base->set_data);
- writel((readl(&gpio6_base->dir) & ~(1 << 10)), &gpio6_base->dir);
+ gpio_direction_output(106, 0);
/* Set U0_SW1 low for UART0 as console*/
- writel((readl(&gpio6_base->set_data) & ~(1 << 12)),
- &gpio6_base->set_data);
- writel((readl(&gpio6_base->dir) & ~(1 << 12)), &gpio6_base->dir);
+ gpio_direction_output(108, 0);
/* Set LCD_B_PWR low to power down LCD Backlight*/
- writel((readl(&gpio6_base->set_data) & ~(1 << 6)),
- &gpio6_base->set_data);
- writel((readl(&gpio6_base->dir) & ~(1 << 6)), &gpio6_base->dir);
+ gpio_direction_output(102, 0);
/* Set DISP_ON low to disable LCD output*/
- writel((readl(&gpio6_base->set_data) & ~(1 << 1)),
- &gpio6_base->set_data);
- writel((readl(&gpio6_base->dir) & ~(1 << 1)), &gpio6_base->dir);
+ gpio_direction_output(97, 0);
#ifndef CONFIG_USE_IRQ
irq_init();
&davinci_syscfg_regs->mstpri[2]);
/* Set LCD_B_PWR low to power up LCD Backlight*/
- writel((readl(&gpio6_base->set_data) | (1 << 6)),
- &gpio6_base->set_data);
+ gpio_set_value(102, 1);
/* Set DISP_ON low to disable LCD output*/
- writel((readl(&gpio6_base->set_data) | (1 << 1)),
- &gpio6_base->set_data);
+ gpio_set_value(97, 1);
return 0;
}
int board_late_init(void)
{
- struct davinci_gpio *gpio8_base =
- (struct davinci_gpio *)DAVINCI_GPIO_BANK8;
-
/* PinMux for HALTEN */
if (davinci_configure_pin_mux(halten_pin, ARRAY_SIZE(halten_pin)) != 0)
return 1;
/* Set HALTEN to high */
- writel((readl(&gpio8_base->set_data) | (1 << 6)),
- &gpio8_base->set_data);
- writel((readl(&gpio8_base->dir) & ~(1 << 6)), &gpio8_base->dir);
+ gpio_direction_output(134, 1);
setenv("stdout", "serial");
#include <asm/arch/sys_proto.h>
#define MUX_CONFIG_LED (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
-#define MUX_CONFIG_LCD (MXS_PAD_3V3 | MXS_PAD_4MA)
+#define MUX_CONFIG_LCD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
#define MUX_CONFIG_TSC (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_PULLUP)
#define MUX_CONFIG_SSP2 (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
MX28_PAD_LCD_D21__LCD_D21 | MUX_CONFIG_LCD,
MX28_PAD_LCD_D22__LCD_D22 | MUX_CONFIG_LCD,
MX28_PAD_LCD_D23__LCD_D23 | MUX_CONFIG_LCD,
- MX28_PAD_LCD_RD_E__LCD_VSYNC | MUX_CONFIG_LCD,
- MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MUX_CONFIG_LCD,
- MX28_PAD_LCD_RS__LCD_DOTCLK | MUX_CONFIG_LCD,
- MX28_PAD_LCD_CS__LCD_CS | MUX_CONFIG_LCD,
- MX28_PAD_LCD_VSYNC__LCD_VSYNC | MUX_CONFIG_LCD,
- MX28_PAD_LCD_HSYNC__LCD_HSYNC | MUX_CONFIG_LCD,
MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | MUX_CONFIG_LCD,
- MX28_PAD_LCD_ENABLE__GPIO_1_31 | MUX_CONFIG_LCD,
- MX28_PAD_LCD_RESET__GPIO_3_30 | MUX_CONFIG_LCD,
+ MX28_PAD_LCD_ENABLE__LCD_ENABLE | MUX_CONFIG_LCD,
/* UART1 */
+#ifdef CONFIG_DENX_M28_V10
+ MX28_PAD_AUART0_CTS__DUART_RX,
+ MX28_PAD_AUART0_RTS__DUART_TX,
+#else
MX28_PAD_PWM0__DUART_RX,
MX28_PAD_PWM1__DUART_TX,
+#endif
MX28_PAD_AUART0_TX__DUART_RTS,
MX28_PAD_AUART0_RX__DUART_CTS,
int board_init(void)
{
- gd->bd->bi_arch_number = MACH_TYPE_DVLHOST;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
int last_stage_init(void)
{
- int minor;
- int major;
-
- major = minor = 0;
-
outb(0x00, LED_LATCH_ADDRESS);
register_timer_isr(enet_timer_isr);
ulpi_write(&ulpi_vp, &ulpi->otg_ctrl_set, ULPI_OTG_CHRGVBUS);
- wait_ms(50);
+ mdelay(50);
/* terminate the reset */
*reg = ehci_readl(status_reg);
#include <spi.h>
#include <dataflash.h>
#include <mmc.h>
+#include <atmel_mci.h>
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91sam9260_matrix.h>
return atmel_mci_init((void *)ATMEL_BASE_MCI);
}
-int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+int board_mmc_getcd(struct mmc *mmc)
{
- *cd = at91_get_pio_value(CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
- return 0;
+ return !at91_get_pio_value(CONFIG_SYS_MMC_CD_PIN);
}
#endif
#include <net.h>
#include <netdev.h>
#include <mmc.h>
+#include <atmel_mci.h>
#include <i2c.h>
#include <spi.h>
#include <asm/io.h>
/*
* write RTC kick register to enable write
- * for RTC Scratch registers. Cratch0 and 1 are
+ * for RTC Scratch registers. Scratch0 and 1 are
* used for bootcount values.
*/
writel(RTC_KICK0R_WE, ®->kick0r);
* Call run_cmd
*/
printf("running command at addr 0x%s ...\n", addr);
- run_command((char*)la, 0);
+ run_command((char *)la, 0);
break;
default:
pldver, 1, 1, do_pldver,
"Show PLD version",
"Show PLD version)");
+
+int board_eth_init(bd_t *bis)
+{
+ return mv6436x_eth_initialize(bis);
+}
void db64360_eth0_disable(void);
bool network_start(bd_t *bis);
+int mv6436x_eth_initialize(bd_t *);
#endif /* __EVB64360_ETH_H__ */
#include <pci.h>
extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
+int cpci_hd_type;
+
+int ata_device(int dev)
+{
+ int retval;
+
+ retval = (dev & 1) << 4;
+ if (cpci_hd_type == 2)
+ retval ^= 1 << 4;
+ return retval;
+}
+
int ide_preinit (void)
{
int l;
status = 1;
+ cpci_hd_type = 0;
if (CPCI750_SLAVE_TEST != 0)
return status;
for (l = 0; l < CONFIG_SYS_IDE_MAXBUS; l++) {
ide_bus_offset[l] = -ATA_STATUS;
}
devbusfn = pci_find_device (0x1103, 0x0004, 0);
- if (devbusfn == -1)
+ if (devbusfn != -1) {
+ cpci_hd_type = 1;
+ } else {
devbusfn = pci_find_device (0x1095, 0x3114, 0);
+ if (devbusfn != -1) {
+ cpci_hd_type = 2;
+ }
+ }
if (devbusfn != -1) {
ulong *ide_bus_offset_ptr;
return;
}
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf (dev->name, "mv_enet%d", devnum);
#ifdef DEBUG
#ifdef CONFIG_PCI
#include <pci.h>
-#ifdef CONFIG_PCI_PNP
-void pciauto_config_init(struct pci_controller *hose);
-int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
-#endif
-
#include "../../Marvell/include/pci.h"
#undef DEBUG
*d = '\0';
start = get_ticks();
- ret = run_command (cmd, 0);
+ ret = run_command(cmd, 0);
end = get_ticks();
printf("ticks=%ld\n", (ulong)(end - start));
writel(csa, &matrix->csa[0]);
/* Configure SMC CS3 for NAND/SmartMedia */
- writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(0) |
- AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(0),
+ writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
+ AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(2),
&smc->cs[3].setup);
writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) |
AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3),
&smc->cs[3].pulse);
- writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
+ writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6),
&smc->cs[3].cycle);
writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
AT91_SMC_MODE_EXNW_DISABLE |
AT91_SMC_MODE_DBW_8 |
- AT91_SMC_MODE_TDF_CYCLE(3),
+ AT91_SMC_MODE_TDF_CYCLE(12),
&smc->cs[3].mode);
/* Configure RDY/BSY */
writel(csa, &matrix->csa[0]);
/* Configure SMC CS3 for NAND/SmartMedia */
- writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(0) |
- AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(0),
+ writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(1) |
+ AT91_SMC_SETUP_NRD(2) | AT91_SMC_SETUP_NCS_RD(2),
&smc->cs[3].setup);
writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) |
AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3),
&smc->cs[3].pulse);
- writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
+ writel(AT91_SMC_CYCLE_NWE(6) | AT91_SMC_CYCLE_NRD(6),
&smc->cs[3].cycle);
writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
AT91_SMC_MODE_EXNW_DISABLE |
AT91_SMC_MODE_DBW_8 |
- AT91_SMC_MODE_TDF_CYCLE(3),
+ AT91_SMC_MODE_TDF_CYCLE(12),
&smc->cs[3].mode);
/* Configure RDY/BSY */
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
net/libnet.o (.text*)
arch/powerpc/cpu/mpc8xx/libmpc8xx.o (.text*)
- *(.text.printf)
*(.text.vsprintf)
. = env_offset;
return;
}
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf(dev->name, "gal_enet%d", devnum);
#ifdef DEBUG
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
int board_phy_config(struct phy_device *phydev)
{
+ if (phydev->drv->config)
+ phydev->drv->config(phydev);
if (phydev->drv->uid == PHY_UID_TN2020) {
unsigned long timeout = 1 * 1000; /* 1 seconds */
enum srds_prtcl device;
uint phyid;
struct mii_dev *bus = phydev->bus;
+ if (phydev->drv->config)
+ phydev->drv->config(phydev);
if (do_once)
return 0;
#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
#define MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL)
+#define MUX_CONFIG_SSP2 (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
const iomux_cfg_t iomux_setup[] = {
/* DUART */
MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI,
MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI,
MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI,
+
+ /* SPI2 (for SPI flash) */
+ MX28_PAD_SSP2_SCK__SSP2_SCK | MUX_CONFIG_SSP2,
+ MX28_PAD_SSP2_MOSI__SSP2_CMD | MUX_CONFIG_SSP2,
+ MX28_PAD_SSP2_MISO__SSP2_D0 | MUX_CONFIG_SSP2,
+ MX28_PAD_SSP2_SS0__SSP2_D3 |
+ (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP),
};
void board_init_ll(void)
/* SSP2 clock at 96MHz */
mx28_set_sspclk(MXC_SSPCLK2, 96000, 0);
+#ifdef CONFIG_CMD_USB
+ mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
+ mxs_iomux_setup_pad(MX28_PAD_AUART2_RX__GPIO_3_8 |
+ MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL);
+ gpio_direction_output(MX28_PAD_AUART2_RX__GPIO_3_8, 1);
+#endif
+
return 0;
}
int checkboard(void)
{
- struct ccm_regs *ccm =
- (struct ccm_regs *)IMX_CCM_BASE;
- u32 cpu_rev = get_cpu_rev();
-
/*
* Be sure that I2C is initialized to check
* the board revision
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
/* Print board revision */
- printf("Board: MX35 PDK %d.0 ", ((get_board_rev() >> 8) + 1) & 0x0F);
-
- /* Print CPU revision */
- printf("i.MX35 %d.%d [", (cpu_rev & 0xF0) >> 4, cpu_rev & 0x0F);
-
- switch (readl(&ccm->rcsr) & 0x0F) {
- case 0x0000:
- puts("POR");
- break;
- case 0x0002:
- puts("JTAG");
- break;
- case 0x0004:
- puts("RST");
- break;
- case 0x0008:
- puts("WDT");
- break;
- default:
- puts("unknown");
- }
- puts("]\n");
+ printf("Board: MX35 PDK %d.0\n", ((get_board_rev() >> 8) + 1) & 0x0F);
return 0;
}
int ret;
mxc_request_iomux(MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(0);
mxc_request_iomux(MX51_PIN_GPIO1_6, IOMUX_CONFIG_ALT0);
+ gpio_direction_input(6);
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
ret = !gpio_get_value(0);
int ret;
mxc_request_iomux(MX53_PIN_GPIO_1, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(1);
mxc_request_iomux(MX53_PIN_GPIO_4, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(4);
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
ret = !gpio_get_value(1); /* GPIO1_1 */
int board_eth_init(bd_t *bis)
{
- int rc = 0;
+ int rc = -ENODEV;
weim_smc911x_iomux();
weim_cs1_settings();
int ret;
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(75);
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(77);
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
ret = !gpio_get_value(77); /* GPIO3_13 */
int ret;
mxc_request_iomux(MX53_PIN_EIM_DA11, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(75);
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(77);
if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
ret = !gpio_get_value(77); /* GPIO3_13 */
int board_mmc_getcd(struct mmc *mmc)
{
mxc_request_iomux(MX53_PIN_EIM_DA13, IOMUX_CONFIG_ALT1);
+ gpio_direction_input(77);
return !gpio_get_value(77); /* GPIO3_13 */
}
# set the default clock gate to save power
DATA 4 0x020c4068 0x00C03F3F
-DATA 4 0x020c406c 0x0030FC00
+DATA 4 0x020c406c 0x0030FC03
DATA 4 0x020c4070 0x0FFFC000
DATA 4 0x020c4074 0x3FF00000
DATA 4 0x020c4078 0x00FFF300
#include <asm/gpio.h>
#include <mmc.h>
#include <fsl_esdhc.h>
+#include <micrel.h>
#include <miiphy.h>
#include <netdev.h>
-
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+#define SPI_PAD_CTRL (PAD_CTL_HYS | \
+ PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
+
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
}
+iomux_v3_cfg_t usb_pads[] = {
+ MX6Q_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
static void setup_iomux_uart(void)
{
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
}
+#ifdef CONFIG_USB_EHCI_MX6
+int board_ehci_hcd_init(int port)
+{
+ imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+
+ /* Reset USB hub */
+ gpio_direction_output(GPIO_NUMBER(7, 12), 0);
+ mdelay(2);
+ gpio_set_value(GPIO_NUMBER(7, 12), 1);
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_FSL_ESDHC
struct fsl_esdhc_cfg usdhc_cfg[2] = {
{USDHC3_BASE_ADDR, 1},
}
#endif
-#define MII_1000BASET_CTRL 0x9
-#define MII_EXTENDED_CTRL 0xb
-#define MII_EXTENDED_DATAW 0xc
-
-int fecmxc_mii_postcall(int phy)
+u32 get_board_rev(void)
{
- /* prefer master mode */
- miiphy_write("FEC", phy, MII_1000BASET_CTRL, 0x0f00);
+ return 0x63000 ;
+}
- /* min rx data delay */
- miiphy_write("FEC", phy, MII_EXTENDED_CTRL, 0x8105);
- miiphy_write("FEC", phy, MII_EXTENDED_DATAW, 0x0000);
+#ifdef CONFIG_MXC_SPI
+iomux_v3_cfg_t ecspi1_pads[] = {
+ /* SS1 */
+ MX6Q_PAD_EIM_D19__GPIO_3_19 | MUX_PAD_CTRL(SPI_PAD_CTRL),
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
+};
- /* max rx/tx clock delay, min rx/tx control delay */
- miiphy_write("FEC", phy, MII_EXTENDED_CTRL, 0x8104);
- miiphy_write("FEC", phy, MII_EXTENDED_DATAW, 0xf0f0);
- miiphy_write("FEC", phy, MII_EXTENDED_CTRL, 0x104);
+void setup_spi(void)
+{
+ gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
+ imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
+ ARRAY_SIZE(ecspi1_pads));
+}
+#endif
+int board_phy_config(struct phy_device *phydev)
+{
+ /* min rx data delay */
+ ksz9021_phy_extended_write(phydev,
+ MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
+ /* min tx data delay */
+ ksz9021_phy_extended_write(phydev,
+ MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
+ /* max rx/tx clock delay, min rx/tx control */
+ ksz9021_phy_extended_write(phydev,
+ MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
+ if (phydev->drv->config)
+ phydev->drv->config(phydev);
+
return 0;
}
int board_eth_init(bd_t *bis)
{
- struct eth_device *dev;
int ret;
setup_iomux_enet();
ret = cpu_eth_init(bis);
- if (ret) {
+ if (ret)
printf("FEC MXC: %s:failed\n", __func__);
- return ret;
- }
-
- dev = eth_get_dev_by_name("FEC");
- if (!dev) {
- printf("FEC MXC: Unable to get FEC device entry\n");
- return -EINVAL;
- }
-
- ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
- if (ret) {
- printf("FEC MXC: Unable to register FEC mii postcall\n");
- return ret;
- }
return 0;
}
/* address of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+#ifdef CONFIG_MXC_SPI
+ setup_spi();
+#endif
+
return 0;
}
#endif
return rc;
}
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+void video_get_info_str(int line_number, char *info)
+{
+ u32 srev = get_cpu_rev();
+
+ switch (line_number) {
+ case 2:
+ sprintf(info, " CPU : Freescale i.MX31 rev %d.%d%s at %d MHz",
+ (srev & 0xF0) >> 4, (srev & 0x0F),
+ ((srev & 0x8000) ? " unknown" : ""),
+ mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ break;
+ case 3:
+ strcpy(info, " " BOARD_STRING);
+ break;
+ default:
+ info[0] = 0;
+ }
+}
+#endif
#ifdef CONFIG_SHOW_BOOT_PROGRESS
# include <status_led.h>
-# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+# define SHOW_BOOT_PROGRESS(arg) bootstage_mark(arg)
#else
# define SHOW_BOOT_PROGRESS(arg)
#endif
immr->im_ioport.iop_pcdat |= PC_REP_RES;
}
}
- SHOW_BOOT_PROGRESS (0x00);
+ SHOW_BOOT_PROGRESS(BOOTSTAGE_ID_CHECK_MAGIC);
return ((revision << 16) | (speed & 0xFFFF));
}
{
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
- if (status < -32) status = -1; /* let things compatible */
+ /* let things compatible */
+ if (status < -BOOTSTAGE_ID_POST_FAIL_R)
+ status = -1;
status ^= 0x0F;
status = (status & 0x0F) << 14;
immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & ~PB_LED_ALL) | status;
#include <common.h>
#include <ahci.h>
+#include <netdev.h>
#include <scsi.h>
#include <asm/sizes.h>
+#include <asm/io.h>
+
+#define HB_SREG_A9_PWR_REQ 0xfff3cf00
+#define HB_SREG_A9_BOOT_SRC_STAT 0xfff3cf04
+#define HB_PWR_SUSPEND 0
+#define HB_PWR_SOFT_RESET 1
+#define HB_PWR_HARD_RESET 2
+#define HB_PWR_SHUTDOWN 3
DECLARE_GLOBAL_DATA_PTR;
int misc_init_r(void)
{
+ char envbuffer[16];
+ u32 boot_choice;
+
ahci_init(0xffe08000);
scsi_scan(1);
+
+ boot_choice = readl(HB_SREG_A9_BOOT_SRC_STAT) & 0xff;
+ sprintf(envbuffer, "bootcmd%d", boot_choice);
+ if (getenv(envbuffer)) {
+ sprintf(envbuffer, "run bootcmd%d", boot_choice);
+ setenv("bootcmd", envbuffer);
+ } else
+ setenv("bootcmd", "");
+
return 0;
}
void reset_cpu(ulong addr)
{
+ writel(HB_PWR_HARD_RESET, HB_SREG_A9_PWR_REQ);
+ asm(" wfi");
}
(status < 0) ? STATUS_LED_ON : STATUS_LED_OFF);
# endif /* STATUS_LED_YELLOW */
# if defined(STATUS_LED_BOOT)
- if (status == 6)
+ if (status == BOOTSTAGE_ID_DECOMP_IMAGE)
status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF);
# endif /* STATUS_LED_BOOT */
#endif /* CONFIG_STATUS_LED */
result = fpga_load(0, fpga_data, data_size);
if (!result)
- show_boot_progress(0);
+ bootstage_mark(BOOTSTAGE_ID_START);
return result;
}
struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO;
switch(val) {
- case 0: /* FPGA ok */
+ case BOOTSTAGE_ID_START: /* FPGA ok */
setbits_be32(&gpio->simple_dvo, LED_G0);
break;
- case 65:
+ case BOOTSTAGE_ID_NET_ETH_INIT:
setbits_be32(&gpio->simple_dvo, LED_G1);
break;
- case 12:
+ case BOOTSTAGE_ID_COPY_RAMDISK:
setbits_be32(&gpio->simple_dvo, LED_Y);
break;
- case 15:
+ case BOOTSTAGE_ID_RUN_OS:
setbits_be32(&gpio->simple_dvo, LED_R);
break;
default:
*/
debug ("flash_sect_erase(%lx, %lx);\n", start, end);
flash_sect_erase(start, end);
- wait_ms(100);
+ mdelay(100);
#ifdef CONFIG_PROGRESSBAR
show_progress(end - start, totsize);
#endif
* Read keypad status
*/
i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status1, 2);
- wait_ms(500);
+ mdelay(500);
i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status2, 2);
/*
out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
/* Turn off all interrupts */
out16r(usb_base_addr + USBINTR,0);
- wait_ms(50);
+ mdelay(50);
out16r( usb_base_addr + USBCMD,0);
- wait_ms(10);
+ mdelay(10);
}
void start_hc(void)
status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
status = (status & 0xfff5) | USBPORTSC_PR;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
- wait_ms(10);
+ mdelay(10);
status = (status & 0xfff5) & ~USBPORTSC_PR;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
udelay(10);
status = (status & 0xfff5) | USBPORTSC_PE;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
- wait_ms(10);
+ mdelay(10);
status = (status & 0xfff5) | 0xa;
out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
len=0;
#include <asm/arch/pinmux.h>
#include <asm/arch/uart.h>
#include <spi.h>
+#include <asm/arch/usb.h>
+#include <i2c.h>
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
return 0;
}
+void __pin_mux_usb(void)
+{
+}
+
+void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb")));
+
/*
* Routine: board_init
* Description: Early hardware init.
#endif
/* boot param addr */
gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
+#ifdef CONFIG_TEGRA_I2C
+#ifndef CONFIG_SYS_I2C_INIT_BOARD
+#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
+#endif
+ i2c_init_board();
+#endif
+
+#ifdef CONFIG_USB_EHCI_TEGRA
+ pin_mux_usb();
+ board_usb_init(gd->fdt_blob);
+#endif
return 0;
}
void gpio_config_uart(void);
void gpio_early_init_uart(void);
+/*
+ * Set up any pin muxing needed for USB (for now, since fdt doesn't support
+ * it). Boards can overwrite the default fucction which does nothing.
+ */
+void pin_mux_usb(void);
+
#endif /* BOARD_H */
--- /dev/null
+/dts-v1/;
+
+/memreserve/ 0x1c000000 0x04000000;
+/include/ ARCH_CPU_DTS
+
+/ {
+ model = "NVIDIA Seaboard";
+ compatible = "nvidia,seaboard", "nvidia,tegra20";
+
+ chosen {
+ bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait";
+ };
+
+ aliases {
+ /* This defines the order of our USB ports */
+ usb0 = "/usb@c5008000";
+ usb1 = "/usb@c5000000";
+
+ i2c0 = "/i2c@7000d000";
+ i2c1 = "/i2c@7000c000";
+ i2c2 = "/i2c@7000c400";
+ i2c3 = "/i2c@7000c500";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = < 0x00000000 0x40000000 >;
+ };
+
+ /* This is not used in U-Boot, but is expected to be in kernel .dts */
+ i2c@7000d000 {
+ clock-frequency = <100000>;
+ pmic@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+
+ clk_32k: clock {
+ compatible = "fixed-clock";
+ /*
+ * leave out for now due to CPP:
+ * #clock-cells = <0>;
+ */
+ clock-frequency = <32768>;
+ };
+ };
+ };
+
+ clocks {
+ osc {
+ clock-frequency = <12000000>;
+ };
+ };
+
+ clock@60006000 {
+ clocks = <&clk_32k &osc>;
+ };
+
+ serial@70006300 {
+ clock-frequency = < 216000000 >;
+ };
+
+ sdhci@c8000400 {
+ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+ power-gpios = <&gpio 70 0>; /* gpio PI6 */
+ };
+
+ sdhci@c8000600 {
+ support-8bit;
+ };
+
+ usb@c5000000 {
+ nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+ dr_mode = "otg";
+ };
+
+ usb@c5004000 {
+ status = "disabled";
+ };
+
+ i2c@7000c000 {
+ clock-frequency = <100000>;
+ };
+
+ i2c@7000c400 {
+ status = "disabled";
+ };
+
+ i2c@7000c500 {
+ clock-frequency = <100000>;
+ };
+};
return 0;
}
#endif
+
+void pin_mux_usb(void)
+{
+ /* For USB's GPIO PD0. For now, since we have no pinmux in fdt */
+ pinmux_tristate_disable(PINGRP_SLXK);
+}
/*
* write RTC kick register to enable write
- * for RTC Scratch registers. Cratch0 and 1 are
+ * for RTC Scratch registers. Scratch0 and 1 are
* used for bootcount values.
*/
writel(RTC_KICK0R_WE, ®->kick0r);
void show_boot_progress (int val)
{
/* find all valid Codes for val in README */
- if (val == -30) return;
+ if (val == -BOOTSTAGE_ID_NEED_RESET)
+ return;
if (val < 0) {
/* smthing goes wrong */
status_led_blink ();
return;
}
switch (val) {
- case 1:
- /* validating Image */
- status_led_set (0, STATUS_LED_OFF);
- status_led_set (1, STATUS_LED_ON);
- status_led_set (2, STATUS_LED_ON);
- break;
- case 15:
- /* booting */
- status_led_set (0, STATUS_LED_ON);
- status_led_set (1, STATUS_LED_ON);
- status_led_set (2, STATUS_LED_ON);
- break;
+ case BOOTSTAGE_ID_CHECK_MAGIC:
+ /* validating Image */
+ status_led_set(0, STATUS_LED_OFF);
+ status_led_set(1, STATUS_LED_ON);
+ status_led_set(2, STATUS_LED_ON);
+ break;
+ case BOOTSTAGE_ID_RUN_OS:
+ status_led_set(0, STATUS_LED_ON);
+ status_led_set(1, STATUS_LED_ON);
+ status_led_set(2, STATUS_LED_ON);
+ break;
#if 0
- case 64:
- /* starting Ethernet configuration */
- status_led_set (0, STATUS_LED_OFF);
- status_led_set (1, STATUS_LED_OFF);
- status_led_set (2, STATUS_LED_ON);
- break;
+ case BOOTSTAGE_ID_NET_ETH_START:
+ /* starting Ethernet configuration */
+ status_led_set(0, STATUS_LED_OFF);
+ status_led_set(1, STATUS_LED_OFF);
+ status_led_set(2, STATUS_LED_ON);
+ break;
#endif
- case 80:
- /* loading Image */
- status_led_set (0, STATUS_LED_ON);
- status_led_set (1, STATUS_LED_OFF);
- status_led_set (2, STATUS_LED_ON);
- break;
+ case BOOTSTAGE_ID_NET_START:
+ /* loading Image */
+ status_led_set(0, STATUS_LED_ON);
+ status_led_set(1, STATUS_LED_OFF);
+ status_led_set(2, STATUS_LED_ON);
+ break;
}
}
#endif
void db64360_eth0_disable(void);
bool network_start(bd_t *bis);
+int mv6446x_eth_initialize(bd_t *);
#endif /* __EVB64360_ETH_H__ */
return;
}
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf (dev->name, "mv_enet%d", devnum);
#ifdef DEBUG
!= temp);
}
+
+int board_eth_init(bd_t *bis)
+{
+ return mv6446x_eth_initialize(bis);
+}
#ifdef CONFIG_PCI
#include <pci.h>
-#ifdef CONFIG_PCI_PNP
-void pciauto_config_init(struct pci_controller *hose);
-int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
-#endif
-
#include "../../Marvell/include/pci.h"
#undef DEBUG
{
int i;
- if (len % 4) {
- for (i = 0; i < len; i++)
- buf[i] = readb(&(pdnb3_ndfc->data));
- } else {
- ulong *ptr = (ulong *)buf;
- int count = len >> 2;
-
- for (i = 0; i < count; i++)
- *ptr++ = readl(&(pdnb3_ndfc->data));
- }
+ for (i = 0; i < len; i++)
+ buf[i] = readb(&(pdnb3_ndfc->data));
}
static int pdnb3_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
static int pdnb3_nand_dev_ready(struct mtd_info *mtd)
{
- volatile u_char val;
-
/*
* Blocking read to wait for NAND to be ready
*/
- val = readb(&(pdnb3_ndfc->wait));
+ readb(&(pdnb3_ndfc->wait));
/*
* Return always true
*/
int board_init(void)
{
- /* arch number of PDNB3 */
- gd->bd->bi_arch_number = MACH_TYPE_PDNB3;
-
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x00000100;
COBJS := ecovec.o
SOBJS := lowlevel_init.o
-$(LIB): $(obj).depend $(COBJS) $(SOBJS)
- $(call cmd_link_o_target, $(COBJS) $(SOBJS))
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
#########################################################################
{
u8 mac[6];
char env_mac[17];
- int i;
udelay(1000);
#include <malloc.h>
#include <asm/processor.h>
#include <asm/io.h>
+#include <asm/mmc.h>
#include <spi_flash.h>
int checkboard(void)
return 0;
}
+int board_mmc_init(bd_t *bis)
+{
+ return mmcif_mmc_init();
+}
+
static int get_sh_eth_mac_raw(unsigned char *buf, int size)
{
struct spi_flash *spi;
#define SM107_DEVICEID (0x13e00060 + NOCACHE_OFFSET)
-static void wait_ms(unsigned long time)
-{
- while (time--)
- udelay(1000);
-}
-
static void test_pld(void)
{
printf("PLD version = %04x\n", readb(PLD_VERSR));
{
printf("turn on LEDs 3, 5, 7, 9\n");
writeb(0x55, PLD_LEDCR);
- wait_ms(2000);
+ mdelay(2000);
printf("turn on LEDs 4, 6, 8, 10\n");
writeb(0xaa, PLD_LEDCR);
- wait_ms(2000);
+ mdelay(2000);
writeb(0x00, PLD_LEDCR);
}
(struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
int i;
- /* UART1 GPIOs (part1) : GPA0CON[7:4] 0x2222 */
- for (i = 4; i < 8; i++) {
+ /*
+ * UART0 GPIOs : GPA0CON[3:0] 0x2222
+ * Must set CFG17 switches to select UART0 to use.
+ */
+ for (i = 0; i <= 3; i++) {
s5p_gpio_set_pull(&gpio1->a0, i, GPIO_PULL_NONE);
s5p_gpio_cfg_pin(&gpio1->a0, i, GPIO_FUNC(0x2));
}
+
+ /*
+ * UART1 GPIOs : GPA0CON[5:4] 0x22
+ * Must set CFG17 switches to select UART1 to use.
+ *
+ * This only sets RXD/TXD, as RTS/CTS need a resistor soldered down
+ * in order to use them (so that those pins can be used for I2C).
+ */
+ for (i = 4; i <= 5; i++) {
+ s5p_gpio_set_pull(&gpio1->a0, i, GPIO_PULL_NONE);
+ s5p_gpio_cfg_pin(&gpio1->a0, i, GPIO_FUNC(0x2));
+ }
+
+ /*
+ * UART2 GPIOs : GPA1CON[1:0] 0x22
+ * Must set CFG17 switches to select UART2 to use.
+ *
+ * This only sets RXD/TXD, as RTS/CTS need a resistor soldered down
+ * in order to use them (so that those pins can be used for I2C).
+ */
+ for (i = 0; i <= 1; i++) {
+ s5p_gpio_set_pull(&gpio1->a1, i, GPIO_PULL_NONE);
+ s5p_gpio_cfg_pin(&gpio1->a1, i, GPIO_FUNC(0x2));
+ }
+
+ /*
+ * UART3 GPIOs : GPA1CON[5:4] 0x22
+ * Must set CFG16 switches to select UART3 to use.
+ */
+ for (i = 4; i <= 5; i++) {
+ s5p_gpio_set_pull(&gpio1->a1, i, GPIO_PULL_NONE);
+ s5p_gpio_cfg_pin(&gpio1->a1, i, GPIO_FUNC(0x2));
+ }
+
+ /*
+ * There's no mux for UART4--it's internal only
+ */
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
{
}
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}
+
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
ulong get_timer(ulong base)
{
return (os_get_nsec() / 1000000) - base;
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
-#else
-# define SHOW_BOOT_PROGRESS(arg)
-#endif
-
int board_init (void)
{
gd->bd->bi_arch_number = MACH_TYPE_SCB9328;
{
#if defined(CONFIG_STATUS_LED)
# if defined(STATUS_LED_BOOT)
- if (status == 15) {
+ if (status == BOOTSTAGE_ID_RUN_OS) {
/* ready to transfer to kernel, make sure LED is proper state */
status_led_set(STATUS_LED_BOOT, CONFIG_BOOT_LED_STATE);
}
return omap_mmc_init(0);
}
#endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Do board specific preperation before SPL
+ * Linux boot
+ */
+void spl_board_prepare_for_linux(void)
+{
+ /* init cs for extern lan */
+ enable_gpmc_cs_config(gpmc_smc911, &gpmc_cfg->cs[5],
+ CONFIG_SMC911X_BASE, GPMC_SIZE_16M);
+}
+int spl_start_uboot(void)
+{
+ int val = 0;
+ if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) {
+ gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY);
+ val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY);
+ gpio_free(CONFIG_SPL_OS_BOOT_KEY);
+ }
+ return val;
+}
+#endif
/* FPGA CS1 configuration */
#define FPGA_GPMC_CONFIG1 0x00001200
-#define FPGA_GPMC_CONFIG2 0x00111a00
-#define FPGA_GPMC_CONFIG3 0x00010100
-#define FPGA_GPMC_CONFIG4 0x06041a04
-#define FPGA_GPMC_CONFIG5 0x0019101a
-#define FPGA_GPMC_CONFIG6 0x890503c0
-#define FPGA_GPMC_CONFIG7 0x00000860
+#define FPGA_GPMC_CONFIG2 0x00161f00
+#define FPGA_GPMC_CONFIG3 0x00040400
+#define FPGA_GPMC_CONFIG4 0x120c1f08
+#define FPGA_GPMC_CONFIG5 0x001e161f
+#define FPGA_GPMC_CONFIG6 0x96080fcf
#define FPGA_BASE_ADDR 0x20000000
}
}
+/*
+ * Enable DVI power
+ */
+static void beagle_dvi_pup(void)
+{
+ uchar val;
+
+ switch (get_board_revision()) {
+ case REVISION_AXBX:
+ case REVISION_CX:
+ case REVISION_C4:
+ case REVISION_XM_A:
+ gpio_request(170, "");
+ gpio_direction_output(170, 0);
+ gpio_set_value(170, 1);
+ break;
+ case REVISION_XM_B:
+ case REVISION_XM_C:
+ default:
+ #define GPIODATADIR1 (TWL4030_BASEADD_GPIO+3)
+ #define GPIODATAOUT1 (TWL4030_BASEADD_GPIO+6)
+
+ i2c_read(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1);
+ val |= 4;
+ i2c_write(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1);
+
+ i2c_read(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1);
+ val |= 4;
+ i2c_write(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1);
+ break;
+ }
+}
+
/*
* Routine: misc_init_r
* Description: Configure board specific parts
GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe);
dieid_num_r();
+
+ beagle_dvi_pup();
beagle_display_init();
omap3_dss_enable();
/* Call usb_stop() before starting the kernel */
void show_boot_progress(int val)
{
- if(val == 15)
+ if (val == BOOTSTAGE_ID_RUN_OS)
usb_stop();
}
+++ /dev/null
-#
-# (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.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
-#
-
-include $(TOPDIR)/config.mk
-
-LIB = $(obj)lib$(BOARD).o
-
-COBJS := omap1610innovator.o flash.o
-SOBJS := lowlevel_init.o
-
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
-
-$(LIB): $(obj).depend $(OBJS) $(SOBJS)
- $(call cmd_link_o_target, $(OBJS) $(SOBJS))
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
+++ /dev/null
-#
-# (C) Copyright 2002
-# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
-# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
-#
-# (C) Copyright 2003
-# Texas Instruments, <www.ti.com>
-# Kshitij Gupta <Kshitij@ti.com>
-#
-# TI Innovator board with OMAP1610 (ARM925EJS) cpu
-# see http://www.ti.com/ for more information on Texas Instruments
-#
-# Innovator has 1 bank of 256 MB SDRAM
-# Physical Address:
-# 1000'0000 to 2000'0000
-#
-#
-# Linux-Kernel is expected to be at 1000'8000, entry 1000'8000
-# (mem base + reserved)
-#
-# we load ourself to 1108'0000
-#
-#
-
-
-CONFIG_SYS_TEXT_BASE = 0x11080000
+++ /dev/null
-/*
- * (C) Copyright 2001
- * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
- *
- * (C) Copyright 2001-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2003
- * Texas Instruments, <www.ti.com>
- * Kshitij Gupta <Kshitij@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 <common.h>
-#include <linux/byteorder/swab.h>
-
-#define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
-flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
-
-/* Board support for 1 or 2 flash devices */
-#undef FLASH_PORT_WIDTH32
-#define FLASH_PORT_WIDTH16
-
-#ifdef FLASH_PORT_WIDTH16
-#define FLASH_PORT_WIDTH ushort
-#define FLASH_PORT_WIDTHV vu_short
-#define SWAP(x) __swab16(x)
-#else
-#define FLASH_PORT_WIDTH ulong
-#define FLASH_PORT_WIDTHV vu_long
-#define SWAP(x) __swab32(x)
-#endif
-
-#define FPW FLASH_PORT_WIDTH
-#define FPWV FLASH_PORT_WIDTHV
-
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-
-
-/* Flash Organization Structure */
-typedef struct OrgDef {
- unsigned int sector_number;
- unsigned int sector_size;
-} OrgDef;
-
-
-/* Flash Organizations */
-OrgDef OrgIntel_28F256L18T[] = {
- {4, 32 * 1024}, /* 4 * 32kBytes sectors */
- {255, 128 * 1024}, /* 255 * 128kBytes sectors */
-};
-
-
-/*-----------------------------------------------------------------------
- * Functions
- */
-unsigned long flash_init (void);
-static ulong flash_get_size (FPW * addr, flash_info_t * info);
-static int write_data (flash_info_t * info, ulong dest, FPW data);
-static void flash_get_offsets (ulong base, flash_info_t * info);
-void inline spin_wheel (void);
-void flash_print_info (flash_info_t * info);
-void flash_unprotect_sectors (FPWV * addr);
-int flash_erase (flash_info_t * info, int s_first, int s_last);
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
-void flash_unlock(flash_info_t * info);
-
-/*-----------------------------------------------------------------------
- */
-
-unsigned long flash_init (void)
-{
- int i;
- ulong size = 0;
-
- for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
- switch (i) {
- case 0:
- flash_get_size ((FPW *) CONFIG_SYS_FLASH_BASE, &flash_info[i]);
- flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[i]);
- /* to reset the lock bit */
- flash_unlock(&flash_info[i]);
- break;
- default:
- panic ("configured too many flash banks!\n");
- break;
- }
- size += flash_info[i].size;
- }
-
- /* Protect monitor and environment sectors
- */
- flash_protect (FLAG_PROTECT_SET,
- CONFIG_SYS_FLASH_BASE,
- CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
-
- flash_protect (FLAG_PROTECT_SET,
- CONFIG_ENV_ADDR,
- CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
-
- return size;
-}
-
-/*-----------------------------------------------------------------------
- */
-void flash_unlock(flash_info_t * info)
-{
- int j;
- for (j=2;j<CONFIG_SYS_MAX_FLASH_SECT;j++){
- FPWV *addr = (FPWV *) (info->start[j]);
- flash_unprotect_sectors (addr);
- *addr = (FPW) 0x00500050;/* clear status register */
- *addr = (FPW) 0x00FF00FF;/* resest to read mode */
- }
-}
-
-/*-----------------------------------------------------------------------
- */
-static void flash_get_offsets (ulong base, flash_info_t * info)
-{
- int i;
-
- if (info->flash_id == FLASH_UNKNOWN) {
- return;
- }
-
- if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
- for (i = 0; i < info->sector_count; i++) {
- if (i > 255) {
- info->start[i] = base + (i * 0x8000);
- info->protect[i] = 0;
- } else {
- info->start[i] = base +
- (i * PHYS_FLASH_SECT_SIZE);
- info->protect[i] = 0;
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------------
- */
-void flash_print_info (flash_info_t * info)
-{
- int i;
-
- if (info->flash_id == FLASH_UNKNOWN) {
- printf ("missing or unknown FLASH type\n");
- return;
- }
-
- switch (info->flash_id & FLASH_VENDMASK) {
- case FLASH_MAN_INTEL:
- printf ("INTEL ");
- break;
- default:
- printf ("Unknown Vendor ");
- break;
- }
-
- switch (info->flash_id & FLASH_TYPEMASK) {
- case FLASH_28F256L18T:
- printf ("FLASH 28F256L18T\n");
- break;
- default:
- printf ("Unknown Chip Type\n");
- break;
- }
-
- printf (" Size: %ld MB in %d Sectors\n",
- info->size >> 20, info->sector_count);
-
- printf (" Sector Start Addresses:");
- for (i = 0; i < info->sector_count; ++i) {
- if ((i % 5) == 0)
- printf ("\n ");
- printf (" %08lX%s",
- info->start[i], info->protect[i] ? " (RO)" : " ");
- }
- printf ("\n");
- return;
-}
-
-/*
- * The following code cannot be run from FLASH!
- */
-static ulong flash_get_size (FPW * addr, flash_info_t * info)
-{
- volatile FPW value;
-
- /* Write auto select command: read Manufacturer ID */
- addr[0x5555] = (FPW) 0x00AA00AA;
- addr[0x2AAA] = (FPW) 0x00550055;
- addr[0x5555] = (FPW) 0x00900090;
-
- mb ();
- value = addr[0];
-
- switch (value) {
-
- case (FPW) INTEL_MANUFACT:
- info->flash_id = FLASH_MAN_INTEL;
- break;
-
- default:
- info->flash_id = FLASH_UNKNOWN;
- info->sector_count = 0;
- info->size = 0;
- addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
- return (0); /* no or unknown flash */
- }
-
- mb ();
- value = addr[1]; /* device ID */
- switch (value) {
-
- case (FPW) (INTEL_ID_28F256L18T):
- info->flash_id += FLASH_28F256L18T;
- info->sector_count = 259;
- info->size = 0x02000000;
- break; /* => 32 MB */
-
- default:
- info->flash_id = FLASH_UNKNOWN;
- break;
- }
-
- if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
- printf ("** ERROR: sector count %d > max (%d) **\n",
- info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
- info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
- }
-
- addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
-
- return (info->size);
-}
-
-
-/* unprotects a sector for write and erase
- * on some intel parts, this unprotects the entire chip, but it
- * wont hurt to call this additional times per sector...
- */
-void flash_unprotect_sectors (FPWV * addr)
-{
-#define PD_FINTEL_WSMS_READY_MASK 0x0080
-
- *addr = (FPW) 0x00500050; /* clear status register */
-
- /* this sends the clear lock bit command */
- *addr = (FPW) 0x00600060;
- *addr = (FPW) 0x00D000D0;
-}
-
-
-/*-----------------------------------------------------------------------
- */
-
-int flash_erase (flash_info_t * info, int s_first, int s_last)
-{
- int flag, prot, sect;
- ulong type, start;
- int rcode = 0;
-
- if ((s_first < 0) || (s_first > s_last)) {
- if (info->flash_id == FLASH_UNKNOWN) {
- printf ("- missing\n");
- } else {
- printf ("- no sectors to erase\n");
- }
- return 1;
- }
-
- type = (info->flash_id & FLASH_VENDMASK);
- if ((type != FLASH_MAN_INTEL)) {
- printf ("Can't erase unknown flash type %08lx - aborted\n",
- info->flash_id);
- return 1;
- }
-
- prot = 0;
- for (sect = s_first; sect <= s_last; ++sect) {
- if (info->protect[sect]) {
- prot++;
- }
- }
-
- if (prot) {
- printf ("- Warning: %d protected sectors will not be erased!\n",
- prot);
- } else {
- printf ("\n");
- }
-
- /* Disable interrupts which might cause a timeout here */
- flag = disable_interrupts ();
-
- /* Start erase on unprotected sectors */
- for (sect = s_first; sect <= s_last; sect++) {
- if (info->protect[sect] == 0) { /* not protected */
- FPWV *addr = (FPWV *) (info->start[sect]);
- FPW status;
-
- printf ("Erasing sector %2d ... ", sect);
-
- flash_unprotect_sectors (addr);
-
- /* arm simple, non interrupt dependent timer */
- start = get_timer(0);
-
- *addr = (FPW) 0x00500050;/* clear status register */
- *addr = (FPW) 0x00200020;/* erase setup */
- *addr = (FPW) 0x00D000D0;/* erase confirm */
-
- while (((status =
- *addr) & (FPW) 0x00800080) !=
- (FPW) 0x00800080) {
- if (get_timer(start) >
- CONFIG_SYS_FLASH_ERASE_TOUT) {
- printf ("Timeout\n");
- /* suspend erase */
- *addr = (FPW) 0x00B000B0;
- /* reset to read mode */
- *addr = (FPW) 0x00FF00FF;
- rcode = 1;
- break;
- }
- }
-
- /* clear status register cmd. */
- *addr = (FPW) 0x00500050;
- *addr = (FPW) 0x00FF00FF;/* resest to read mode */
- printf (" done\n");
- }
- }
- if (flag)
- enable_interrupts();
-
- return rcode;
-}
-
-/*-----------------------------------------------------------------------
- * Copy memory to flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- * 4 - Flash not identified
- */
-
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
- ulong cp, wp;
- FPW data;
- int count, i, l, rc, port_width;
-
- if (info->flash_id == FLASH_UNKNOWN) {
- return 4;
- }
-/* get lower word aligned address */
-#ifdef FLASH_PORT_WIDTH16
- wp = (addr & ~1);
- port_width = 2;
-#else
- wp = (addr & ~3);
- port_width = 4;
-#endif
-
- /*
- * handle unaligned start bytes
- */
- if ((l = addr - wp) != 0) {
- data = 0;
- for (i = 0, cp = wp; i < l; ++i, ++cp) {
- data = (data << 8) | (*(uchar *) cp);
- }
- for (; i < port_width && cnt > 0; ++i) {
- data = (data << 8) | *src++;
- --cnt;
- ++cp;
- }
- for (; cnt == 0 && i < port_width; ++i, ++cp) {
- data = (data << 8) | (*(uchar *) cp);
- }
-
- if ((rc = write_data (info, wp, SWAP (data))) != 0) {
- return (rc);
- }
- wp += port_width;
- }
-
- /*
- * handle word aligned part
- */
- count = 0;
- while (cnt >= port_width) {
- data = 0;
- for (i = 0; i < port_width; ++i) {
- data = (data << 8) | *src++;
- }
- if ((rc = write_data (info, wp, SWAP (data))) != 0) {
- return (rc);
- }
- wp += port_width;
- cnt -= port_width;
- if (count++ > 0x800) {
- spin_wheel ();
- count = 0;
- }
- }
-
- if (cnt == 0) {
- return (0);
- }
-
- /*
- * handle unaligned tail bytes
- */
- data = 0;
- for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
- data = (data << 8) | *src++;
- --cnt;
- }
- for (; i < port_width; ++i, ++cp) {
- data = (data << 8) | (*(uchar *) cp);
- }
-
- return (write_data (info, wp, SWAP (data)));
-}
-
-/*-----------------------------------------------------------------------
- * Write a word or halfword to Flash, returns:
- * 0 - OK
- * 1 - write timeout
- * 2 - Flash not erased
- */
-static int write_data (flash_info_t * info, ulong dest, FPW data)
-{
- FPWV *addr = (FPWV *) dest;
- ulong status;
- int flag, rc = 0;
- ulong start;
-
- /* Check if Flash is (sufficiently) erased */
- if ((*addr & data) != data) {
- printf("not erased at %08lx (%x)\n", (ulong) addr, *addr);
- return 2;
- }
- /* Disable interrupts which might cause a timeout here */
- flag = disable_interrupts ();
- *addr = (FPW) 0x00400040; /* write setup */
- *addr = data;
-
- /* arm simple, non interrupt dependent timer */
- start = get_timer(0);
-
- /* wait while polling the status register */
- while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
- if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
- rc = 1;
- goto done;
- }
- }
-done:
- if (flag)
- enable_interrupts();
-
- *addr = (FPW) 0x00FF00FF; /* restore read mode */
- return rc;
-}
-
-void inline spin_wheel (void)
-{
- static int p = 0;
- static char w[] = "\\/-";
-
- printf ("\010%c", w[p]);
- (++p == 3) ? (p = 0) : 0;
-}
+++ /dev/null
-/*
- * Board specific setup info
- *
- * (C) Copyright 2003
- * Texas Instruments, <www.ti.com>
- * Kshitij Gupta <Kshitij@ti.com>
- *
- * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
- *
- * 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>
-#include <version.h>
-
-#if defined(CONFIG_OMAP1610)
-#include <./configs/omap1510.h>
-#endif
-
-
-_TEXT_BASE:
- .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */
-
-.globl lowlevel_init
-lowlevel_init:
-
-
- /*------------------------------------------------------*
- *mask all IRQs by setting all bits in the INTMR default*
- *------------------------------------------------------*/
- mov r1, #0xffffffff
- ldr r0, =REG_IHL1_MIR
- str r1, [r0]
- ldr r0, =REG_IHL2_MIR
- str r1, [r0]
-
- /*------------------------------------------------------*
- * Set up ARM CLM registers (IDLECT1) *
- *------------------------------------------------------*/
- ldr r0, REG_ARM_IDLECT1
- ldr r1, VAL_ARM_IDLECT1
- str r1, [r0]
-
- /*------------------------------------------------------*
- * Set up ARM CLM registers (IDLECT2) *
- *------------------------------------------------------*/
- ldr r0, REG_ARM_IDLECT2
- ldr r1, VAL_ARM_IDLECT2
- str r1, [r0]
-
- /*------------------------------------------------------*
- * Set up ARM CLM registers (IDLECT3) *
- *------------------------------------------------------*/
- ldr r0, REG_ARM_IDLECT3
- ldr r1, VAL_ARM_IDLECT3
- str r1, [r0]
-
-#ifdef CONFIG_CS_AUTOBOOT /* do the setup depending on boot mode */
- ldr r0, CONF_STATUS
- ldr r1, [r0]
- tst r1, #0x02
- beq disable_wd /* booting from RAM, skip setup */
-#endif
-
- mov r1, #0x01 /* PER_EN bit */
- ldr r0, REG_ARM_RSTCT2
- strh r1, [r0] /* CLKM; Peripheral reset. */
-
- /* Set CLKM to Sync-Scalable */
- /* I supposedly need to enable the dsp clock before switching */
- mov r1, #0x0000
- ldr r0, REG_ARM_SYSST
- strh r1, [r0]
- mov r0, #0x400
-1:
- subs r0, r0, #0x1 /* wait for any bubbles to finish */
- bne 1b
- ldr r1, VAL_ARM_CKCTL
- ldr r0, REG_ARM_CKCTL
- strh r1, [r0]
-
- /* a few nops to let settle */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
- /* setup DPLL 1 */
- /* Ramp up the clock to 96Mhz */
- ldr r1, VAL_DPLL1_CTL
- ldr r0, REG_DPLL1_CTL
- strh r1, [r0]
- ands r1, r1, #0x10 /* Check if PLL is enabled. */
- beq lock_end /* Do not look for lock if BYPASS selected */
-2:
- ldrh r1, [r0]
- ands r1, r1, #0x01 /* Check the LOCK bit.*/
- beq 2b /* loop until bit goes hi. */
-lock_end:
-
-
- /*------------------------------------------------------*
- * Turn off the watchdog during init... *
- *------------------------------------------------------*/
-disable_wd:
- ldr r0, REG_WATCHDOG
- ldr r1, WATCHDOG_VAL1
- str r1, [r0]
- ldr r1, WATCHDOG_VAL2
- str r1, [r0]
- ldr r0, REG_WSPRDOG
- ldr r1, WSPRDOG_VAL1
- str r1, [r0]
- ldr r0, REG_WWPSDOG
-
-watch1Wait:
- ldr r1, [r0]
- tst r1, #0x10
- bne watch1Wait
-
- ldr r0, REG_WSPRDOG
- ldr r1, WSPRDOG_VAL2
- str r1, [r0]
- ldr r0, REG_WWPSDOG
-watch2Wait:
- ldr r1, [r0]
- tst r1, #0x10
- bne watch2Wait
-
-
- /* Set memory timings corresponding to the new clock speed */
-
- /* Check execution location to determine current execution location
- * and branch to appropriate initialization code.
- */
- /* Load physical SDRAM base. */
- mov r0, #0x10000000
- /* Get current execution location. */
- mov r1, pc
- /* Compare. */
- cmp r1, r0
- /* Skip over EMIF-fast initialization if running from SDRAM. */
- bge skip_sdram
-
- /*
- * Delay for SDRAM initialization.
- */
- mov r3, #0x1800 /* value should be checked */
-3:
- subs r3, r3, #0x1 /* Decrement count */
- bne 3b
-
-
- /*
- * Set SDRAM control values. Disable refresh before MRS command.
- */
-
- /* mobile ddr operation */
- ldr r0, REG_SDRAM_OPERATION
- mov r2, #07
- str r2, [r0]
-
- /* config register */
- ldr r0, REG_SDRAM_CONFIG
- ldr r1, SDRAM_CONFIG_VAL
- str r1, [r0]
-
- /* manual command register */
- ldr r0, REG_SDRAM_MANUAL_CMD
- /* issue set cke high */
- mov r1, #CMD_SDRAM_CKE_SET_HIGH
- str r1, [r0]
- /* issue nop */
- mov r1, #CMD_SDRAM_NOP
- str r1, [r0]
-
- mov r2, #0x0100
-waitMDDR1:
- subs r2, r2, #1
- bne waitMDDR1 /* delay loop */
-
- /* issue precharge */
- mov r1, #CMD_SDRAM_PRECHARGE
- str r1, [r0]
-
- /* issue autorefresh x 2 */
- mov r1, #CMD_SDRAM_AUTOREFRESH
- str r1, [r0]
- str r1, [r0]
-
- /* mrs register ddr mobile */
- ldr r0, REG_SDRAM_MRS
- mov r1, #0x33
- str r1, [r0]
-
- /* emrs1 low-power register */
- ldr r0, REG_SDRAM_EMRS1
- /* self refresh on all banks */
- mov r1, #0
- str r1, [r0]
-
- ldr r0, REG_DLL_URD_CONTROL
- ldr r1, DLL_URD_CONTROL_VAL
- str r1, [r0]
-
- ldr r0, REG_DLL_LRD_CONTROL
- ldr r1, DLL_LRD_CONTROL_VAL
- str r1, [r0]
-
- ldr r0, REG_DLL_WRT_CONTROL
- ldr r1, DLL_WRT_CONTROL_VAL
- str r1, [r0]
-
- /* delay loop */
- mov r2, #0x0100
-waitMDDR2:
- subs r2, r2, #1
- bne waitMDDR2
-
- /*
- * Delay for SDRAM initialization.
- */
- mov r3, #0x1800
-4:
- subs r3, r3, #1 /* Decrement count. */
- bne 4b
- b common_tc
-
-skip_sdram:
-
- ldr r0, REG_SDRAM_CONFIG
- ldr r1, SDRAM_CONFIG_VAL
- str r1, [r0]
-
-common_tc:
- /* slow interface */
- ldr r1, VAL_TC_EMIFS_CS0_CONFIG
- ldr r0, REG_TC_EMIFS_CS0_CONFIG
- str r1, [r0] /* Chip Select 0 */
-
- ldr r1, VAL_TC_EMIFS_CS1_CONFIG
- ldr r0, REG_TC_EMIFS_CS1_CONFIG
- str r1, [r0] /* Chip Select 1 */
- ldr r1, VAL_TC_EMIFS_CS3_CONFIG
- ldr r0, REG_TC_EMIFS_CS3_CONFIG
- str r1, [r0] /* Chip Select 3 */
-
-#ifdef CONFIG_H2_OMAP1610
- /* inserting additional 2 clock cycle hold time for LAN */
- ldr r0, REG_TC_EMIFS_CS1_ADVANCED
- ldr r1, VAL_TC_EMIFS_CS1_ADVANCED
- str r1, [r0]
-#endif
- /* Start MPU Timer 1 */
- ldr r0, REG_MPU_LOAD_TIMER
- ldr r1, VAL_MPU_LOAD_TIMER
- str r1, [r0]
-
- ldr r0, REG_MPU_CNTL_TIMER
- ldr r1, VAL_MPU_CNTL_TIMER
- str r1, [r0]
-
- /* back to arch calling code */
- mov pc, lr
-
- /* the literal pools origin */
- .ltorg
-
-#ifdef CONFIG_CS_AUTOBOOT
-CONF_STATUS:
- .word 0xfffe1130 /* 32 bits */
-#endif
-
-REG_TC_EMIFS_CONFIG: /* 32 bits */
- .word 0xfffecc0c
-REG_TC_EMIFS_CS0_CONFIG: /* 32 bits */
- .word 0xfffecc10
-REG_TC_EMIFS_CS1_CONFIG: /* 32 bits */
- .word 0xfffecc14
-REG_TC_EMIFS_CS2_CONFIG: /* 32 bits */
- .word 0xfffecc18
-REG_TC_EMIFS_CS3_CONFIG: /* 32 bits */
- .word 0xfffecc1c
-
-#ifdef CONFIG_H2_OMAP1610
-REG_TC_EMIFS_CS1_ADVANCED: /* 32 bits */
- .word 0xfffecc54
-#endif
-
-/* MPU clock/reset/power mode control registers */
-REG_ARM_CKCTL: /* 16 bits */
- .word 0xfffece00
-
-REG_ARM_IDLECT3: /* 16 bits */
- .word 0xfffece24
-REG_ARM_IDLECT2: /* 16 bits */
- .word 0xfffece08
-REG_ARM_IDLECT1: /* 16 bits */
- .word 0xfffece04
-
-REG_ARM_RSTCT2: /* 16 bits */
- .word 0xfffece14
-REG_ARM_SYSST: /* 16 bits */
- .word 0xfffece18
-/* DPLL control registers */
-REG_DPLL1_CTL: /* 16 bits */
- .word 0xfffecf00
-
-/* Watch Dog register */
-/* secure watchdog stop */
-REG_WSPRDOG:
- .word 0xfffeb048
-/* watchdog write pending */
-REG_WWPSDOG:
- .word 0xfffeb034
-
-WSPRDOG_VAL1:
- .word 0x0000aaaa
-WSPRDOG_VAL2:
- .word 0x00005555
-
-/* SDRAM config is: auto refresh enabled, 16 bit 4 bank,
- counter @8192 rows, 10 ns, 8 burst */
-REG_SDRAM_CONFIG:
- .word 0xfffecc20
-
-/* Operation register */
-REG_SDRAM_OPERATION:
- .word 0xfffecc80
-
-/* Manual command register */
-REG_SDRAM_MANUAL_CMD:
- .word 0xfffecc84
-
-/* SDRAM MRS (New) config is: CAS latency is 2, burst length 8 */
-REG_SDRAM_MRS:
- .word 0xfffecc70
-
-/* SDRAM MRS (New) config is: CAS latency is 2, burst length 8 */
-REG_SDRAM_EMRS1:
- .word 0xfffecc78
-
-/* WRT DLL register */
-REG_DLL_WRT_CONTROL:
- .word 0xfffecc68
-DLL_WRT_CONTROL_VAL:
- .word 0x03f00002
-
-/* URD DLL register */
-REG_DLL_URD_CONTROL:
- .word 0xfffeccc0
-DLL_URD_CONTROL_VAL:
- .word 0x00800002
-
-/* LRD DLL register */
-REG_DLL_LRD_CONTROL:
- .word 0xfffecccc
-
-REG_WATCHDOG:
- .word 0xfffec808
-
-REG_MPU_LOAD_TIMER:
- .word 0xfffec504
-REG_MPU_CNTL_TIMER:
- .word 0xfffec500
-
-/* 96 MHz Samsung Mobile DDR */
-SDRAM_CONFIG_VAL:
- .word 0x001200f4
-
-DLL_LRD_CONTROL_VAL:
- .word 0x00800002
-
-VAL_ARM_CKCTL:
- .word 0x3000
-VAL_DPLL1_CTL:
- .word 0x2830
-
-#ifdef CONFIG_INNOVATOROMAP1610
-VAL_TC_EMIFS_CS0_CONFIG:
- .word 0x002130b0
-VAL_TC_EMIFS_CS1_CONFIG:
- .word 0x00001131
-VAL_TC_EMIFS_CS2_CONFIG:
- .word 0x000055f0
-VAL_TC_EMIFS_CS3_CONFIG:
- .word 0x88011131
-#endif
-
-#ifdef CONFIG_H2_OMAP1610
-VAL_TC_EMIFS_CS0_CONFIG:
- .word 0x00203331
-VAL_TC_EMIFS_CS1_CONFIG:
- .word 0x8180fff3
-VAL_TC_EMIFS_CS2_CONFIG:
- .word 0xf800f22a
-VAL_TC_EMIFS_CS3_CONFIG:
- .word 0x88011131
-VAL_TC_EMIFS_CS1_ADVANCED:
- .word 0x00000022
-#endif
-
-VAL_TC_EMIFF_SDRAM_CONFIG:
- .word 0x010290fc
-VAL_TC_EMIFF_MRS:
- .word 0x00000027
-
-VAL_ARM_IDLECT1:
- .word 0x00000400
-
-VAL_ARM_IDLECT2:
- .word 0x00000886
-VAL_ARM_IDLECT3:
- .word 0x00000015
-
-WATCHDOG_VAL1:
- .word 0x000000f5
-WATCHDOG_VAL2:
- .word 0x000000a0
-
-VAL_MPU_LOAD_TIMER:
- .word 0xffffffff
-VAL_MPU_CNTL_TIMER:
- .word 0xffffffa1
-
-/* command values */
-.equ CMD_SDRAM_NOP, 0x00000000
-.equ CMD_SDRAM_PRECHARGE, 0x00000001
-.equ CMD_SDRAM_AUTOREFRESH, 0x00000002
-.equ CMD_SDRAM_CKE_SET_HIGH, 0x00000007
+++ /dev/null
-/*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2002
- * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
- *
- * (C) Copyright 2003
- * Texas Instruments, <www.ti.com>
- * Kshitij Gupta <Kshitij@ti.com>
- *
- * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <netdev.h>
-#if defined(CONFIG_OMAP1610)
-#include <./configs/omap1510.h>
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifdef CONFIG_CS_AUTOBOOT
-unsigned long omap_flash_base;
-#endif
-
-void flash__init (void);
-void ether__init (void);
-void set_muxconf_regs (void);
-void peripheral_power_enable (void);
-
-#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
-
-static inline void delay (unsigned long loops)
-{
- __asm__ volatile ("1:\n"
- "subs %0, %1, #1\n"
- "bne 1b":"=r" (loops):"0" (loops));
-}
-
-/*
- * Miscellaneous platform dependent initialisations
- */
-
-int board_init (void)
-{
- /* adress of boot parameters */
- gd->bd->bi_boot_params = 0x10000100;
-
- /* Configure MUX settings */
- set_muxconf_regs ();
- peripheral_power_enable ();
-
-/* this speeds up your boot a quite a bit. However to make it
- * work, you need make sure your kernel startup flush bug is fixed.
- * ... rkw ...
- */
- icache_enable ();
-
- flash__init ();
- ether__init ();
- return 0;
-}
-
-
-int misc_init_r (void)
-{
- /* currently empty */
- return (0);
-}
-
-/******************************
- Routine:
- Description:
-******************************/
-void flash__init (void)
-{
-#define EMIFS_GlB_Config_REG 0xfffecc0c
- unsigned int regval;
-
-#ifdef CONFIG_CS_AUTOBOOT
- /* Check swapping of CS0 and CS3, set flash base accordingly */
- omap_flash_base = ((*((u32 *)OMAP_EMIFS_CONFIG_REG) & 0x02) == 0) ?
- PHYS_FLASH_1_BM0 : PHYS_FLASH_1_BM1;
-#endif
- regval = *((volatile unsigned int *) EMIFS_GlB_Config_REG);
- /* Turn off write protection for flash devices. */
- regval = regval | 0x0001;
- *((volatile unsigned int *) EMIFS_GlB_Config_REG) = regval;
-}
-/*************************************************************
- Routine:ether__init
- Description: take the Ethernet controller out of reset and wait
- for the EEPROM load to complete.
-*************************************************************/
-void ether__init (void)
-{
-#define ETH_CONTROL_REG 0x0400030b
-
-#ifdef CONFIG_H2_OMAP1610
- #define LAN_RESET_REGISTER 0x0400001c
-
- /* The debug board on which the lan chip resides may not be powered
- * ON at the same time as the OMAP chip. So wait in a loop until the
- * lan reset register (on the debug board) is available (powered on)
- * and reset the lan chip.
- */
-
- *((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0000;
- do {
- *((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0001;
- udelay (3);
- } while (*((volatile unsigned short *) LAN_RESET_REGISTER) != 0x0001);
-
- do {
- *((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0000;
- udelay (3);
- } while (*((volatile unsigned short *) LAN_RESET_REGISTER) != 0x0000);
-#endif
-
- *((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
- udelay (3);
-}
-
-/******************************
- Routine:
- Description:
-******************************/
-int dram_init (void)
-{
- gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
- gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-
- return 0;
-}
-
-/******************************************************
- Routine: set_muxconf_regs
- Description: Setting up the configuration Mux registers
- specific to the hardware
-*******************************************************/
-void set_muxconf_regs (void)
-{
- volatile unsigned int *MuxConfReg;
- /* set each registers to its reset value; */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_0);
- /* setup for UART1 */
- *MuxConfReg &= ~(0x02000000); /* bit 25 */
- /* setup for UART2 */
- *MuxConfReg &= ~(0x01000000); /* bit 24 */
- /* Disable Uwire CS Hi-Z */
- *MuxConfReg |= 0x08000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_3);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_4);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_5);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_6);
- /*setup mux for UART3 */
- *MuxConfReg |= 0x00000001; /* bit3, 1, 0 (mux0 5,5,26) */
- *MuxConfReg &= ~0x0000003e;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_7);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_8);
- /* Disable Uwire CS Hi-Z */
- *MuxConfReg |= 0x00001200; /*bit 9 for CS0 12 for CS3 */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_9);
- /* Need to turn on bits 21 and 12 in FUNC_MUX_CTRL_9 so the */
- /* hardware will actually use TX and RTS based on bit 25 in */
- /* FUNC_MUX_CTRL_0. I told you this thing was screwy! */
- *MuxConfReg |= 0x00201000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_A);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_B);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_C);
- /* setup for UART2 */
- /* Need to turn on bits 27 and 24 in FUNC_MUX_CTRL_C so the */
- /* hardware will actually use TX and RTS based on bit 24 in */
- /* FUNC_MUX_CTRL_0. */
- *MuxConfReg |= 0x09000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_0);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_1);
- *MuxConfReg = 0x00000000;
- /* mux setup for SD/MMC driver */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_2);
- *MuxConfReg &= 0xFFFE0FFF;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_3);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
- /* bit 13 for MMC2 XOR_CLK */
- *MuxConfReg &= ~(0x00002000);
- /* bit 29 for UART 1 */
- *MuxConfReg &= ~(0x00002000);
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) FUNC_MUX_CTRL_0);
- /* Configure for USB. Turn on VBUS_CTRL and VBUS_MODE. */
- *MuxConfReg |= 0x000C0000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int)USB_TRANSCEIVER_CTRL);
- *MuxConfReg &= ~(0x00000070);
- *MuxConfReg &= ~(0x00000008);
- *MuxConfReg |= 0x00000003;
- *MuxConfReg |= 0x00000180;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
- /* bit 17, software controls VBUS */
- *MuxConfReg &= ~(0x00020000);
- /* Enable USB 48 and 12M clocks */
- *MuxConfReg |= 0x00000200;
- *MuxConfReg &= ~(0x00000180);
- /*2.75V for MMCSDIO1 */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) VOLTAGE_CTRL_0);
- *MuxConfReg = 0x00001FE7;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_0);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_1);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_2);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_3);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_4);
- *MuxConfReg = 0x00000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PULL_DWN_CTRL_4);
- *MuxConfReg = 0x00000000;
- /* Turn on UART2 48 MHZ clock */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) MOD_CONF_CTRL_0);
- *MuxConfReg |= 0x40000000;
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) USB_OTG_CTRL);
- /* setup for USB VBus detection OMAP161x */
- *MuxConfReg |= 0x00040000; /* bit 18 */
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int) PU_PD_SEL_2);
- /* PullUps for SD/MMC driver */
- *MuxConfReg |= ~(0xFFFE0FFF);
- MuxConfReg =
- (volatile unsigned int *) ((unsigned int)COMP_MODE_CTRL_0);
- *MuxConfReg = COMP_MODE_ENABLE;
-}
-
-/******************************************************
- Routine: peripheral_power_enable
- Description: Enable the power for UART1
-*******************************************************/
-void peripheral_power_enable (void)
-{
-#define UART1_48MHZ_ENABLE ((unsigned short)0x0200)
-#define SW_CLOCK_REQUEST ((volatile unsigned short *)0xFFFE0834)
-
- *SW_CLOCK_REQUEST |= UART1_48MHZ_ENABLE;
-}
-
-#ifdef CONFIG_CMD_NET
-int board_eth_init(bd_t *bis)
-{
- int rc = 0;
-#ifdef CONFIG_LAN91C96
- rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE);
-#endif
- return rc;
-}
-#endif
#include <asm/arch/mem.h>
#include <asm/mach-types.h>
#include "devkit8000.h"
+#include <asm/gpio.h>
#ifdef CONFIG_DRIVER_DM9000
#include <net.h>
#include <netdev.h>
return 0;
}
+/* Configure GPMC registers for DM9000 */
+static void gpmc_dm9000_config(void)
+{
+ enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6],
+ CONFIG_DM9000_BASE, GPMC_SIZE_16M);
+}
+
/*
* Routine: misc_init_r
* Description: Configure board specific parts
}
#endif
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Do board specific preperation before SPL
+ * Linux boot
+ */
+void spl_board_prepare_for_linux(void)
+{
+ gpmc_dm9000_config();
+}
+
+/*
+ * devkit8000 specific implementation of spl_start_uboot()
+ *
+ * RETURN
+ * 0 if the button is not pressed
+ * 1 if the button is pressed
+ */
+int spl_start_uboot(void)
+{
+ int val = 0;
+ if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) {
+ gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY);
+ val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY);
+ gpio_free(CONFIG_SPL_OS_BOOT_KEY);
+ }
+ return !val;
+}
+#endif
+
/*
* Routine: get_board_mem_timings
* Description: If we use SPL then there is no x-loader nor config header
for (;;)
;
}
-
-void icache_disable(void) {}
-void dcache_disable(void) {}
#include <serial.h>
#include <asm/arch/hardware.h>
#include <asm/arch/pxa.h>
+#include <asm/arch/regs-mmc.h>
#include <spi.h>
#include <asm/io.h>
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
}
+#ifdef CONFIG_CMD_MMC
+int board_mmc_init(bd_t *bis)
+{
+ pxa_mmc_register(0);
+ return 0;
+}
+#endif
+
#ifdef CONFIG_CMD_SPI
struct {
pm9g45 arm arm926ejs pm9g45 ronetix at91 pm9g45:AT91SAM9G45
cam_enc_4xx arm arm926ejs cam_enc_4xx ait davinci cam_enc_4xx
da830evm arm arm926ejs da8xxevm davinci davinci
-da850_am18xxevm arm arm926ejs da8xxevm davinci davinci da850evm:DA850_AM18X_EVM
-da850evm arm arm926ejs da8xxevm davinci davinci
+da850_am18xxevm arm arm926ejs da8xxevm davinci davinci da850evm:DA850_AM18X_EVM,MAC_ADDR_IN_EEPROM,SYS_I2C_EEPROM_ADDR_LEN=2,SYS_I2C_EEPROM_ADDR=0x50
+da850evm arm arm926ejs da8xxevm davinci davinci da850evm:MAC_ADDR_IN_SPIFLASH
davinci_dm355evm arm arm926ejs dm355evm davinci davinci
davinci_dm355leopard arm arm926ejs dm355leopard davinci davinci
davinci_dm365evm arm arm926ejs dm365evm davinci davinci
-davinci_dm6467evm arm arm926ejs dm6467evm davinci davinci
-davinci_dm6467Tevm arm arm926ejs dm6467evm davinci davinci
+davinci_dm6467evm arm arm926ejs dm6467evm davinci davinci davinci_dm6467evm:REFCLK_FREQ=27000000
+davinci_dm6467Tevm arm arm926ejs dm6467evm davinci davinci davinci_dm6467evm:DAVINCI_DM6467TEVM,REFCLK_FREQ=33000000
davinci_dvevm arm arm926ejs dvevm davinci davinci
davinci_schmoogie arm arm926ejs schmoogie davinci davinci
davinci_sffsdr arm arm926ejs sffsdr davinci davinci
mx28evk arm arm926ejs - freescale mx28
nhk8815 arm arm926ejs nhk8815 st nomadik
nhk8815_onenand arm arm926ejs nhk8815 st nomadik nhk8815:BOOT_ONENAND
-omap1610h2 arm arm926ejs omap1610inn ti omap omap1610inn:CS3_BOOT
-omap1610h2_cs0boot arm arm926ejs omap1610inn ti omap omap1610inn:CS0_BOOT
-omap1610h2_cs3boot arm arm926ejs omap1610inn ti omap omap1610inn:CS3_BOOT
-omap1610h2_cs_autoboot arm arm926ejs omap1610inn ti omap omap1610inn:CS_AUTOBOOT
-omap1610inn arm arm926ejs omap1610inn ti omap omap1610inn:CS3_BOOT
-omap1610inn_cs0boot arm arm926ejs omap1610inn ti omap omap1610inn:CS0_BOOT
-omap1610inn_cs3boot arm arm926ejs omap1610inn ti omap omap1610inn:CS3_BOOT
-omap1610inn_cs_autoboot arm arm926ejs omap1610inn ti omap omap1610inn:CS_AUTOBOOT
omap5912osk arm arm926ejs - ti omap
omap730p2 arm arm926ejs omap730p2 ti omap omap730p2:CS3_BOOT
omap730p2_cs0boot arm arm926ejs omap730p2 ti omap omap730p2:CS0_BOOT
actux3 arm ixp
actux4 arm ixp
dvlhost arm ixp
+pdnb3 arm ixp pdnb3 prodrive
+scpu arm ixp pdnb3 prodrive - pdnb3:SCPU
balloon3 arm pxa
lubbock arm pxa
palmld arm pxa
COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o
COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o
+COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o
COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o
COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o
COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
ifdef CONFIG_CMD_USB
COBJS-y += cmd_usb.o
-COBJS-y += usb.o
+COBJS-y += usb.o usb_hub.o
COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
endif
COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
+COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
# others
ifdef CONFIG_DDR_SPD
endif
COBJS-$(SPD) += ddr_spd.o
COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
+COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o
COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
COBJS-y += flash.o
COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
endif
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o
+endif
COBJS-y += console.o
COBJS-y += dlmalloc.o
COBJS-y += memsize.o
--- /dev/null
+/*
+ * Copyright (c) 2011, Google Inc. All rights reserved.
+ *
+ * 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
+ */
+
+
+/*
+ * This module records the progress of boot and arbitrary commands, and
+ * permits accurate timestamping of each.
+ *
+ * TBD: Pass timings to kernel in the FDT
+ */
+
+#include <common.h>
+#include <libfdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum bootstage_flags {
+ BOOTSTAGEF_ERROR = 1 << 0, /* Error record */
+ BOOTSTAGEF_ALLOC = 1 << 1, /* Allocate an id */
+};
+
+struct bootstage_record {
+ ulong time_us;
+ const char *name;
+ int flags; /* see enum bootstage_flags */
+ enum bootstage_id id;
+};
+
+static struct bootstage_record record[BOOTSTAGE_ID_COUNT] = { {1} };
+static int next_id = BOOTSTAGE_ID_USER;
+
+ulong bootstage_add_record(enum bootstage_id id, const char *name,
+ int flags)
+{
+ struct bootstage_record *rec;
+ ulong mark = timer_get_boot_us();
+
+ if (flags & BOOTSTAGEF_ALLOC)
+ id = next_id++;
+
+ if (id < BOOTSTAGE_ID_COUNT) {
+ rec = &record[id];
+
+ /* Only record the first event for each */
+ if (!rec->time_us) {
+ rec->time_us = mark;
+ rec->name = name;
+ rec->flags = flags;
+ rec->id = id;
+ }
+ }
+
+ /* Tell the board about this progress */
+ show_boot_progress(flags & BOOTSTAGEF_ERROR ? -id : id);
+ return mark;
+}
+
+
+ulong bootstage_mark(enum bootstage_id id)
+{
+ return bootstage_add_record(id, NULL, 0);
+}
+
+ulong bootstage_error(enum bootstage_id id)
+{
+ return bootstage_add_record(id, NULL, BOOTSTAGEF_ERROR);
+}
+
+ulong bootstage_mark_name(enum bootstage_id id, const char *name)
+{
+ int flags = 0;
+
+ if (id == BOOTSTAGE_ID_ALLOC)
+ flags = BOOTSTAGEF_ALLOC;
+ return bootstage_add_record(id, name, flags);
+}
+
+static void print_time(unsigned long us_time)
+{
+ char str[15], *s;
+ int grab = 3;
+
+ /* We don't seem to have %'d in U-Boot */
+ sprintf(str, "%12lu", us_time);
+ for (s = str + 3; *s; s += grab) {
+ if (s != str + 3)
+ putc(s[-1] != ' ' ? ',' : ' ');
+ printf("%.*s", grab, s);
+ grab = 3;
+ }
+}
+
+static uint32_t print_time_record(enum bootstage_id id,
+ struct bootstage_record *rec, uint32_t prev)
+{
+ print_time(rec->time_us);
+ print_time(rec->time_us - prev);
+ if (rec->name)
+ printf(" %s\n", rec->name);
+ else if (id >= BOOTSTAGE_ID_USER)
+ printf(" user_%d\n", id - BOOTSTAGE_ID_USER);
+ else
+ printf(" id=%d\n", id);
+ return rec->time_us;
+}
+
+static int h_compare_record(const void *r1, const void *r2)
+{
+ const struct bootstage_record *rec1 = r1, *rec2 = r2;
+
+ return rec1->time_us > rec2->time_us ? 1 : -1;
+}
+
+void bootstage_report(void)
+{
+ struct bootstage_record *rec = record;
+ int id;
+ uint32_t prev;
+
+ puts("Timer summary in microseconds:\n");
+ printf("%11s%11s %s\n", "Mark", "Elapsed", "Stage");
+
+ /* Fake the first record - we could get it from early boot */
+ rec->name = "reset";
+ rec->time_us = 0;
+ prev = print_time_record(BOOTSTAGE_ID_AWAKE, rec, 0);
+
+ /* Sort records by increasing time */
+ qsort(record, ARRAY_SIZE(record), sizeof(*rec), h_compare_record);
+
+ for (id = 0; id < BOOTSTAGE_ID_COUNT; id++, rec++) {
+ if (rec->time_us != 0)
+ prev = print_time_record(rec->id, rec, prev);
+ }
+ if (next_id > BOOTSTAGE_ID_COUNT)
+ printf("(Overflowed internal boot id table by %d entries\n"
+ "- please increase CONFIG_BOOTSTAGE_USER_COUNT\n",
+ next_id - BOOTSTAGE_ID_COUNT);
+}
len = dis_last_len;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/* New command */
int rcode = 0;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
printf ("\nEnter '.' when done\n");
mem_addr = simple_strtoul (argv[1], NULL, 16);
if (len == -1)
printf ("<INTERRUPT>\n");
else
- rc = run_command (lastcommand, flag);
+ rc = run_command(lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
addr = simple_strtoul(argv[1], NULL, 16);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return (bmp_info(addr));
y = simple_strtoul(argv[3], NULL, 10);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return (bmp_display(addr, x, y));
if (c)
return c->cmd(cmdtp, flag, argc, argv);
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
int rcode = 0;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = simple_strtoul(argv[1], NULL, 16);
#define IH_INITRD_ARCH IH_ARCH_DEFAULT
-static void bootm_start_lmb(void)
-{
#ifdef CONFIG_LMB
+static void boot_start_lmb(bootm_headers_t *images)
+{
ulong mem_start;
phys_size_t mem_size;
- lmb_init(&images.lmb);
+ lmb_init(&images->lmb);
mem_start = getenv_bootm_low();
mem_size = getenv_bootm_size();
- lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size);
+ lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
- arch_lmb_reserve(&images.lmb);
- board_lmb_reserve(&images.lmb);
+ arch_lmb_reserve(&images->lmb);
+ board_lmb_reserve(&images->lmb);
+}
#else
-# define lmb_reserve(lmb, base, size)
+#define lmb_reserve(lmb, base, size)
+static inline void boot_start_lmb(bootm_headers_t *images) { }
#endif
-}
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
memset((void *)&images, 0, sizeof(images));
images.verify = getenv_yesno("verify");
- bootm_start_lmb();
+ boot_start_lmb(&images);
+
+ bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start");
/* get kernel image header, start address and length */
os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
if (fit_image_get_type(images.fit_hdr_os,
images.fit_noffset_os, &images.os.type)) {
puts("Can't get image type!\n");
- show_boot_progress(-109);
+ bootstage_error(BOOTSTAGE_ID_FIT_TYPE);
return 1;
}
if (fit_image_get_comp(images.fit_hdr_os,
images.fit_noffset_os, &images.os.comp)) {
puts("Can't get image compression!\n");
- show_boot_progress(-110);
+ bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION);
return 1;
}
if (fit_image_get_os(images.fit_hdr_os,
images.fit_noffset_os, &images.os.os)) {
puts("Can't get image OS!\n");
- show_boot_progress(-111);
+ bootstage_error(BOOTSTAGE_ID_FIT_OS);
return 1;
}
if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os,
&images.os.load)) {
puts("Can't get image load address!\n");
- show_boot_progress(-112);
+ bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR);
return 1;
}
break;
puts("GUNZIP: uncompress, out-of-mem or overwrite "
"error - must RESET board to recover\n");
if (boot_progress)
- show_boot_progress(-6);
+ bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return BOOTM_ERR_RESET;
}
printf("BUNZIP2: uncompress or overwrite error %d "
"- must RESET board to recover\n", i);
if (boot_progress)
- show_boot_progress(-6);
+ bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return BOOTM_ERR_RESET;
}
if (ret != SZ_OK) {
printf("LZMA: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
- show_boot_progress(-6);
+ bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return BOOTM_ERR_RESET;
}
*load_end = load + unc_len;
printf("LZO: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
if (boot_progress)
- show_boot_progress(-6);
+ bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return BOOTM_ERR_RESET;
}
puts("OK\n");
debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
- if (boot_progress)
- show_boot_progress(7);
+ bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
}
} else {
/* Unrecognized command */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (images.state >= state) {
printf("Trying to execute a command out of order\n");
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
images.state |= state;
} else {
puts("ERROR: new format image overwritten - "
"must RESET the board to recover\n");
- show_boot_progress(-113);
+ bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
do_reset(cmdtp, flag, argc, argv);
}
}
if (ret == BOOTM_ERR_UNIMPLEMENTED) {
if (iflag)
enable_interrupts();
- show_boot_progress(-7);
+ bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
return 1;
}
}
return 0;
}
- show_boot_progress(8);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS);
#ifdef CONFIG_SILENT_CONSOLE
if (images.os.os == IH_OS_LINUX)
enable_interrupts();
printf("ERROR: booting os '%s' (%d) is not supported\n",
genimg_get_os_name(images.os.os), images.os.os);
- show_boot_progress(-8);
+ bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
return 1;
}
boot_fn(0, argc, argv, &images);
- show_boot_progress(-9);
+ bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
#ifdef DEBUG
puts("\n## Control returned to monitor - resetting...\n");
#endif
if (!image_check_magic(hdr)) {
puts("Bad Magic Number\n");
- show_boot_progress(-1);
+ bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
return NULL;
}
- show_boot_progress(2);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);
if (!image_check_hcrc(hdr)) {
puts("Bad Header Checksum\n");
- show_boot_progress(-2);
+ bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
return NULL;
}
- show_boot_progress(3);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
image_print_contents(hdr);
if (verify) {
puts(" Verifying Checksum ... ");
if (!image_check_dcrc(hdr)) {
printf("Bad Data CRC\n");
- show_boot_progress(-3);
+ bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
return NULL;
}
puts("OK\n");
}
- show_boot_progress(4);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);
if (!image_check_target_arch(hdr)) {
printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
- show_boot_progress(-4);
+ bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
return NULL;
}
return hdr;
puts(" Verifying Hash Integrity ... ");
if (!fit_image_check_hashes(fit, os_noffset)) {
puts("Bad Data Hash\n");
- show_boot_progress(-104);
+ bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);
return 0;
}
puts("OK\n");
}
- show_boot_progress(105);
+ bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH);
if (!fit_image_check_target_arch(fit, os_noffset)) {
puts("Unsupported Architecture\n");
- show_boot_progress(-105);
+ bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH);
return 0;
}
- show_boot_progress(106);
+ bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) &&
!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) {
puts("Not a kernel image\n");
- show_boot_progress(-106);
+ bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
return 0;
}
- show_boot_progress(107);
+ bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED);
return 1;
}
#endif /* CONFIG_FIT */
debug("* kernel: cmdline image address = 0x%08lx\n", img_addr);
}
- show_boot_progress(1);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
/* copy from dataflash if needed */
img_addr = genimg_get_image(img_addr);
hdr = image_get_kernel(img_addr, images->verify);
if (!hdr)
return NULL;
- show_boot_progress(5);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);
/* get os_data and os_len */
switch (image_get_type(hdr)) {
default:
printf("Wrong Image Type for %s command\n",
cmdtp->name);
- show_boot_progress(-5);
+ bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
return NULL;
}
images->legacy_hdr_os = hdr;
images->legacy_hdr_valid = 1;
- show_boot_progress(6);
+ bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
if (!fit_check_format(fit_hdr)) {
puts("Bad FIT kernel image format!\n");
- show_boot_progress(-100);
+ bootstage_error(BOOTSTAGE_ID_FIT_FORMAT);
return NULL;
}
- show_boot_progress(100);
+ bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT);
if (!fit_uname_kernel) {
/*
* fit_conf_get_node() will try to find default config
* node
*/
- show_boot_progress(101);
+ bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
cfg_noffset = fit_conf_get_node(fit_hdr,
fit_uname_config);
if (cfg_noffset < 0) {
- show_boot_progress(-101);
+ bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
return NULL;
}
/* save configuration uname provided in the first
NULL);
printf(" Using '%s' configuration\n",
images->fit_uname_cfg);
- show_boot_progress(103);
+ bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
os_noffset = fit_conf_get_kernel_node(fit_hdr,
cfg_noffset);
NULL);
} else {
/* get kernel component image node offset */
- show_boot_progress(102);
+ bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME);
os_noffset = fit_image_get_node(fit_hdr,
fit_uname_kernel);
}
if (os_noffset < 0) {
- show_boot_progress(-103);
+ bootstage_error(BOOTSTAGE_ID_FIT_CONFIG);
return NULL;
}
printf(" Trying '%s' kernel subimage\n", fit_uname_kernel);
- show_boot_progress(104);
+ bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE);
if (!fit_check_kernel(fit_hdr, os_noffset, images->verify))
return NULL;
/* get kernel image data address and length */
if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) {
puts("Could not find kernel subimage data!\n");
- show_boot_progress(-107);
+ bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR);
return NULL;
}
- show_boot_progress(108);
+ bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO);
*os_len = len;
*os_data = (ulong)data;
#endif
default:
printf("Wrong Image Format for %s command\n", cmdtp->name);
- show_boot_progress(-108);
+ bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
return NULL;
}
{
int rcode = 0;
-#ifndef CONFIG_SYS_HUSH_PARSER
if (run_command(getenv("bootcmd"), flag) < 0)
rcode = 1;
-#else
- if (parse_string_outer(getenv("bootcmd"),
- FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0)
- rcode = 1;
-#endif
return rcode;
}
"(at address %08lx) ...\n",
(ulong)loader);
- show_boot_progress(15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* NetBSD Stage-2 Loader Parameters:
printf("## Transferring control to RTEMS (at address %08lx) ...\n",
(ulong)entry_point);
- show_boot_progress(15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* RTEMS Parameters:
printf("## Transferring control to OSE (at address %08lx) ...\n",
(ulong)entry_point);
- show_boot_progress(15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* OSE Parameters:
printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
(ulong)entry_point);
- show_boot_progress(15);
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
/*
* INTEGRITY Parameters:
return 1;
}
#endif
+
+#ifdef CONFIG_CMD_BOOTZ
+
+static int __bootz_setup(void *image, void **start, void **end)
+{
+ /* Please define bootz_setup() for your platform */
+
+ puts("Your platform's zImage format isn't supported yet!\n");
+ return -1;
+}
+int bootz_setup(void *image, void **start, void **end)
+ __attribute__((weak, alias("__bootz_setup")));
+
+/*
+ * zImage booting support
+ */
+static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[], bootm_headers_t *images)
+{
+ int ret;
+ void *zi_start, *zi_end;
+
+ memset(images, 0, sizeof(bootm_headers_t));
+
+ boot_start_lmb(images);
+
+ /* Setup Linux kernel zImage entry point */
+ if (argc < 2) {
+ images->ep = load_addr;
+ debug("* kernel: default image load address = 0x%08lx\n",
+ load_addr);
+ } else {
+ images->ep = simple_strtoul(argv[1], NULL, 16);
+ debug("* kernel: cmdline image address = 0x%08lx\n",
+ images->ep);
+ }
+
+ ret = bootz_setup((void *)images->ep, &zi_start, &zi_end);
+ if (ret != 0)
+ return 1;
+
+ lmb_reserve(&images->lmb, images->ep, zi_end - zi_start);
+
+ /* Find ramdisk */
+ ret = boot_get_ramdisk(argc, argv, images, IH_INITRD_ARCH,
+ &images->rd_start, &images->rd_end);
+ if (ret) {
+ puts("Ramdisk image is corrupt or invalid\n");
+ return 1;
+ }
+
+#if defined(CONFIG_OF_LIBFDT)
+ /* find flattened device tree */
+ ret = boot_get_fdt(flag, argc, argv, images,
+ &images->ft_addr, &images->ft_len);
+ if (ret) {
+ puts("Could not find a valid device tree\n");
+ return 1;
+ }
+
+ set_working_fdt_addr(images->ft_addr);
+#endif
+
+ return 0;
+}
+
+static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ ulong iflag;
+ bootm_headers_t images;
+
+ if (bootz_start(cmdtp, flag, argc, argv, &images))
+ return 1;
+
+ /*
+ * We have reached the point of no return: we are going to
+ * overwrite all exception vector code, so we cannot easily
+ * recover from any failures any more...
+ */
+ iflag = disable_interrupts();
+
+#if defined(CONFIG_CMD_USB)
+ /*
+ * turn off USB to prevent the host controller from writing to the
+ * SDRAM while Linux is booting. This could happen (at least for OHCI
+ * controller), because the HCCA (Host Controller Communication Area)
+ * lies within the SDRAM and the host controller writes continously to
+ * this area (as busmaster!). The HccaFrameNumber is for example
+ * updated every 1 ms within the HCCA structure in SDRAM! For more
+ * details see the OpenHCI specification.
+ */
+ usb_stop();
+#endif
+
+#ifdef CONFIG_SILENT_CONSOLE
+ fixup_silent_linux();
+#endif
+ arch_preboot_os();
+
+ do_bootm_linux(0, argc, argv, &images);
+#ifdef DEBUG
+ puts("\n## Control returned to monitor - resetting...\n");
+#endif
+ do_reset(cmdtp, flag, argc, argv);
+
+ return 1;
+}
+
+U_BOOT_CMD(
+ bootz, CONFIG_SYS_MAXARGS, 1, do_bootz,
+ "boot Linux zImage image from memory",
+ "[addr [initrd[:size]] [fdt]]\n"
+ " - boot Linux zImage stored in memory\n"
+ "\tThe argument 'initrd' is optional and specifies the address\n"
+ "\tof the initrd in memory. The optional argument ':size' allows\n"
+ "\tspecifying the size of RAW initrd.\n"
+#if defined(CONFIG_OF_LIBFDT)
+ "\tWhen booting a Linux kernel which requires a flat device-tree\n"
+ "\ta third argument is required which is the address of the\n"
+ "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
+ "\tuse a '-' for the second argument. If you do not pass a third\n"
+ "\ta bd_info struct will be passed instead\n"
+#endif
+);
+#endif /* CONFIG_CMD_BOOTZ */
static int parse_argv(const char *);
-void __weak flush_icache(void)
+void __weak invalidate_icache_all(void)
{
- /* please define arch specific flush_icache */
- puts("No arch specific flush_icache available!\n");
+ /* please define arch specific invalidate_icache_all */
+ puts("No arch specific invalidate_icache_all available!\n");
}
int do_icache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
break;
case 1: icache_enable ();
break;
- case 2: flush_icache();
+ case 2: invalidate_icache_all();
break;
}
/* FALL TROUGH */
icache_status() ? "ON" : "OFF");
return 0;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
}
-void __weak flush_dcache(void)
+void __weak flush_dcache_all(void)
{
- puts("No arch specific flush_dcache available!\n");
- /* please define arch specific flush_dcache */
+ puts("No arch specific flush_dcache_all available!\n");
+ /* please define arch specific flush_dcache_all */
}
int do_dcache ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
break;
case 1: dcache_enable ();
break;
- case 2: flush_dcache();
+ case 2: flush_dcache_all();
break;
}
/* FALL TROUGH */
dcache_status() ? "ON" : "OFF");
return 0;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
AT91F_GetMuxStatus () ? "MMC" : "SPI");
return 0;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
}
break;
default:
- cmd_usage(cmdtp);
- rcode = 1;
+ rcode = CMD_RET_USAGE;
}
/* switch back to original I2C bus */
/* Validate arguments */
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Get a DCR */
dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16);
/* Validate arguments */
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Set a DCR */
dcrn = (unsigned short) simple_strtoul (argv[1], NULL, 16);
/* Validate arguments */
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Find out whether ther is '.' (dot) symbol in the first parameter. */
strncpy (buf, argv[1], sizeof(buf)-1);
/* Validate arguments */
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Find out whether ther is '.' (dot) symbol in the first parameter. */
strncpy (buf, argv[1], sizeof(buf)-1);
}
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
}
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
#endif
(char *) bootaddr);
printf ("## Starting vxWorks at 0x%08lx ...\n", addr);
- ((void (*)(void)) addr) ();
+ dcache_disable();
+ ((void (*)(int)) addr) (0);
puts ("## vxWorks terminated\n");
return 1;
int part_length;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc = get_dev(argv[1],dev);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (!filename) {
"<interface> <dev[:part]>\n"
" - print information about filesystem from 'dev' on 'interface'"
);
+
+#ifdef CONFIG_FAT_WRITE
+static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ long size;
+ unsigned long addr;
+ unsigned long count;
+ block_dev_desc_t *dev_desc = NULL;
+ int dev = 0;
+ int part = 1;
+ char *ep;
+
+ if (argc < 5)
+ return cmd_usage(cmdtp);
+
+ dev = (int)simple_strtoul(argv[2], &ep, 16);
+ dev_desc = get_dev(argv[1], dev);
+ if (dev_desc == NULL) {
+ puts("\n** Invalid boot device **\n");
+ return 1;
+ }
+ if (*ep) {
+ if (*ep != ':') {
+ puts("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ part = (int)simple_strtoul(++ep, NULL, 16);
+ }
+ if (fat_register_device(dev_desc, part) != 0) {
+ printf("\n** Unable to use %s %d:%d for fatwrite **\n",
+ argv[1], dev, part);
+ return 1;
+ }
+ addr = simple_strtoul(argv[3], NULL, 16);
+ count = simple_strtoul(argv[5], NULL, 16);
+
+ size = file_fat_write(argv[4], (void *)addr, count);
+ if (size == -1) {
+ printf("\n** Unable to write \"%s\" from %s %d:%d **\n",
+ argv[4], argv[1], dev, part);
+ return 1;
+ }
+
+ printf("%ld bytes written\n", size);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ fatwrite, 6, 0, do_fat_fswrite,
+ "write file into a dos filesystem",
+ "<interface> <dev[:part]> <addr> <filename> <bytes>\n"
+ " - write file 'filename' from the address 'addr' in RAM\n"
+ " to 'dev' on 'interface'"
+);
+#endif
boot_drive=simple_strtoul(argv[2], NULL, 10);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/* setup FDC and scan for drives */
if(fdc_setup(boot_drive,pCMD,pFG)==FALSE) {
name = argv [2];
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/* Init physical layer */
int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Set the address of the fdt
int err;
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Set the address and length of the fdt.
* Parameters: Node path, new node to be appended to the path.
*/
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
pathp = argv[2];
nodep = argv[3];
* Parameters: Node path, property, optional value.
*/
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
pathp = argv[2];
prop = argv[3];
}
} else {
/* Unrecognized command */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
}
#ifdef CONFIG_OF_BOARD_SETUP
unsigned long initrd_start = 0, initrd_end = 0;
if ((argc != 2) && (argc != 4))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (argc == 4) {
initrd_start = simple_strtoul(argv[2], NULL, 16);
}
else {
/* Unrecognized command */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
ulong addr = 0UL;
if (argc > 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (argc == 2)
addr = simple_strtoul(argv[1], NULL, 16);
int rcode = 0;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (strcmp(argv[1], "all") == 0) {
for (bank=1; bank<=CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
#endif
if (argc != 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (strcmp(argv[1], "bank") == 0) {
bank = simple_strtoul(argv[2], NULL, 16);
}
if (addr_first >= addr_last)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
rcode = flash_sect_erase(addr_first, addr_last);
return rcode;
#endif
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#if !defined(CONFIG_SYS_NO_FLASH) || defined(CONFIG_HAS_DATAFLASH)
if (strcmp(argv[1], "off") == 0)
else if (strcmp(argv[1], "on") == 0)
p = 1;
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#endif
#ifdef CONFIG_HAS_DATAFLASH
#endif
if (argc != 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (strcmp(argv[2], "bank") == 0) {
bank = simple_strtoul(argv[3], NULL, 16);
}
if (addr_first >= addr_last)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
rcode = flash_sect_protect (p, addr_first, addr_last);
#endif /* CONFIG_SYS_NO_FLASH */
switch (op) {
case FPGA_NONE:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case FPGA_INFO:
rc = fpga_info (dev);
default:
printf ("Unknown operation\n");
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return (rc);
}
if (argc != 3)
show_usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
str_cmd = argv[1];
str_gpio = argv[2];
u_char *memaddr;
if (argc != 5)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* I2C chip address
devaddr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Length is the number of objects, not number of bytes.
length = i2c_dp_last_length;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/*
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* If another parameter, it is the length to display.
int count;
if ((argc < 4) || (argc > 5))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Value to write is always specified.
ulong err;
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Count is always specified
int nbytes;
if (argc != 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout(); /* got a good command to get here */
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/*
int delay;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
addr = simple_strtoul(argv[2], NULL, 16);
alen = get_alen(argv[2]);
if (alen > 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Length is the number of objects, not number of bytes.
};
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* Chip is always specified.
cmd_tbl_t *c;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Strip off leading 'i2c' command argument */
argc--;
c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub));
if (c)
- return c->cmd(cmdtp, flag, argc, argv);
+ return c->cmd(cmdtp, flag, argc, argv);
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/***************************************************/
switch (argc) {
case 0:
case 1:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1], "res", 3) == 0) {
puts("\nReset IDE"
}
return rcode;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int) simple_strtoul(argv[2], NULL, 10);
return rcode;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
default:
/* at least 4 args */
else
return 1;
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return rcode;
const void *fit_hdr = NULL;
#endif
- show_boot_progress(41);
+ bootstage_mark(BOOTSTAGE_ID_IDE_START);
switch (argc) {
case 1:
addr = CONFIG_SYS_LOAD_ADDR;
boot_device = argv[2];
break;
default:
- show_boot_progress(-42);
- return cmd_usage(cmdtp);
+ bootstage_error(BOOTSTAGE_ID_IDE_ADDR);
+ return CMD_RET_USAGE;
}
- show_boot_progress(42);
+ bootstage_mark(BOOTSTAGE_ID_IDE_ADDR);
if (!boot_device) {
puts("\n** No boot device **\n");
- show_boot_progress(-43);
+ bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE);
return 1;
}
- show_boot_progress(43);
+ bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE);
dev = simple_strtoul(boot_device, &ep, 16);
if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
printf("\n** Device %d not available\n", dev);
- show_boot_progress(-44);
+ bootstage_error(BOOTSTAGE_ID_IDE_TYPE);
return 1;
}
- show_boot_progress(44);
+ bootstage_mark(BOOTSTAGE_ID_IDE_TYPE);
if (*ep) {
if (*ep != ':') {
puts("\n** Invalid boot device, use `dev[:part]' **\n");
- show_boot_progress(-45);
+ bootstage_error(BOOTSTAGE_ID_IDE_PART);
return 1;
}
part = simple_strtoul(++ep, NULL, 16);
}
- show_boot_progress(45);
+ bootstage_mark(BOOTSTAGE_ID_IDE_PART);
+
if (get_partition_info(&ide_dev_desc[dev], part, &info)) {
- show_boot_progress(-46);
+ bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO);
return 1;
}
- show_boot_progress(46);
+ bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO);
+
if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0)
&&
(strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)
printf("\n** Invalid partition type \"%.32s\"" " (expect \""
BOOT_PART_TYPE "\")\n",
info.type);
- show_boot_progress(-47);
+ bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE);
return 1;
}
- show_boot_progress(47);
+ bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE);
printf("\nLoading from IDE device %d, partition %d: "
"Name: %.32s Type: %.32s\n", dev, part, info.name, info.type);
if (ide_dev_desc[dev].
block_read(dev, info.start, 1, (ulong *) addr) != 1) {
printf("** Read error on %d:%d\n", dev, part);
- show_boot_progress(-48);
+ bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
return 1;
}
- show_boot_progress(48);
+ bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);
switch (genimg_get_format((void *) addr)) {
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *) addr;
- show_boot_progress(49);
+ bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);
if (!image_check_hcrc(hdr)) {
puts("\n** Bad Header Checksum **\n");
- show_boot_progress(-50);
+ bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM);
return 1;
}
- show_boot_progress(50);
+ bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM);
image_print_contents(hdr);
break;
#endif
default:
- show_boot_progress(-49);
+ bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
puts("** Unknown image type\n");
return 1;
}
if (ide_dev_desc[dev].block_read(dev, info.start + 1, cnt,
(ulong *)(addr + info.blksz)) != cnt) {
printf("** Read error on %d:%d\n", dev, part);
- show_boot_progress(-51);
+ bootstage_error(BOOTSTAGE_ID_IDE_READ);
return 1;
}
- show_boot_progress(51);
+ bootstage_mark(BOOTSTAGE_ID_IDE_READ);
#if defined(CONFIG_FIT)
/* This cannot be done earlier, we need complete FIT image in RAM first */
if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
if (!fit_check_format(fit_hdr)) {
- show_boot_progress(-140);
+ bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
puts("** Bad FIT image format\n");
return 1;
}
- show_boot_progress(141);
+ bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
fit_print_contents(fit_hdr);
}
#endif
{
if (argc != 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* on */
if (strncmp(argv[1], "on", 2) == 0)
/* Validate arguments */
if ((argc != 4))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for a data width specification.
* Defaults to long (4) if no specification.
/* Validate arguments */
if ((argc != 3)) {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
cmd = get_led_cmd(argv[2]);
if (cmd < 0) {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
for (i = 0; led_commands[i].string; i++) {
/* If we ran out of matches, print Usage */
if (!match) {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
if (strcmp(argv[1], "on") == 0)
hwflow_onoff(1);
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
printf("RTS/CTS hardware flow control: %s\n", hwflow_onoff(0) ? "on" : "off");
return 0;
DECLARE_GLOBAL_DATA_PTR;
/* Local prototypes */
-static void logbuff_putc (const char c);
-static void logbuff_puts (const char *s);
+static void logbuff_putc(const char c);
+static void logbuff_puts(const char *s);
static int logbuff_printk(const char *line);
static char buf[1024];
{
return CONFIG_SYS_SDRAM_BASE + gd->ram_size - LOGBUFF_LEN;
}
-unsigned long logbuffer_base (void) __attribute__((weak, alias("__logbuffer_base")));
+unsigned long logbuffer_base(void)
+__attribute__((weak, alias("__logbuffer_base")));
-void logbuff_init_ptrs (void)
+void logbuff_init_ptrs(void)
{
unsigned long tag, post_word;
char *s;
log = (logbuff_t *)CONFIG_ALT_LH_ADDR;
lbuf = (char *)CONFIG_ALT_LB_ADDR;
#else
- log = (logbuff_t *)(logbuffer_base ()) - 1;
+ log = (logbuff_t *)(logbuffer_base()) - 1;
lbuf = (char *)log->buf;
#endif
/* Set up log version */
if ((s = getenv ("logversion")) != NULL)
- log_version = (int)simple_strtoul (s, NULL, 10);
+ log_version = (int)simple_strtoul(s, NULL, 10);
if (log_version == 2)
tag = log->v2.tag;
post_word = post_word_load();
#ifdef CONFIG_POST
/* The post routines have setup the word so we can simply test it */
- if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) {
- logbuff_reset ();
- }
+ if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT))
+ logbuff_reset();
#else
/* No post routines, so we do our own checking */
if (tag != LOGBUFF_MAGIC || post_word != LOGBUFF_MAGIC) {
/* Initialize default loglevel if present */
if ((s = getenv ("loglevel")) != NULL)
- console_loglevel = (int)simple_strtoul (s, NULL, 10);
+ console_loglevel = (int)simple_strtoul(s, NULL, 10);
gd->flags |= GD_FLG_LOGINIT;
}
-void logbuff_reset (void)
+void logbuff_reset(void)
{
#ifndef CONFIG_ALT_LB_ADDR
- memset (log, 0, sizeof (logbuff_t));
+ memset(log, 0, sizeof(logbuff_t));
#endif
if (log_version == 2) {
log->v2.tag = LOGBUFF_MAGIC;
}
}
-int drv_logbuff_init (void)
+int drv_logbuff_init(void)
{
struct stdio_dev logdev;
int rc;
logdev.putc = logbuff_putc; /* 'putc' function */
logdev.puts = logbuff_puts; /* 'puts' function */
- rc = stdio_register (&logdev);
+ rc = stdio_register(&logdev);
return (rc == 0) ? 1 : rc;
}
-static void logbuff_putc (const char c)
+static void logbuff_putc(const char c)
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
- logbuff_printk (buf);
+ logbuff_printk(buf);
}
-static void logbuff_puts (const char *s)
+static void logbuff_puts(const char *s)
{
logbuff_printk (s);
}
void logbuff_log(char *msg)
{
if ((gd->flags & GD_FLG_LOGINIT)) {
- logbuff_printk (msg);
+ logbuff_printk(msg);
} else {
- /* Can happen only for pre-relocated errors as logging */
- /* at that stage should be disabled */
+ /*
+ * Can happen only for pre-relocated errors as logging
+ * at that stage should be disabled
+ */
puts (msg);
}
}
* Return: None
*
*/
-int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char *s;
unsigned long i, start, size;
- if (strcmp(argv[1],"append") == 0) {
+ if (strcmp(argv[1], "append") == 0) {
/* Log concatenation of all arguments separated by spaces */
- for (i=2; i<argc; i++) {
- logbuff_printk (argv[i]);
- logbuff_putc ((i<argc-1) ? ' ' : '\n');
+ for (i = 2; i < argc; i++) {
+ logbuff_printk(argv[i]);
+ logbuff_putc((i < argc - 1) ? ' ' : '\n');
}
return 0;
}
switch (argc) {
case 2:
- if (strcmp(argv[1],"show") == 0) {
+ if (strcmp(argv[1], "show") == 0) {
if (log_version == 2) {
start = log->v2.start;
size = log->v2.end - log->v2.start;
- }
- else {
+ } else {
start = log->v1.start;
size = log->v1.size;
}
- for (i=0; i < (size&LOGBUFF_MASK); i++) {
- s = lbuf+((start+i)&LOGBUFF_MASK);
- putc (*s);
+ if (size > LOGBUFF_LEN)
+ size = LOGBUFF_LEN;
+ for (i = 0; i < size; i++) {
+ s = lbuf + ((start + i) & LOGBUFF_MASK);
+ putc(*s);
}
return 0;
- } else if (strcmp(argv[1],"reset") == 0) {
- logbuff_reset ();
+ } else if (strcmp(argv[1], "reset") == 0) {
+ logbuff_reset();
return 0;
- } else if (strcmp(argv[1],"info") == 0) {
- printf ("Logbuffer at %08lx\n", (unsigned long)lbuf);
+ } else if (strcmp(argv[1], "info") == 0) {
+ printf("Logbuffer at %08lx\n", (unsigned long)lbuf);
if (log_version == 2) {
- printf ("log_start = %08lx\n", log->v2.start);
- printf ("log_end = %08lx\n", log->v2.end);
- printf ("logged_chars = %08lx\n", log->v2.chars);
+ printf("log_start = %08lx\n",
+ log->v2.start);
+ printf("log_end = %08lx\n", log->v2.end);
+ printf("log_con = %08lx\n", log->v2.con);
+ printf("logged_chars = %08lx\n",
+ log->v2.chars);
}
else {
- printf ("log_start = %08lx\n", log->v1.start);
- printf ("log_size = %08lx\n", log->v1.size);
- printf ("logged_chars = %08lx\n", log->v1.chars);
+ printf("log_start = %08lx\n",
+ log->v1.start);
+ printf("log_size = %08lx\n",
+ log->v1.size);
+ printf("logged_chars = %08lx\n",
+ log->v1.chars);
}
return 0;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
}
int line_feed;
static signed char msg_level = -1;
- strcpy (buf + 3, line);
- i = strlen (line);
+ strcpy(buf + 3, line);
+ i = strlen(line);
buf_end = buf + 3 + i;
for (p = buf + 3; p < buf_end; p++) {
msg = p;
p[0] = '<';
p[1] = default_message_loglevel + '0';
p[2] = '>';
- } else
+ } else {
msg += 3;
+ }
msg_level = p[1] - '0';
}
line_feed = 0;
if (log->v2.end - log->v2.start > LOGBUFF_LEN)
log->v2.start++;
log->v2.chars++;
- }
- else {
+ } else {
lbuf[(log->v1.start + log->v1.size) &
LOGBUFF_MASK] = *p;
if (log->v1.size < LOGBUFF_LEN)
u8 output[16];
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = simple_strtoul(argv[1], NULL, 16);
len = simple_strtoul(argv[2], NULL, 16);
struct mii_dev *bus;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* We use the last specified parameters, unless new ones are
length = dp_last_length;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/* New command specified. Check for a size specification.
int size;
if ((argc < 3) || (argc > 4))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for size specification.
*/
ulong count;
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
count = simple_strtoul(argv[3], NULL, 10);
ulong count;
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
count = simple_strtoul(argv[3], NULL, 10);
int rcode = 0;
if (argc != 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for size specification.
*/
int size;
if (argc != 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for size specification.
*/
volatile u_char *cp;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for a size spefication.
* Defaults to long if no or incorrect specification.
volatile u_char *cp;
if (argc < 4)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Check for a size spefication.
* Defaults to long if no or incorrect specification.
int nbytes, size;
if (argc != 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#ifdef CONFIG_BOOT_RETRY_TIME
reset_cmd_timeout(); /* got a good command to get here */
ulong *ptr;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = simple_strtoul (argv[1], NULL, 16);
addr += base_address;
if (argc < 3) {
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
av = argv + 1;
unsigned int blocking;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16);
if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) {
puts ("Bad number of FSL\n");
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
switch (fslnum) {
unsigned int blocking;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16);
num = (unsigned int)simple_strtoul (argv[2], NULL, 16);
blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16);
if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
switch (fslnum) {
#if (XILINX_FSL_NUMBER > 0)
unsigned int val = 0;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
reg = (unsigned int)simple_strtoul (argv[1], NULL, 16);
val = (unsigned int)simple_strtoul (argv[2], NULL, 16);
return 1;
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
}
const char *devname;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#if defined(CONFIG_MII_INIT)
mii_init ();
else
miiphy_set_current_dev (argv[2]);
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/*
ulong delay;
if (argc != 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
delay = simple_strtoul(argv[1], NULL, 10) * CONFIG_SYS_HZ;
int dev;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (strcmp(argv[1], "init") == 0) {
if (argc == 2) {
} else if (argc == 3) {
dev = (int)simple_strtoul(argv[2], NULL, 10);
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (mmc_legacy_init(dev) != 0) {
#endif
curr_device = dev;
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
printf("mmc%d is current device\n", curr_device);
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return 0;
enum mmc_state state;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (curr_device < 0) {
if (get_mmc_num() > 0)
return 1;
}
} else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
mmc = find_mmc_device(dev);
if (!mmc) {
return (n == cnt) ? 0 : 1;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
return 0;
usage:
- cmd_usage(cmdtp);
- return 1;
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
unsigned long cpuid;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
cpuid = simple_strtoul(argv[1], NULL, 10);
if (!is_core_valid(cpuid)) {
else if (strncmp(argv[2], "disable", 7) == 0)
return cpu_disable(cpuid);
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
return 0;
}
/* 4 or greater, make sure its release */
if (strncmp(argv[2], "release", 7) != 0)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (cpu_release(cpuid, argc - 3, argv + 3))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
return 0;
}
return spread_partitions();
#endif /* CONFIG_CMD_MTDPARTS_SPREAD */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/***************************************************/
last = off;
- datbuf = malloc(nand->writesize + nand->oobsize);
+ datbuf = malloc(nand->writesize);
oobbuf = malloc(nand->oobsize);
if (!datbuf || !oobbuf) {
puts("No memory for page buffer\n");
struct mtd_oob_ops ops;
memset(&ops, 0, sizeof(ops));
ops.datbuf = datbuf;
- ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */
+ ops.oobbuf = oobbuf;
ops.len = nand->writesize;
ops.ooblen = nand->oobsize;
ops.mode = MTD_OOB_RAW;
}
puts("OOB:\n");
i = nand->oobsize >> 3;
+ p = oobbuf;
while (i--) {
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
return ret;
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
#endif
#endif
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
if (s != NULL &&
(strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
printf("Unknown nand load suffix '%s'\n", s);
- show_boot_progress(-53);
+ bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX);
return 1;
}
r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
if (r) {
puts("** Read error\n");
- show_boot_progress (-56);
+ bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ);
return 1;
}
- show_boot_progress (56);
+ bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ);
switch (genimg_get_format ((void *)addr)) {
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *)addr;
- show_boot_progress (57);
+ bootstage_mark(BOOTSTAGE_ID_NAND_TYPE);
image_print_contents (hdr);
cnt = image_get_image_size (hdr);
break;
#endif
default:
- show_boot_progress (-57);
+ bootstage_error(BOOTSTAGE_ID_NAND_TYPE);
puts ("** Unknown image type\n");
return 1;
}
- show_boot_progress (57);
+ bootstage_mark(BOOTSTAGE_ID_NAND_TYPE);
r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
if (r) {
puts("** Read error\n");
- show_boot_progress (-58);
+ bootstage_error(BOOTSTAGE_ID_NAND_READ);
return 1;
}
- show_boot_progress (58);
+ bootstage_mark(BOOTSTAGE_ID_NAND_READ);
#if defined(CONFIG_FIT)
/* This cannot be done earlier, we need complete FIT image in RAM first */
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
if (!fit_check_format (fit_hdr)) {
- show_boot_progress (-150);
+ bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ);
puts ("** Bad FIT image format\n");
return 1;
}
- show_boot_progress (151);
+ bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK);
fit_print_contents (fit_hdr);
}
#endif
}
#endif
- show_boot_progress(52);
+ bootstage_mark(BOOTSTAGE_ID_NAND_PART);
switch (argc) {
case 1:
addr = CONFIG_SYS_LOAD_ADDR;
#if defined(CONFIG_CMD_MTDPARTS)
usage:
#endif
- show_boot_progress(-53);
- return cmd_usage(cmdtp);
+ bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX);
+ return CMD_RET_USAGE;
}
+ bootstage_mark(BOOTSTAGE_ID_NAND_SUFFIX);
- show_boot_progress(53);
if (!boot_device) {
puts("\n** No boot device **\n");
- show_boot_progress(-54);
+ bootstage_error(BOOTSTAGE_ID_NAND_BOOT_DEVICE);
return 1;
}
- show_boot_progress(54);
+ bootstage_mark(BOOTSTAGE_ID_NAND_BOOT_DEVICE);
idx = simple_strtoul(boot_device, NULL, 16);
if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) {
printf("\n** Device %d not available\n", idx);
- show_boot_progress(-55);
+ bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE);
return 1;
}
- show_boot_progress(55);
+ bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE);
return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
}
int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- return netboot_common(TFTPGET, cmdtp, argc, argv);
+ int ret;
+
+ bootstage_mark_name(BOOTSTAGE_KERNELREAD_START, "tftp_start");
+ ret = netboot_common(TFTPGET, cmdtp, argc, argv);
+ bootstage_mark_name(BOOTSTAGE_KERNELREAD_STOP, "tftp_done");
+ return ret;
}
U_BOOT_CMD(
break;
#endif
default:
- show_boot_progress (-80);
- return cmd_usage(cmdtp);
+ bootstage_error(BOOTSTAGE_ID_NET_START);
+ return CMD_RET_USAGE;
}
+ bootstage_mark(BOOTSTAGE_ID_NET_START);
- show_boot_progress (80);
if ((size = NetLoop(proto)) < 0) {
- show_boot_progress (-81);
+ bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
return 1;
}
+ bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
- show_boot_progress (81);
/* NetLoop ok, update environment */
netboot_update_env();
/* done if no file was loaded (no errors though) */
if (size == 0) {
- show_boot_progress (-82);
+ bootstage_error(BOOTSTAGE_ID_NET_LOADED);
return 0;
}
/* flush cache */
flush_cache(load_addr, size);
- show_boot_progress(82);
+ bootstage_mark(BOOTSTAGE_ID_NET_LOADED);
+
rcode = bootm_maybe_autostart(cmdtp, argv[0]);
if (rcode < 0)
- show_boot_progress (-83);
+ bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
else
- show_boot_progress (84);
+ bootstage_mark(BOOTSTAGE_ID_NET_DONE);
return rcode;
}
NetPingIP = string_to_ip(argv[1]);
if (NetPingIP == 0)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (NetLoop(PING) < 0) {
printf("ping failed; host %s is not alive\n", argv[1]);
int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc == 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* We should check for a valid hostname:
!defined(CONFIG_ENV_IS_IN_DATAFLASH) && \
!defined(CONFIG_ENV_IS_IN_MG_DISK) && \
!defined(CONFIG_ENV_IS_IN_MMC) && \
+ !defined(CONFIG_ENV_IS_IN_FAT) && \
!defined(CONFIG_ENV_IS_IN_NAND) && \
!defined(CONFIG_ENV_IS_IN_NVRAM) && \
!defined(CONFIG_ENV_IS_IN_ONENAND) && \
!defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
!defined(CONFIG_ENV_IS_NOWHERE)
# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
-SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE
+SPI_FLASH|MG_DISK|NVRAM|MMC|FAT} or CONFIG_ENV_IS_NOWHERE
#endif
#define XMK_STR(x) #x
int rcode = 1, arg = 1, idx;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
memset(matched, 0, env_htab.size / 8);
int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
return _do_env_set(flag, argc, argv);
}
/* Check the syntax */
switch (argc) {
case 1:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 2: /* env_ask envname */
sprintf(message, "Please enter '%s':", argv[1]);
char *init_val;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* Set read buffer to initial value or empty sting */
init_val = getenv(argv[1]);
int argc, char * const argv[])
{
if (argc != 2 || strcmp(argv[1], "-f") != 0)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
set_default_env("## Resetting to default environment\n");
return 0;
sep = '\n';
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
}
NXTARG: ;
}
if (argc < 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = (char *)simple_strtoul(argv[0], NULL, 16);
del = 1;
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
}
}
if (argc < 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (!fmt)
printf("## Warning: defaulting to text format\n");
cmd_tbl_t *cp;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* drop initial "env" arg */
argc--;
if (cp)
return cp->cmd(cmdtp, flag, argc, argv);
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
size_t retlen = 0;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
s = strchr(argv[0], '.');
if ((s != NULL) && (!strcmp(s, ".oob")))
size_t retlen = 0;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (strncmp(argv[0] + 6, "yaffs", 5) == 0)
withoob = 1;
char *s;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
s = strchr(argv[0], '.');
ofs = (int)simple_strtoul(argv[1], NULL, 16);
argv += 2;
if (argc <= 0)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
while (argc > 0) {
addr = simple_strtoul(*argv, NULL, 16);
cmd_tbl_t *c;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
mtd = &onenand_mtd;
if (c)
return c->cmd(cmdtp, flag, argc, argv);
else
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
if (argc < 4) {
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
prompt_user = false;
return 1;
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/***************************************************/
uint value = out_last_value;
if (argc != 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/*
uint size = in_last_size;
if (argc != 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
/*
do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char *pxefile_addr_str;
- void *pxefile_addr_r;
+ unsigned long pxefile_addr_r;
int err;
if (argc != 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
pxefile_addr_str = from_env("pxefile_addr_r");
* Keep trying paths until we successfully get a file we're looking
* for.
*/
- if (pxe_uuid_path(pxefile_addr_r) > 0
- || pxe_mac_path(pxefile_addr_r) > 0
- || pxe_ipaddr_paths(pxefile_addr_r) > 0
- || get_pxelinux_path("default", pxefile_addr_r) > 0) {
+ if (pxe_uuid_path((void *)pxefile_addr_r) > 0
+ || pxe_mac_path((void *)pxefile_addr_r) > 0
+ || pxe_ipaddr_paths((void *)pxefile_addr_r) > 0
+ || get_pxelinux_path("default", (void *)pxefile_addr_r) > 0) {
printf("Config file found\n");
*/
static int get_relfile_envaddr(char *file_path, char *envaddr_name)
{
- void *file_addr;
+ unsigned long file_addr;
char *envaddr;
envaddr = from_env(envaddr_name);
if (!envaddr)
return -ENOENT;
- if (strict_strtoul(envaddr, 16, (unsigned long *)&file_addr) < 0)
+ if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL;
- return get_relfile(file_path, file_addr);
+ return get_relfile(file_path, (void *)file_addr);
}
/*
printf("running: %s\n", dupcmd);
- ret = run_command2(dupcmd, 0);
+ ret = run_command(dupcmd, 0);
free(dupcmd);
} else if (argc == 2) {
pxefile_addr_str = argv[1];
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
cmd_tbl_t *cp;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/* drop initial "pxe" arg */
argc--;
if (cp)
return cp->cmd(cmdtp, flag, argc, argv);
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
int part_length;
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc = get_dev(argv[1],dev);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (!filename) {
switch (argc) {
case 0:
case 1:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1],"inf", 3) == 0) {
int i;
}
return rc;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
}
return rc;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
default: /* at least 4 args */
if (strcmp(argv[1], "read") == 0) {
n, (n == cnt) ? "OK" : "ERROR");
return (n == cnt) ? 0 : 1;
} else {
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
return rc;
boot_device = argv[2];
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (!boot_device) {
int do_scsi (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
switch (argc) {
- case 0:
- case 1: return cmd_usage(cmdtp);
+ case 0:
+ case 1:
+ return CMD_RET_USAGE;
- case 2:
+ case 2:
if (strncmp(argv[1],"res",3) == 0) {
printf("\nReset SCSI\n");
scsi_bus_reset();
printf("\nno SCSI devices available\n");
return 1;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
case 3:
if (strncmp(argv[1],"dev",3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
}
return 1;
}
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
default:
/* at least 4 args */
if (strcmp(argv[1],"read") == 0) {
return 0;
}
} /* switch */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
/****************************************************************************************
/* Validate arguments */
if ((argc != 5) || (strlen(argv[3]) != 1))
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
w = cmd_get_data_size(argv[0], 4);
return ret;
usage:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
U_BOOT_CMD(
u8 output[20];
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = simple_strtoul(argv[1], NULL, 16);
len = simple_strtoul(argv[2], NULL, 16);
if (*line) {
debug ("** exec: \"%s\"\n",
line);
- if (run_command (line, 0) < 0) {
+ if (run_command(line, 0) < 0) {
rcode = 1;
break;
}
--- /dev/null
+/*
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.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
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cmd_spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char **subcmd_list[] = {
+
+ [SPL_EXPORT_FDT] = (const char * []) {
+#ifdef CONFIG_OF_LIBFDT
+ "start",
+ "loados",
+ #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+ "ramdisk",
+ #endif
+ "fdt",
+ "cmdline",
+ "bdt",
+ "prep",
+#endif
+ NULL,
+ },
+ [SPL_EXPORT_ATAGS] = (const char * []) {
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+ defined(CONFIG_CMDLINE_TAG) || \
+ defined(CONFIG_INITRD_TAG) || \
+ defined(CONFIG_SERIAL_TAG) || \
+ defined(CONFIG_REVISION_TAG)
+ "start",
+ "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+ "ramdisk",
+#endif
+ "cmdline",
+ "bdt",
+ "prep",
+#endif
+ NULL,
+ },
+ NULL
+};
+
+/* Calls bootm with the parameters given */
+static int call_bootm(int argc, char * const argv[], const char *subcommand[])
+{
+ char *bootm_argv[5];
+
+ int i = 0;
+ int ret = 0;
+ int j;
+
+ /* create paramter array */
+ bootm_argv[0] = "do_bootm";
+ switch (argc) {
+ case 3:
+ bootm_argv[4] = argv[2]; /* fdt addr */
+ case 2:
+ bootm_argv[3] = argv[1]; /* initrd addr */
+ case 1:
+ bootm_argv[2] = argv[0]; /* kernel addr */
+ }
+
+
+ /*
+ * - do the work -
+ * exec subcommands of do_bootm to init the images
+ * data structure
+ */
+ while (subcommand[i] != NULL) {
+ bootm_argv[1] = (char *)subcommand[i];
+ debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]);
+ for (j = 0; j < argc; j++)
+ debug("%s ", bootm_argv[j + 2]);
+ debug("\n");
+
+ ret = do_bootm(find_cmd("do_bootm"), 0, argc+2,
+ bootm_argv);
+ debug("Subcommand retcode: %d\n", ret);
+ i++;
+ }
+
+ if (ret) {
+ printf("ERROR prep subcommand failed!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static cmd_tbl_t cmd_spl_export_sub[] = {
+ U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""),
+ U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""),
+};
+
+static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ const cmd_tbl_t *c;
+
+ if (argc < 2) /* no subcommand */
+ return cmd_usage(cmdtp);
+
+ c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0],
+ ARRAY_SIZE(cmd_spl_export_sub));
+ if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) {
+ argc -= 2;
+ argv += 2;
+ if (call_bootm(argc, argv, subcmd_list[(int)c->cmd]))
+ return -1;
+ switch ((int)c->cmd) {
+ case SPL_EXPORT_FDT:
+ printf("Argument image is now in RAM: 0x%p\n",
+ (void *)images.ft_addr);
+ break;
+ case SPL_EXPORT_ATAGS:
+ printf("Argument image is now in RAM at: 0x%p\n",
+ (void *)gd->bd->bi_boot_params);
+ break;
+ }
+ } else {
+ /* Unrecognized command */
+ return cmd_usage(cmdtp);
+ }
+
+ return 0;
+}
+
+static cmd_tbl_t cmd_spl_sub[] = {
+ U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""),
+};
+
+static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ const cmd_tbl_t *c;
+ int cmd;
+
+ if (argc < 2) /* no subcommand */
+ return cmd_usage(cmdtp);
+
+ c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub));
+ if (c) {
+ cmd = (int)c->cmd;
+ switch (cmd) {
+ case SPL_EXPORT:
+ argc--;
+ argv++;
+ if (spl_export(cmdtp, flag, argc, argv))
+ printf("Subcommand failed\n");
+ break;
+ default:
+ /* unrecognized command */
+ return cmd_usage(cmdtp);
+ }
+ } else {
+ /* Unrecognized command */
+ return cmd_usage(cmdtp);
+ }
+ return 0;
+}
+
+U_BOOT_CMD(
+ spl, 6 , 1, do_spl, "SPL configuration",
+ "export <img=atags|fdt> [kernel_addr] [initrd_addr] "
+ "[fdt_addr if <img> = fdt] - export a kernel parameter image\n"
+ "\t initrd_img can be set to \"-\" if fdt_addr without initrd img is"
+ "used");
int do_strings(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc == 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((flag & CMD_FLAG_REPEAT) == 0) {
start_addr = (char *)simple_strtoul(argv[1], NULL, 16);
return 1;
}
if (argc > cmdtp->maxargs)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
/*
* TODO(clchiou): get_timer_masked() is only defined in certain ARM
int retval = 0;
if (argc == 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
retval = run_command_and_time_it(0, argc - 1, argv + 1, &cycles);
report_time(cycles);
int err = 0;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (mtdparts_init() != 0) {
printf("Error initializing mtdparts!\n");
}
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
#ifdef CONFIG_CMD_UBIFS
/*
int ret;
if (argc != 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
vol_name = argv[1];
debug("Using volume %s\n", vol_name);
int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc != 1)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if (ubifs_initialized == 0) {
printf("No UBIFS volume mounted!\n");
}
if (argc < 3)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
addr = simple_strtoul(argv[1], &endp, 16);
if (endp == argv[1])
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
filename = argv[2];
if (argc == 4) {
size = simple_strtoul(argv[3], &endp, 16);
if (endp == argv[3])
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
debug("Loading file '%s' to address 0x%08x (size %d)\n", filename, addr, size);
dst = simple_strtoul(argv[2], NULL, 16);
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (gunzip((void *) dst, dst_len, (void *) src, &src_len) != 0)
boot_device = argv[2];
break;
default:
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
if (!boot_device) {
#endif
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
if ((strncmp(argv[1], "reset", 5) == 0) ||
(strncmp(argv[1], "start", 5) == 0)) {
+ bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
usb_stop();
printf("(Re)start USB...\n");
i = usb_init();
return 0;
}
#endif /* CONFIG_USB_STORAGE */
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
#ifdef CONFIG_USB_STORAGE
}
}
#endif
+
+/**
+ * Call a command function. This should be the only route in U-Boot to call
+ * a command, so that we can track whether we are waiting for input or
+ * executing a command.
+ *
+ * @param cmdtp Pointer to the command to execute
+ * @param flag Some flags normally 0 (see CMD_FLAG_.. above)
+ * @param argc Number of arguments (arg 0 must be the command text)
+ * @param argv Arguments
+ * @return 0 if command succeeded, else non-zero (CMD_RET_...)
+ */
+static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int result;
+
+ result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
+ if (result)
+ debug("Command failed, result=%d", result);
+ return result;
+}
+
+enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
+ int *repeatable)
+{
+ enum command_ret_t rc = CMD_RET_SUCCESS;
+ cmd_tbl_t *cmdtp;
+
+ /* Look up command in command table */
+ cmdtp = find_cmd(argv[0]);
+ if (cmdtp == NULL) {
+ printf("Unknown command '%s' - try 'help'\n", argv[0]);
+ return 1;
+ }
+
+ /* found - check max args */
+ if (argc > cmdtp->maxargs)
+ rc = CMD_RET_USAGE;
+
+#if defined(CONFIG_CMD_BOOTD)
+ /* avoid "bootd" recursion */
+ else if (cmdtp->cmd == do_bootd) {
+ if (flag & CMD_FLAG_BOOTD) {
+ puts("'bootd' recursion detected\n");
+ rc = CMD_RET_FAILURE;
+ } else {
+ flag |= CMD_FLAG_BOOTD;
+ }
+ }
+#endif
+
+ /* If OK so far, then do the command */
+ if (!rc) {
+ rc = cmd_call(cmdtp, flag, argc, argv);
+ *repeatable &= cmdtp->repeatable;
+ }
+ if (rc == CMD_RET_USAGE)
+ rc = cmd_usage(cmdtp);
+ return rc;
+}
return serial_tstc();
}
-#if defined(CONFIG_PRE_CONSOLE_BUFFER) || defined(CONFIG_PRE_CONSOLE_PUTC)
+#ifdef CONFIG_PRE_CONSOLE_BUFFER
#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
static void pre_console_putc(const char c)
{
-#ifdef CONFIG_PRE_CONSOLE_BUFFER
char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
buffer[CIRC_BUF_IDX(gd->precon_buf_idx++)] = c;
-#endif
-#ifdef CONFIG_PRE_CONSOLE_PUTC
- board_pre_console_putc(c);
-#endif
}
static void pre_console_puts(const char *s)
static void print_pre_console_buffer(void)
{
-#ifdef CONFIG_PRE_CONSOLE_BUFFER
unsigned long i = 0;
char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
while (i < gd->precon_buf_idx)
putc(buffer[CIRC_BUF_IDX(i++)]);
-#endif
}
-
#else
static inline void pre_console_putc(const char c) {}
static inline void pre_console_puts(const char *s) {}
#if defined(CONFIG_ENV_IS_NOWHERE) /* Environment not changable */
set_default_env(NULL);
#else
- show_boot_progress(-60);
+ bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
set_default_env("!bad CRC");
#endif
} else {
--- /dev/null
+/*
+ * (c) Copyright 2011 by Tigris Elektronik GmbH
+ *
+ * Author:
+ * Maximilian Schwerin <mvs@tigris.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
+ */
+
+#include <common.h>
+
+#include <command.h>
+#include <environment.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+#include <search.h>
+#include <errno.h>
+#include <fat.h>
+#include <mmc.h>
+
+char *env_name_spec = "FAT";
+
+env_t *env_ptr;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+uchar env_get_char_spec(int index)
+{
+ return *((uchar *)(gd->env_addr + index));
+}
+
+int env_init(void)
+{
+ /* use default */
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = 1;
+
+ return 0;
+}
+
+#ifdef CONFIG_CMD_SAVEENV
+int saveenv(void)
+{
+ env_t env_new;
+ ssize_t len;
+ char *res;
+ block_dev_desc_t *dev_desc = NULL;
+ int dev = FAT_ENV_DEVICE;
+ int part = FAT_ENV_PART;
+
+ res = (char *)&env_new.data;
+ len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL);
+ if (len < 0) {
+ error("Cannot export environment: errno = %d\n", errno);
+ return 1;
+ }
+
+#ifdef CONFIG_MMC
+ if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) {
+ struct mmc *mmc = find_mmc_device(dev);
+
+ if (!mmc) {
+ printf("no mmc device at slot %x\n", dev);
+ return 1;
+ }
+
+ mmc->has_init = 0;
+ mmc_init(mmc);
+ }
+#endif /* CONFIG_MMC */
+
+ dev_desc = get_dev(FAT_ENV_INTERFACE, dev);
+ if (dev_desc == NULL) {
+ printf("Failed to find %s%d\n",
+ FAT_ENV_INTERFACE, dev);
+ return 1;
+ }
+ if (fat_register_device(dev_desc, part) != 0) {
+ printf("Failed to register %s%d:%d\n",
+ FAT_ENV_INTERFACE, dev, part);
+ return 1;
+ }
+
+ env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) {
+ printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
+ FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
+ return 1;
+ }
+
+ puts("done\n");
+ return 0;
+}
+#endif /* CONFIG_CMD_SAVEENV */
+
+void env_relocate_spec(void)
+{
+ char buf[CONFIG_ENV_SIZE];
+ block_dev_desc_t *dev_desc = NULL;
+ int dev = FAT_ENV_DEVICE;
+ int part = FAT_ENV_PART;
+
+#ifdef CONFIG_MMC
+ if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) {
+ struct mmc *mmc = find_mmc_device(dev);
+
+ if (!mmc) {
+ printf("no mmc device at slot %x\n", dev);
+ set_default_env(NULL);
+ return;
+ }
+
+ mmc->has_init = 0;
+ mmc_init(mmc);
+ }
+#endif /* CONFIG_MMC */
+
+ dev_desc = get_dev(FAT_ENV_INTERFACE, dev);
+ if (dev_desc == NULL) {
+ printf("Failed to find %s%d\n",
+ FAT_ENV_INTERFACE, dev);
+ set_default_env(NULL);
+ return;
+ }
+ if (fat_register_device(dev_desc, part) != 0) {
+ printf("Failed to register %s%d:%d\n",
+ FAT_ENV_INTERFACE, dev, part);
+ set_default_env(NULL);
+ return;
+ }
+
+ if (file_fat_read(FAT_ENV_FILE, (unsigned char *)&buf, CONFIG_ENV_SIZE) == -1) {
+ printf("\n** Unable to read \"%s\" from %s%d:%d **\n",
+ FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
+ set_default_env(NULL);
+ return;
+ }
+
+ env_import(buf, 1);
+}
int nextin;
int flag = do_repeat ? CMD_FLAG_REPEAT : 0;
struct child_prog *child;
- cmd_tbl_t *cmdtp;
char *p;
# if __GNUC__
/* Avoid longjmp clobbering */
* Is it really safe for inline use? Experimentally,
* things seem to work with glibc. */
setup_redirects(child, squirrel);
-#else
- /* check ";", because ,example , argv consist from
- * "help;flinfo" must not execute
- */
- if (strchr(child->argv[i], ';')) {
- printf ("Unknown command '%s' - try 'help' or use 'run' command\n",
- child->argv[i]);
- return -1;
- }
- /* Look up command in command table */
-
- if ((cmdtp = find_cmd(child->argv[i])) == NULL) {
- printf ("Unknown command '%s' - try 'help'\n", child->argv[i]);
- return -1; /* give up after bad command */
- } else {
- int rcode;
-#if defined(CONFIG_CMD_BOOTD)
- /* avoid "bootd" recursion */
- if (cmdtp->cmd == do_bootd) {
- if (flag & CMD_FLAG_BOOTD) {
- printf ("'bootd' recursion detected\n");
- return -1;
- }
- else
- flag |= CMD_FLAG_BOOTD;
- }
-#endif
- /* found - check max args */
- if ((child->argc - i) > cmdtp->maxargs)
- return cmd_usage(cmdtp);
-#endif
- child->argv+=i; /* XXX horrible hack */
-#ifndef __U_BOOT__
+ child->argv += i; /* XXX horrible hack */
rcode = x->function(child);
-#else
- /* OK - call function to do the command */
-
- rcode = (cmdtp->cmd)
-(cmdtp, flag,child->argc-i,&child->argv[i]);
- if ( !cmdtp->repeatable )
- flag_repeat = 0;
-
-
-#endif
- child->argv-=i; /* XXX restore hack so free() can work right */
-#ifndef __U_BOOT__
-
+ /* XXX restore hack so free() can work right */
+ child->argv -= i;
restore_redirects(squirrel);
-#endif
-
- return rcode;
}
+ return rcode;
}
-#ifndef __U_BOOT__
+#else
+ /* check ";", because ,example , argv consist from
+ * "help;flinfo" must not execute
+ */
+ if (strchr(child->argv[i], ';')) {
+ printf("Unknown command '%s' - try 'help' or use "
+ "'run' command\n", child->argv[i]);
+ return -1;
+ }
+ /* Process the command */
+ return cmd_process(flag, child->argc, child->argv,
+ &flag_repeat);
+#endif
}
+#ifndef __U_BOOT__
for (i = 0; i < pi->num_progs; i++) {
child = & (pi->progs[i]);
if (!image_check_magic(rd_hdr)) {
puts("Bad Magic Number\n");
- show_boot_progress(-10);
+ bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
return NULL;
}
if (!image_check_hcrc(rd_hdr)) {
puts("Bad Header Checksum\n");
- show_boot_progress(-11);
+ bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
return NULL;
}
- show_boot_progress(10);
+ bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
image_print_contents(rd_hdr);
if (verify) {
puts(" Verifying Checksum ... ");
if (!image_check_dcrc(rd_hdr)) {
puts("Bad Data CRC\n");
- show_boot_progress(-12);
+ bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
return NULL;
}
puts("OK\n");
}
- show_boot_progress(11);
+ bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
!image_check_arch(rd_hdr, arch) ||
!image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
printf("No Linux %s Ramdisk Image\n",
genimg_get_arch_name(arch));
- show_boot_progress(-13);
+ bootstage_error(BOOTSTAGE_ID_RAMDISK);
return NULL;
}
ulong rd_addr, rd_load;
ulong rd_data, rd_len;
const image_header_t *rd_hdr;
+#ifdef CONFIG_SUPPORT_RAW_INITRD
+ char *end;
+#endif
#if defined(CONFIG_FIT)
void *fit_hdr;
const char *fit_uname_config = NULL;
printf("## Loading init Ramdisk from Legacy "
"Image at %08lx ...\n", rd_addr);
- show_boot_progress(9);
+ bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
rd_hdr = image_get_ramdisk(rd_addr, arch,
images->verify);
printf("## Loading init Ramdisk from FIT "
"Image at %08lx ...\n", rd_addr);
- show_boot_progress(120);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT);
if (!fit_check_format(fit_hdr)) {
puts("Bad FIT ramdisk image format!\n");
- show_boot_progress(-120);
+ bootstage_error(
+ BOOTSTAGE_ID_FIT_RD_FORMAT);
return 1;
}
- show_boot_progress(121);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK);
if (!fit_uname_ramdisk) {
/*
* node first. If config unit node name is NULL
* fit_conf_get_node() will try to find default config node
*/
- show_boot_progress(122);
+ bootstage_mark(
+ BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
cfg_noffset = fit_conf_get_node(fit_hdr,
fit_uname_config);
if (cfg_noffset < 0) {
puts("Could not find configuration "
"node\n");
- show_boot_progress(-122);
+ bootstage_error(
+ BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
return 1;
}
fit_uname_config = fdt_get_name(fit_hdr,
rd_noffset, NULL);
} else {
/* get ramdisk component image node offset */
- show_boot_progress(123);
+ bootstage_mark(
+ BOOTSTAGE_ID_FIT_RD_UNIT_NAME);
rd_noffset = fit_image_get_node(fit_hdr,
fit_uname_ramdisk);
}
if (rd_noffset < 0) {
puts("Could not find subimage node\n");
- show_boot_progress(-124);
+ bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE);
return 1;
}
printf(" Trying '%s' ramdisk subimage\n",
fit_uname_ramdisk);
- show_boot_progress(125);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK);
if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch,
images->verify))
return 1;
if (fit_image_get_data(fit_hdr, rd_noffset, &data,
&size)) {
puts("Could not find ramdisk subimage data!\n");
- show_boot_progress(-127);
+ bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA);
return 1;
}
- show_boot_progress(128);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK);
rd_data = (ulong)data;
rd_len = size;
if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) {
puts("Can't get ramdisk subimage load "
"address!\n");
- show_boot_progress(-129);
+ bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD);
return 1;
}
- show_boot_progress(129);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD);
images->fit_hdr_rd = fit_hdr;
images->fit_uname_rd = fit_uname_ramdisk;
break;
#endif
default:
- puts("Wrong Ramdisk Image Format\n");
- rd_data = rd_len = rd_load = 0;
- return 1;
+#ifdef CONFIG_SUPPORT_RAW_INITRD
+ if (argc >= 3 && (end = strchr(argv[2], ':'))) {
+ rd_len = simple_strtoul(++end, NULL, 16);
+ rd_data = rd_addr;
+ } else
+#endif
+ {
+ puts("Wrong Ramdisk Image Format\n");
+ rd_data = rd_len = rd_load = 0;
+ return 1;
+ }
}
} else if (images->legacy_hdr_valid &&
image_check_type(&images->legacy_hdr_os_copy,
* Now check if we have a legacy mult-component image,
* get second entry data start address and len.
*/
- show_boot_progress(13);
+ bootstage_mark(BOOTSTAGE_ID_RAMDISK);
printf("## Loading init Ramdisk from multi component "
"Legacy Image at %08lx ...\n",
(ulong)images->legacy_hdr_os);
/*
* no initrd image
*/
- show_boot_progress(14);
+ bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
rd_len = rd_data = 0;
}
puts("ramdisk - allocation error\n");
goto error;
}
- show_boot_progress(12);
+ bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);
*initrd_end = *initrd_start + rd_len;
printf(" Loading Ramdisk to %08lx, end %08lx ... ",
if (((ulong) desired_addr) == ~0UL) {
/* All ones means use fdt in place */
- desired_addr = fdt_blob;
+ of_start = fdt_blob;
+ lmb_reserve(lmb, (ulong)of_start, of_len);
disable_relocation = 1;
- }
- if (desired_addr) {
+ } else if (desired_addr) {
of_start =
(void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000,
- ((ulong)
- desired_addr)
- + of_len);
- if (desired_addr && of_start != desired_addr) {
+ (ulong)desired_addr);
+ if (of_start == 0) {
puts("Failed using fdt_high value for Device Tree");
goto error;
}
const image_header_t *fdt_hdr;
ulong fdt_addr;
char *fdt_blob = NULL;
- ulong image_start, image_end;
+ ulong image_start, image_data, image_end;
ulong load_start, load_end;
#if defined(CONFIG_FIT)
void *fit_hdr;
* make sure we don't overwrite initial image
*/
image_start = (ulong)fdt_hdr;
+ image_data = (ulong)image_get_data(fdt_hdr);
image_end = image_get_image_end(fdt_hdr);
load_start = image_get_load(fdt_hdr);
load_end = load_start + image_get_data_size(fdt_hdr);
+ if (load_start == image_start ||
+ load_start == image_data) {
+ fdt_blob = (char *)image_data;
+ break;
+ }
+
if ((load_start < image_end) && (load_end > image_start)) {
fdt_error("fdt overwritten");
goto error;
}
debug(" Loading FDT from 0x%08lx to 0x%08lx\n",
- image_get_data(fdt_hdr), load_start);
+ image_data, load_start);
memmove((void *)load_start,
- (void *)image_get_data(fdt_hdr),
+ (void *)image_data,
image_get_data_size(fdt_hdr));
fdt_blob = (char *)load_start;
puts(" Verifying Hash Integrity ... ");
if (!fit_image_check_hashes(fit, rd_noffset)) {
puts("Bad Data Hash\n");
- show_boot_progress(-125);
+ bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH);
return 0;
}
puts("OK\n");
}
- show_boot_progress(126);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) ||
!fit_image_check_arch(fit, rd_noffset, arch) ||
!fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) {
printf("No Linux %s Ramdisk Image\n",
genimg_get_arch_name(arch));
- show_boot_progress(-126);
+ bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
return 0;
}
- show_boot_progress(127);
+ bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK);
return 1;
}
#endif /* USE_HOSTCC */
# endif /* CONFIG_AUTOBOOT_KEYED */
#endif /* CONFIG_BOOTDELAY >= 0 */
-/*
- * Return 0 on success, or != 0 on error.
- */
-#ifndef CONFIG_CMD_PXE
-static inline
-#endif
-int run_command2(const char *cmd, int flag)
-{
-#ifndef CONFIG_SYS_HUSH_PARSER
- /*
- * run_command can return 0 or 1 for success, so clean up its result.
- */
- if (run_command(cmd, flag) == -1)
- return 1;
-
- return 0;
-#else
- return parse_string_outer(cmd,
- FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
-#endif
-}
-
/****************************************************************************/
void main_loop (void)
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
- run_command2(p, 0);
+ run_command(p, 0);
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
- run_command2(s, 0);
+ run_command(s, 0);
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
if (menukey == CONFIG_MENUKEY) {
s = getenv("menucmd");
if (s)
- run_command2(s, 0);
+ run_command(s, 0);
}
#endif /* CONFIG_MENUKEY */
#endif /* CONFIG_BOOTDELAY */
if (len == -1)
puts ("<INTERRUPT>\n");
else
- rc = run_command (lastcommand, flag);
+ rc = run_command(lastcommand, flag);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
/****************************************************************************/
+#ifndef CONFIG_SYS_HUSH_PARSER
static void process_macros (const char *input, char *output)
{
char c, prev;
* the environment data, which may change magicly when the command we run
* creates or modifies environment variables (like "bootp" does).
*/
-
-int run_command (const char *cmd, int flag)
+static int builtin_run_command(const char *cmd, int flag)
{
- cmd_tbl_t *cmdtp;
char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */
char *token; /* start of token in cmdbuf */
char *sep; /* end of token (separator) in cmdbuf */
continue;
}
- /* Look up command in command table */
- if ((cmdtp = find_cmd(argv[0])) == NULL) {
- printf ("Unknown command '%s' - try 'help'\n", argv[0]);
- rc = -1; /* give up after bad command */
- continue;
- }
-
- /* found - check max args */
- if (argc > cmdtp->maxargs) {
- cmd_usage(cmdtp);
- rc = -1;
- continue;
- }
-
-#if defined(CONFIG_CMD_BOOTD)
- /* avoid "bootd" recursion */
- if (cmdtp->cmd == do_bootd) {
-#ifdef DEBUG_PARSER
- printf ("[%s]\n", finaltoken);
-#endif
- if (flag & CMD_FLAG_BOOTD) {
- puts ("'bootd' recursion detected\n");
- rc = -1;
- continue;
- } else {
- flag |= CMD_FLAG_BOOTD;
- }
- }
-#endif
-
- /* OK - call function to do the command */
- if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
- rc = -1;
- }
-
- repeatable &= cmdtp->repeatable;
+ rc = cmd_process(flag, argc, argv, &repeatable);
/* Did the user stop this? */
if (had_ctrlc ())
return rc ? rc : repeatable;
}
+#endif
+
+/*
+ * Run a command using the selected parser.
+ *
+ * @param cmd Command to run
+ * @param flag Execution flags (CMD_FLAG_...)
+ * @return 0 on success, or != 0 on error.
+ */
+int run_command(const char *cmd, int flag)
+{
+#ifndef CONFIG_SYS_HUSH_PARSER
+ /*
+ * builtin_run_command can return 0 or 1 for success, so clean up
+ * its result.
+ */
+ if (builtin_run_command(cmd, flag) == -1)
+ return 1;
+
+ return 0;
+#else
+ return parse_string_outer(cmd,
+ FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+#endif
+}
/****************************************************************************/
int i;
if (argc < 2)
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
for (i=1; i<argc; ++i) {
char *arg;
return 1;
}
- if (run_command2(arg, flag) != 0)
+ if (run_command(arg, flag) != 0)
return 1;
}
return 0;
static int dev_index;
static int running;
static int asynch_allowed;
-static struct devrequest setup_packet;
char usb_started; /* flag for the started/stopped USB status */
/**********************************************************************
* some forward declerations...
*/
-void usb_scan_devices(void);
-
-int usb_hub_probe(struct usb_device *dev, int ifnum);
-void usb_hub_reset(void);
-static int hub_port_reset(struct usb_device *dev, int port,
- unsigned short *portstat);
-
-/***********************************************************************
- * wait_ms
- */
-
-inline void wait_ms(unsigned long ms)
-{
- while (ms-- > 0)
- udelay(1000);
-}
+static void usb_scan_devices(void);
/***************************************************************************
* Init USB Device
unsigned short value, unsigned short index,
void *data, unsigned short size, int timeout)
{
+ struct devrequest setup_packet;
+
if ((timeout == 0) && (!asynch_allowed)) {
/* request for a asynch control pipe is not allowed */
return -1;
while (timeout--) {
if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
break;
- wait_ms(1);
+ mdelay(1);
}
if (dev->status)
return -1;
while (timeout--) {
if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
break;
- wait_ms(1);
+ mdelay(1);
}
*actual_length = dev->act_len;
if (dev->status == 0)
/*
* set the max packed value of all endpoints in the given configuration
*/
-int usb_set_maxpacket(struct usb_device *dev)
+static int usb_set_maxpacket(struct usb_device *dev)
{
int i, ii;
* Parse the config, located in buffer, and fills the dev->config structure.
* Note that all little/big endian swapping are done automatically.
*/
-int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
+static int usb_parse_config(struct usb_device *dev,
+ unsigned char *buffer, int cfgno)
{
struct usb_descriptor_header *head;
int index, ifno, epno, curr_if_num;
/**********************************************************************
* get_descriptor type
*/
-int usb_get_descriptor(struct usb_device *dev, unsigned char type,
+static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
unsigned char index, void *buf, int size)
{
int res;
* set address of a device to the value in dev->devnum.
* This can only be done by addressing the device via the default address (0)
*/
-int usb_set_address(struct usb_device *dev)
+static int usb_set_address(struct usb_device *dev)
{
int res;
/********************************************************************
* set configuration number to configuration
*/
-int usb_set_configuration(struct usb_device *dev, int configuration)
+static int usb_set_configuration(struct usb_device *dev, int configuration)
{
int res;
USB_PRINTF("set configuration %d\n", configuration);
/********************************************************************
* get string index in buffer
*/
-int usb_get_string(struct usb_device *dev, unsigned short langid,
+static int usb_get_string(struct usb_device *dev, unsigned short langid,
unsigned char index, void *buf, int size)
{
int i;
return 1;
}
- wait_ms(10); /* Let the SET_ADDRESS settle */
+ mdelay(10); /* Let the SET_ADDRESS settle */
tmp = sizeof(dev->descriptor);
}
/* build device Tree */
-void usb_scan_devices(void)
+static void usb_scan_devices(void)
{
int i;
struct usb_device *dev;
USB_PRINTF("scan end\n");
}
-
-/****************************************************************************
- * HUB "Driver"
- * Probes device for being a hub and configurate it
- */
-
-static struct usb_hub_device hub_dev[USB_MAX_HUB];
-static int usb_hub_index;
-
-
-int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
-{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
- USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
-}
-
-int usb_clear_hub_feature(struct usb_device *dev, int feature)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature,
- 0, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
- port, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_set_port_feature(struct usb_device *dev, int port, int feature)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
- port, NULL, 0, USB_CNTL_TIMEOUT);
-}
-
-int usb_get_hub_status(struct usb_device *dev, void *data)
-{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
- data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
-}
-
-int usb_get_port_status(struct usb_device *dev, int port, void *data)
-{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
- data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
-}
-
-
-static void usb_hub_power_on(struct usb_hub_device *hub)
-{
- int i;
- struct usb_device *dev;
-
- dev = hub->pusb_dev;
- /* Enable power to the ports */
- USB_HUB_PRINTF("enabling power on all ports\n");
- for (i = 0; i < dev->maxchild; i++) {
- usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
- USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status);
- wait_ms(hub->desc.bPwrOn2PwrGood * 2);
- }
-}
-
-void usb_hub_reset(void)
-{
- usb_hub_index = 0;
-}
-
-struct usb_hub_device *usb_hub_allocate(void)
-{
- if (usb_hub_index < USB_MAX_HUB)
- return &hub_dev[usb_hub_index++];
-
- printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
- return NULL;
-}
-
-#define MAX_TRIES 5
-
-static inline char *portspeed(int portstatus)
-{
- if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
- return "480 Mb/s";
- else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
- return "1.5 Mb/s";
- else
- return "12 Mb/s";
-}
-
-static int hub_port_reset(struct usb_device *dev, int port,
- unsigned short *portstat)
-{
- int tries;
- struct usb_port_status portsts;
- unsigned short portstatus, portchange;
-
- USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
- for (tries = 0; tries < MAX_TRIES; tries++) {
-
- usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
- wait_ms(200);
-
- if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
- USB_HUB_PRINTF("get_port_status failed status %lX\n",
- dev->status);
- return -1;
- }
- portstatus = le16_to_cpu(portsts.wPortStatus);
- portchange = le16_to_cpu(portsts.wPortChange);
-
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
- portstatus, portchange,
- portspeed(portstatus));
-
- USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \
- " USB_PORT_STAT_ENABLE %d\n",
- (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
- (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
- (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
-
- if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
- !(portstatus & USB_PORT_STAT_CONNECTION))
- return -1;
-
- if (portstatus & USB_PORT_STAT_ENABLE)
- break;
-
- wait_ms(200);
- }
-
- if (tries == MAX_TRIES) {
- USB_HUB_PRINTF("Cannot enable port %i after %i retries, " \
- "disabling port.\n", port + 1, MAX_TRIES);
- USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
- return -1;
- }
-
- usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
- *portstat = portstatus;
- return 0;
-}
-
-
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
-{
- struct usb_device *usb;
- struct usb_port_status portsts;
- unsigned short portstatus;
-
- /* Check status */
- if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
- USB_HUB_PRINTF("get_port_status failed\n");
- return;
- }
-
- portstatus = le16_to_cpu(portsts.wPortStatus);
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
- portstatus,
- le16_to_cpu(portsts.wPortChange),
- portspeed(portstatus));
-
- /* Clear the connection change status */
- usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
-
- /* Disconnect any existing devices under this port */
- if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
- (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
- USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n");
- /* Return now if nothing is connected */
- if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return;
- }
- wait_ms(200);
-
- /* Reset the port */
- if (hub_port_reset(dev, port, &portstatus) < 0) {
- printf("cannot reset port %i!?\n", port + 1);
- return;
- }
-
- wait_ms(200);
-
- /* Allocate a new device struct for it */
- usb = usb_alloc_new_device();
-
- if (portstatus & USB_PORT_STAT_HIGH_SPEED)
- usb->speed = USB_SPEED_HIGH;
- else if (portstatus & USB_PORT_STAT_LOW_SPEED)
- usb->speed = USB_SPEED_LOW;
- else
- usb->speed = USB_SPEED_FULL;
-
- dev->children[port] = usb;
- usb->parent = dev;
- usb->portnr = port + 1;
- /* Run it through the hoops (find a driver, etc) */
- if (usb_new_device(usb)) {
- /* Woops, disable the port */
- USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
- usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
- }
-}
-
-
-int usb_hub_configure(struct usb_device *dev)
-{
- int i;
- unsigned char buffer[USB_BUFSIZ], *bitmap;
- struct usb_hub_descriptor *descriptor;
- struct usb_hub_device *hub;
-#ifdef USB_HUB_DEBUG
- struct usb_hub_status *hubsts;
-#endif
-
- /* "allocate" Hub device */
- hub = usb_hub_allocate();
- if (hub == NULL)
- return -1;
- hub->pusb_dev = dev;
- /* Get the the hub descriptor */
- if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
- USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
- "descriptor, giving up %lX\n", dev->status);
- return -1;
- }
- descriptor = (struct usb_hub_descriptor *)buffer;
-
- /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */
- i = descriptor->bLength;
- if (i > USB_BUFSIZ) {
- USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
- "descriptor - too long: %d\n",
- descriptor->bLength);
- return -1;
- }
-
- if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) {
- USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
- "descriptor 2nd giving up %lX\n", dev->status);
- return -1;
- }
- memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength);
- /* adjust 16bit values */
- hub->desc.wHubCharacteristics =
- le16_to_cpu(descriptor->wHubCharacteristics);
- /* set the bitmap */
- bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
- /* devices not removable by default */
- memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
- bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
- memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
-
- for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
- hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
-
- for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
- hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
-
- dev->maxchild = descriptor->bNbrPorts;
- USB_HUB_PRINTF("%d ports detected\n", dev->maxchild);
-
- switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) {
- case 0x00:
- USB_HUB_PRINTF("ganged power switching\n");
- break;
- case 0x01:
- USB_HUB_PRINTF("individual port power switching\n");
- break;
- case 0x02:
- case 0x03:
- USB_HUB_PRINTF("unknown reserved power switching mode\n");
- break;
- }
-
- if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND)
- USB_HUB_PRINTF("part of a compound device\n");
- else
- USB_HUB_PRINTF("standalone hub\n");
-
- switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) {
- case 0x00:
- USB_HUB_PRINTF("global over-current protection\n");
- break;
- case 0x08:
- USB_HUB_PRINTF("individual port over-current protection\n");
- break;
- case 0x10:
- case 0x18:
- USB_HUB_PRINTF("no over-current protection\n");
- break;
- }
-
- USB_HUB_PRINTF("power on to power good time: %dms\n",
- descriptor->bPwrOn2PwrGood * 2);
- USB_HUB_PRINTF("hub controller current requirement: %dmA\n",
- descriptor->bHubContrCurrent);
-
- for (i = 0; i < dev->maxchild; i++)
- USB_HUB_PRINTF("port %d is%s removable\n", i + 1,
- hub->desc.DeviceRemovable[(i + 1) / 8] & \
- (1 << ((i + 1) % 8)) ? " not" : "");
-
- if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
- USB_HUB_PRINTF("usb_hub_configure: failed to get Status - " \
- "too long: %d\n", descriptor->bLength);
- return -1;
- }
-
- if (usb_get_hub_status(dev, buffer) < 0) {
- USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
- dev->status);
- return -1;
- }
-
-#ifdef USB_HUB_DEBUG
- hubsts = (struct usb_hub_status *)buffer;
-#endif
- USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n",
- le16_to_cpu(hubsts->wHubStatus),
- le16_to_cpu(hubsts->wHubChange));
- USB_HUB_PRINTF("local power source is %s\n",
- (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \
- "lost (inactive)" : "good");
- USB_HUB_PRINTF("%sover-current condition exists\n",
- (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
- "" : "no ");
- usb_hub_power_on(hub);
-
- for (i = 0; i < dev->maxchild; i++) {
- struct usb_port_status portsts;
- unsigned short portstatus, portchange;
-
- if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
- USB_HUB_PRINTF("get_port_status failed\n");
- continue;
- }
-
- portstatus = le16_to_cpu(portsts.wPortStatus);
- portchange = le16_to_cpu(portsts.wPortChange);
- USB_HUB_PRINTF("Port %d Status %X Change %X\n",
- i + 1, portstatus, portchange);
-
- if (portchange & USB_PORT_STAT_C_CONNECTION) {
- USB_HUB_PRINTF("port %d connection change\n", i + 1);
- usb_hub_port_connect_change(dev, i);
- }
- if (portchange & USB_PORT_STAT_C_ENABLE) {
- USB_HUB_PRINTF("port %d enable change, status %x\n",
- i + 1, portstatus);
- usb_clear_port_feature(dev, i + 1,
- USB_PORT_FEAT_C_ENABLE);
-
- /* EM interference sometimes causes bad shielded USB
- * devices to be shutdown by the hub, this hack enables
- * them again. Works at least with mouse driver */
- if (!(portstatus & USB_PORT_STAT_ENABLE) &&
- (portstatus & USB_PORT_STAT_CONNECTION) &&
- ((dev->children[i]))) {
- USB_HUB_PRINTF("already running port %i " \
- "disabled by hub (EMI?), " \
- "re-enabling...\n", i + 1);
- usb_hub_port_connect_change(dev, i);
- }
- }
- if (portstatus & USB_PORT_STAT_SUSPEND) {
- USB_HUB_PRINTF("port %d suspend change\n", i + 1);
- usb_clear_port_feature(dev, i + 1,
- USB_PORT_FEAT_SUSPEND);
- }
-
- if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- USB_HUB_PRINTF("port %d over-current change\n", i + 1);
- usb_clear_port_feature(dev, i + 1,
- USB_PORT_FEAT_C_OVER_CURRENT);
- usb_hub_power_on(hub);
- }
-
- if (portchange & USB_PORT_STAT_C_RESET) {
- USB_HUB_PRINTF("port %d reset change\n", i + 1);
- usb_clear_port_feature(dev, i + 1,
- USB_PORT_FEAT_C_RESET);
- }
- } /* end for i all ports */
-
- return 0;
-}
-
-int usb_hub_probe(struct usb_device *dev, int ifnum)
-{
- struct usb_interface *iface;
- struct usb_endpoint_descriptor *ep;
- int ret;
-
- iface = &dev->config.if_desc[ifnum];
- /* Is it a hub? */
- if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
- return 0;
- /* Some hubs have a subclass of 1, which AFAICT according to the */
- /* specs is not defined, but it works */
- if ((iface->desc.bInterfaceSubClass != 0) &&
- (iface->desc.bInterfaceSubClass != 1))
- return 0;
- /* Multiple endpoints? What kind of mutant ninja-hub is this? */
- if (iface->desc.bNumEndpoints != 1)
- return 0;
- ep = &iface->ep_desc[0];
- /* Output endpoint? Curiousier and curiousier.. */
- if (!(ep->bEndpointAddress & USB_DIR_IN))
- return 0;
- /* If it's not an interrupt endpoint, we'd better punt! */
- if ((ep->bmAttributes & 3) != 3)
- return 0;
- /* We found a hub */
- USB_HUB_PRINTF("USB hub found\n");
- ret = usb_hub_configure(dev);
- return ret;
-}
-
/* EOF */
--- /dev/null
+/*
+ *
+ * Most of this source has been derived from the Linux USB
+ * project:
+ * (C) Copyright Linus Torvalds 1999
+ * (C) Copyright Johannes Erdfelt 1999-2001
+ * (C) Copyright Andreas Gal 1999
+ * (C) Copyright Gregory P. Smith 1999
+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
+ * (C) Copyright Randy Dunlap 2000
+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
+ * (C) Copyright Yggdrasil Computing, Inc. 2000
+ * (usb_device_id matching changes by Adam J. Richter)
+ *
+ * Adapted for U-Boot:
+ * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ *
+ */
+
+/****************************************************************************
+ * HUB "Driver"
+ * Probes device for being a hub and configurate it
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
+#include <usb.h>
+#ifdef CONFIG_4xx
+#include <asm/4xx_pci.h>
+#endif
+
+#ifdef DEBUG
+#define USB_DEBUG 1
+#define USB_HUB_DEBUG 1
+#else
+#define USB_DEBUG 0
+#define USB_HUB_DEBUG 0
+#endif
+
+#define USB_PRINTF(fmt, args...) debug_cond(USB_DEBUG, fmt, ##args)
+#define USB_HUB_PRINTF(fmt, args...) debug_cond(USB_HUB_DEBUG, fmt, ##args)
+
+#define USB_BUFSIZ 512
+
+static struct usb_hub_device hub_dev[USB_MAX_HUB];
+static int usb_hub_index;
+
+
+static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
+ USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+}
+
+static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature,
+ port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+static int usb_set_port_feature(struct usb_device *dev, int port, int feature)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT, feature,
+ port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+static int usb_get_hub_status(struct usb_device *dev, void *data)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
+ data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+static int usb_get_port_status(struct usb_device *dev, int port, void *data)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
+ data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+
+static void usb_hub_power_on(struct usb_hub_device *hub)
+{
+ int i;
+ struct usb_device *dev;
+ unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2;
+
+ dev = hub->pusb_dev;
+ /* Enable power to the ports */
+ USB_HUB_PRINTF("enabling power on all ports\n");
+ for (i = 0; i < dev->maxchild; i++) {
+ usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+ USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status);
+ }
+
+ /* Wait at least 100 msec for power to become stable */
+ mdelay(max(pgood_delay, (unsigned)100));
+}
+
+void usb_hub_reset(void)
+{
+ usb_hub_index = 0;
+}
+
+static struct usb_hub_device *usb_hub_allocate(void)
+{
+ if (usb_hub_index < USB_MAX_HUB)
+ return &hub_dev[usb_hub_index++];
+
+ printf("ERROR: USB_MAX_HUB (%d) reached\n", USB_MAX_HUB);
+ return NULL;
+}
+
+#define MAX_TRIES 5
+
+static inline char *portspeed(int portstatus)
+{
+ if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
+ return "480 Mb/s";
+ else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
+ return "1.5 Mb/s";
+ else
+ return "12 Mb/s";
+}
+
+int hub_port_reset(struct usb_device *dev, int port,
+ unsigned short *portstat)
+{
+ int tries;
+ struct usb_port_status portsts;
+ unsigned short portstatus, portchange;
+
+ USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
+ for (tries = 0; tries < MAX_TRIES; tries++) {
+
+ usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
+ mdelay(200);
+
+ if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+ USB_HUB_PRINTF("get_port_status failed status %lX\n",
+ dev->status);
+ return -1;
+ }
+ portstatus = le16_to_cpu(portsts.wPortStatus);
+ portchange = le16_to_cpu(portsts.wPortChange);
+
+ USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
+ portstatus, portchange,
+ portspeed(portstatus));
+
+ USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \
+ " USB_PORT_STAT_ENABLE %d\n",
+ (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
+ (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
+ (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
+
+ if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
+ !(portstatus & USB_PORT_STAT_CONNECTION))
+ return -1;
+
+ if (portstatus & USB_PORT_STAT_ENABLE)
+ break;
+
+ mdelay(200);
+ }
+
+ if (tries == MAX_TRIES) {
+ USB_HUB_PRINTF("Cannot enable port %i after %i retries, " \
+ "disabling port.\n", port + 1, MAX_TRIES);
+ USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
+ return -1;
+ }
+
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
+ *portstat = portstatus;
+ return 0;
+}
+
+
+void usb_hub_port_connect_change(struct usb_device *dev, int port)
+{
+ struct usb_device *usb;
+ struct usb_port_status portsts;
+ unsigned short portstatus;
+
+ /* Check status */
+ if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+ USB_HUB_PRINTF("get_port_status failed\n");
+ return;
+ }
+
+ portstatus = le16_to_cpu(portsts.wPortStatus);
+ USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
+ portstatus,
+ le16_to_cpu(portsts.wPortChange),
+ portspeed(portstatus));
+
+ /* Clear the connection change status */
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
+
+ /* Disconnect any existing devices under this port */
+ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
+ (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
+ USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n");
+ /* Return now if nothing is connected */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return;
+ }
+ mdelay(200);
+
+ /* Reset the port */
+ if (hub_port_reset(dev, port, &portstatus) < 0) {
+ printf("cannot reset port %i!?\n", port + 1);
+ return;
+ }
+
+ mdelay(200);
+
+ /* Allocate a new device struct for it */
+ usb = usb_alloc_new_device();
+
+ if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+ usb->speed = USB_SPEED_HIGH;
+ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+ usb->speed = USB_SPEED_LOW;
+ else
+ usb->speed = USB_SPEED_FULL;
+
+ dev->children[port] = usb;
+ usb->parent = dev;
+ usb->portnr = port + 1;
+ /* Run it through the hoops (find a driver, etc) */
+ if (usb_new_device(usb)) {
+ /* Woops, disable the port */
+ USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
+ }
+}
+
+
+static int usb_hub_configure(struct usb_device *dev)
+{
+ int i;
+ unsigned char buffer[USB_BUFSIZ], *bitmap;
+ struct usb_hub_descriptor *descriptor;
+ struct usb_hub_device *hub;
+#ifdef USB_HUB_DEBUG
+ struct usb_hub_status *hubsts;
+#endif
+
+ /* "allocate" Hub device */
+ hub = usb_hub_allocate();
+ if (hub == NULL)
+ return -1;
+ hub->pusb_dev = dev;
+ /* Get the the hub descriptor */
+ if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
+ "descriptor, giving up %lX\n", dev->status);
+ return -1;
+ }
+ descriptor = (struct usb_hub_descriptor *)buffer;
+
+ /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */
+ i = descriptor->bLength;
+ if (i > USB_BUFSIZ) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
+ "descriptor - too long: %d\n",
+ descriptor->bLength);
+ return -1;
+ }
+
+ if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \
+ "descriptor 2nd giving up %lX\n", dev->status);
+ return -1;
+ }
+ memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength);
+ /* adjust 16bit values */
+ hub->desc.wHubCharacteristics =
+ le16_to_cpu(descriptor->wHubCharacteristics);
+ /* set the bitmap */
+ bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0];
+ /* devices not removable by default */
+ memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8);
+ bitmap = (unsigned char *)&hub->desc.PortPowerCtrlMask[0];
+ memset(bitmap, 0xff, (USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
+
+ for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
+ hub->desc.DeviceRemovable[i] = descriptor->DeviceRemovable[i];
+
+ for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++)
+ hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];
+
+ dev->maxchild = descriptor->bNbrPorts;
+ USB_HUB_PRINTF("%d ports detected\n", dev->maxchild);
+
+ switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) {
+ case 0x00:
+ USB_HUB_PRINTF("ganged power switching\n");
+ break;
+ case 0x01:
+ USB_HUB_PRINTF("individual port power switching\n");
+ break;
+ case 0x02:
+ case 0x03:
+ USB_HUB_PRINTF("unknown reserved power switching mode\n");
+ break;
+ }
+
+ if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND)
+ USB_HUB_PRINTF("part of a compound device\n");
+ else
+ USB_HUB_PRINTF("standalone hub\n");
+
+ switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) {
+ case 0x00:
+ USB_HUB_PRINTF("global over-current protection\n");
+ break;
+ case 0x08:
+ USB_HUB_PRINTF("individual port over-current protection\n");
+ break;
+ case 0x10:
+ case 0x18:
+ USB_HUB_PRINTF("no over-current protection\n");
+ break;
+ }
+
+ USB_HUB_PRINTF("power on to power good time: %dms\n",
+ descriptor->bPwrOn2PwrGood * 2);
+ USB_HUB_PRINTF("hub controller current requirement: %dmA\n",
+ descriptor->bHubContrCurrent);
+
+ for (i = 0; i < dev->maxchild; i++)
+ USB_HUB_PRINTF("port %d is%s removable\n", i + 1,
+ hub->desc.DeviceRemovable[(i + 1) / 8] & \
+ (1 << ((i + 1) % 8)) ? " not" : "");
+
+ if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get Status - " \
+ "too long: %d\n", descriptor->bLength);
+ return -1;
+ }
+
+ if (usb_get_hub_status(dev, buffer) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",
+ dev->status);
+ return -1;
+ }
+
+#ifdef USB_HUB_DEBUG
+ hubsts = (struct usb_hub_status *)buffer;
+#endif
+ USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n",
+ le16_to_cpu(hubsts->wHubStatus),
+ le16_to_cpu(hubsts->wHubChange));
+ USB_HUB_PRINTF("local power source is %s\n",
+ (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \
+ "lost (inactive)" : "good");
+ USB_HUB_PRINTF("%sover-current condition exists\n",
+ (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \
+ "" : "no ");
+ usb_hub_power_on(hub);
+
+ for (i = 0; i < dev->maxchild; i++) {
+ struct usb_port_status portsts;
+ unsigned short portstatus, portchange;
+
+ if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+ USB_HUB_PRINTF("get_port_status failed\n");
+ continue;
+ }
+
+ portstatus = le16_to_cpu(portsts.wPortStatus);
+ portchange = le16_to_cpu(portsts.wPortChange);
+ USB_HUB_PRINTF("Port %d Status %X Change %X\n",
+ i + 1, portstatus, portchange);
+
+ if (portchange & USB_PORT_STAT_C_CONNECTION) {
+ USB_HUB_PRINTF("port %d connection change\n", i + 1);
+ usb_hub_port_connect_change(dev, i);
+ }
+ if (portchange & USB_PORT_STAT_C_ENABLE) {
+ USB_HUB_PRINTF("port %d enable change, status %x\n",
+ i + 1, portstatus);
+ usb_clear_port_feature(dev, i + 1,
+ USB_PORT_FEAT_C_ENABLE);
+
+ /* EM interference sometimes causes bad shielded USB
+ * devices to be shutdown by the hub, this hack enables
+ * them again. Works at least with mouse driver */
+ if (!(portstatus & USB_PORT_STAT_ENABLE) &&
+ (portstatus & USB_PORT_STAT_CONNECTION) &&
+ ((dev->children[i]))) {
+ USB_HUB_PRINTF("already running port %i " \
+ "disabled by hub (EMI?), " \
+ "re-enabling...\n", i + 1);
+ usb_hub_port_connect_change(dev, i);
+ }
+ }
+ if (portstatus & USB_PORT_STAT_SUSPEND) {
+ USB_HUB_PRINTF("port %d suspend change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1,
+ USB_PORT_FEAT_SUSPEND);
+ }
+
+ if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
+ USB_HUB_PRINTF("port %d over-current change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1,
+ USB_PORT_FEAT_C_OVER_CURRENT);
+ usb_hub_power_on(hub);
+ }
+
+ if (portchange & USB_PORT_STAT_C_RESET) {
+ USB_HUB_PRINTF("port %d reset change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1,
+ USB_PORT_FEAT_C_RESET);
+ }
+ } /* end for i all ports */
+
+ return 0;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+ struct usb_interface *iface;
+ struct usb_endpoint_descriptor *ep;
+ int ret;
+
+ iface = &dev->config.if_desc[ifnum];
+ /* Is it a hub? */
+ if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
+ return 0;
+ /* Some hubs have a subclass of 1, which AFAICT according to the */
+ /* specs is not defined, but it works */
+ if ((iface->desc.bInterfaceSubClass != 0) &&
+ (iface->desc.bInterfaceSubClass != 1))
+ return 0;
+ /* Multiple endpoints? What kind of mutant ninja-hub is this? */
+ if (iface->desc.bNumEndpoints != 1)
+ return 0;
+ ep = &iface->ep_desc[0];
+ /* Output endpoint? Curiousier and curiousier.. */
+ if (!(ep->bEndpointAddress & USB_DIR_IN))
+ return 0;
+ /* If it's not an interrupt endpoint, we'd better punt! */
+ if ((ep->bmAttributes & 3) != 3)
+ return 0;
+ /* We found a hub */
+ USB_HUB_PRINTF("USB hub found\n");
+ ret = usb_hub_configure(dev);
+ return ret;
+}
'|', '~', ':', '"', '~', '<', '>', '?'
};
+static const unsigned char usb_kbd_num_keypad[] = {
+ '/', '*', '-', '+', '\r',
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
+ '.', 0, 0, 0, '='
+};
+
/*
* NOTE: It's important for the NUM, CAPS, SCROLL-lock bits to be in this
* order. See usb_kbd_setled() function!
keycode = usb_kbd_numkey[scancode - 0x1e];
}
+ /* Numeric keypad */
+ if ((scancode >= 0x54) && (scancode <= 0x67))
+ keycode = usb_kbd_num_keypad[scancode - 0x54];
+
if (data->flags & USB_KBD_CTRL)
keycode = scancode - 0x3;
static inline void usb_kbd_poll_for_event(struct usb_device *dev)
{
#if defined(CONFIG_SYS_USB_EVENT_POLL)
- usb_event_poll();
+ struct usb_interface *iface;
+ struct usb_endpoint_descriptor *ep;
+ struct usb_kbd_pdata *data;
+ int pipe;
+ int maxp;
+
+ /* Get the pointer to USB Keyboard device pointer */
+ data = dev->privptr;
+ iface = &dev->config.if_desc[0];
+ ep = &iface->ep_desc[0];
+ pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
+
+ /* Submit a interrupt transfer request */
+ maxp = usb_maxpacket(dev, pipe);
+ usb_submit_int_msg(dev, pipe, &data->new[0],
+ maxp > 8 ? 8 : maxp, ep->bInterval);
+
usb_kbd_irq_worker(dev);
#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
struct usb_interface *iface;
struct usb_kbd_pdata *data = dev->privptr;
iface = &dev->config.if_desc[0];
usb_get_report(dev, iface->desc.bInterfaceNumber,
- 1, 1, data->new, sizeof(data->new));
+ 1, 0, data->new, sizeof(data->new));
if (memcmp(data->old, data->new, sizeof(data->new)))
usb_kbd_irq_worker(dev);
#endif
if (error)
return error;
+#ifdef CONFIG_CONSOLE_MUX
+ error = iomux_doenv(stdin, stdinname);
+ if (error)
+ return error;
+#else
/* Check if this is the standard input device. */
if (strcmp(stdinname, DEVNAME))
return 1;
error = console_assign(stdin, DEVNAME);
if (error)
return error;
+#endif
return 1;
}
}
/* long wait for reset */
- wait_ms(150);
+ mdelay(150);
USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result,
us->pusb_dev->status);
pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
result = usb_clear_halt(us->pusb_dev, pipe);
/* long wait for reset */
- wait_ms(150);
+ mdelay(150);
USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n",
result, us->pusb_dev->status);
/* long wait for reset */
pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
result = usb_clear_halt(us->pusb_dev, pipe);
- wait_ms(150);
+ mdelay(150);
USB_STOR_PRINTF("BBB_reset result %d: status %lX"
" clearing OUT endpoint\n", result,
us->pusb_dev->status);
USB_CNTL_TIMEOUT * 5);
/* long wait for reset */
- wait_ms(1500);
+ mdelay(1500);
USB_STOR_PRINTF("CB_reset result %d: status %lX"
" clearing endpoint halt\n", result,
us->pusb_dev->status);
while (timeout--) {
if ((volatile int *) us->ip_wanted == 0)
break;
- wait_ms(10);
+ mdelay(10);
}
if (us->ip_wanted) {
printf(" Did not get interrupt on CBI\n");
usb_stor_BBB_reset(us);
return USB_STOR_TRANSPORT_FAILED;
}
- wait_ms(5);
+ mdelay(5);
pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
/* DATA phase + error handling */
srb->sense_buf[12], srb->sense_buf[13]);
return USB_STOR_TRANSPORT_FAILED;
} else {
- wait_ms(100);
+ mdelay(100);
goto do_retry;
}
break;
if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD)
return 0;
usb_request_sense(srb, ss);
- wait_ms(100);
+ mdelay(100);
} while (retries--);
return -1;
# only supported compiler options are used
#
CC_OPTIONS_CACHE_FILE := $(OBJTREE)/include/generated/cc_options.mk
-
-$(if $(wildcard $(CC_OPTIONS_CACHE_FILE)),,\
- $(shell mkdir -p $(dir $(CC_OPTIONS_CACHE_FILE))))
+CC_TEST_OFILE := $(OBJTREE)/include/generated/cc_test_file.o
-include $(CC_OPTIONS_CACHE_FILE)
-cc-option-sys = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
+cc-option-sys = $(shell mkdir -p $(dir $(CC_TEST_OFILE)); \
+ if $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o $(CC_TEST_OFILE) \
> /dev/null 2>&1; then \
echo 'CC_OPTIONS += $(strip $1)' >> $(CC_OPTIONS_CACHE_FILE); \
echo "$(1)"; fi)
$(call cc-option,-Wno-format-security)
CFLAGS += $(CFLAGS_WARN)
+# Report stack usage if supported
+CFLAGS_STACK := $(call cc-option,-fstack-usage)
+CFLAGS += $(CFLAGS_STACK)
+
# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format>
# option to the assembler.
AFLAGS_DEBUG :=
block_dev_desc_t* (*reloc_get_dev)(int dev);
char *name;
+ if (!ifname)
+ return NULL;
+
name = drvr->name;
#ifdef CONFIG_NEEDS_MANUAL_RELOC
name += gd->reloc_off;
PORTMUX_DIR_OUTPUT
PORTMUX_DIR_INPUT
-These mutually-exlusive flags configure the initial direction of the
+These mutually-exclusive flags configure the initial direction of the
pins. PORTMUX_DIR_OUTPUT means that the pins are driven by the CPU,
while PORTMUX_DIR_INPUT means that the pins are tristated by the CPU.
These flags are ignored by portmux_select_peripheral().
PORTMUX_DRIVE_HIGH
PORTMUX_DRIVE_MAX
-These mutually-exlusive flags determine the drive strength of the
+These mutually-exclusive flags determine the drive strength of the
pins. PORTMUX_DRIVE_MIN will give low power-consumption, but may cause
corruption of high-speed signals. PORTMUX_DRIVE_MAX will give high
power-consumption, but may be necessary on pins toggling at very high
+++ /dev/null
-
-These are brief instructions on how to add support for CF adapters to
-custom designed PXA boards. You need to set the parameters in the
-config file. This should work for most implementations especially if you
-follow the connections of the standard lubbock. Anyway just the block
-marked memory configuration should be touched since the other parameters
-are imposed by the PXA architecture.
-
-EDIT 2010-07-01: in common/cmd_ide.c, having CONFIG_PXA_PCMCIA defined
-would cause looping on inw()/outw() rather than using insw()/outsw(),
-thus making sure IDE / ATA bytes are properly swapped. This behaviour
-is now controlled by CONFIG_IDE_SWAP_IO, therefore PXA boards with
-PCMCIA should #define CONFIG_IDE_SWAP_IO.
-
-#define CONFIG_IDE_SWAP_IO
-
-#define CONFIG_PXA_PCMCIA 1
-#define CONFIG_PXA_IDE 1
-
-#define CONFIG_PCMCIA_SLOT_A 1
-/* just to keep build system happy */
-
-#define CONFIG_SYS_PCMCIA_MEM_ADDR 0x28000000
-#define CONFIG_SYS_PCMCIA_MEM_SIZE 0x10000000
-
-#define CONFIG_SYS_MECR_VAL 0x00000000
-#define CONFIG_SYS_MCMEM0_VAL 0x00004204
-#define CONFIG_SYS_MCMEM1_VAL 0x00000000
-#define CONFIG_SYS_MCATT0_VAL 0x00010504
-#define CONFIG_SYS_MCATT1_VAL 0x00000000
-#define CONFIG_SYS_MCIO0_VAL 0x00008407
-#define CONFIG_SYS_MCIO1_VAL 0x00000000
-/* memory configuration */
-
-#define CONFIG_SYS_IDE_MAXBUS 1
-/* max. 1 IDE bus */
-#define CONFIG_SYS_IDE_MAXDEVICE 1
-/* max. 1 drive per IDE bus */
-
-#define CONFIG_SYS_ATA_IDE0_OFFSET 0x0000
-
-#define CONFIG_SYS_ATA_BASE_ADDR 0x20000000
-
-/* Offset for data I/O */
-#define CONFIG_SYS_ATA_DATA_OFFSET 0x1f0
-
-/* Offset for normal register accesses */
-#define CONFIG_SYS_ATA_REG_OFFSET 0x1f0
-
-/* Offset for alternate registers */
-#define CONFIG_SYS_ATA_ALT_OFFSET 0x3f0
-
-
-Another important point is that maybe you have to power the pcmcia
-subsystem. This is very board specific, for an example on how to
-do it please search for CONFIG_EXADRON1 in cmd_pcmcia.c
parameter of server's IP address or environment variable
"ntpserverip". The network time is sent as UTC. So if you want to
set local time to RTC, set the offset in second from UTC to the
-enviroment variable "time offset".
+environment variable "time offset".
If the DHCP server provides time server's IP or time offset, you
don't need to set the above environment variables yourself.
=> setenv serverip 192.168.0.10
=> setenv gatewayip=192.168.0.1
=> saveenv
-Saving Enviroment to Flash...
+Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
=> cp.b 0x100000 FFF00000 1f28c
Copy to Flash... done
=> saveenv
-Saving Enviroment to Flash...
+Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
done
Erased 7 sectors
Copy to Flash... done
-Saving Enviroment to Flash...
+Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
done
U-Boot environment variables can be stored at different places:
- Dataflash on SPI chip select 0 (dataflash card)
- Nand flash.
- - Nor falsh (not populate by default)
+ - Nor flash (not populate by default)
You can choose your storage location at config step (here for at91sam9260ek) :
make at91sam9263ek_config - use data flash (spi cs0) (default)
make at91sam9263ek_nandflash_config - use nand flash
make at91sam9263ek_dataflash_cs0_config - use data flash (spi cs0)
- make at91sam9263ek_norflash_config - use nor falsh
+ make at91sam9263ek_norflash_config - use nor flash
You can choose to boot directly from U-Boot at config step
- make at91sam9263ek_norflash_boot_config - boot from nor falsh
+ make at91sam9263ek_norflash_boot_config - boot from nor flash
------------------------------------------------------------------------------
example: this is added to at91sam9260_devices.c:
-#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+#if defined(CONFIG_GENERIC_ATMEL_MCI)
void at91_mci_hw_init(void)
{
at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */
--- /dev/null
+The spl command is used to export a boot parameter image to RAM. Later
+it may implement more functions connected to the SPL.
+
+SUBCOMMAND EXPORT
+To execute the command everything has to be in place as if bootm should be
+used. (kernel image, initrd-image, fdt-image etc.)
+
+export has two subcommands:
+ atags: exports the ATAGS
+ fdt: exports the FDT
+
+Call is:
+spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt]
+
+
+TYPICAL CALL
+
+on OMAP3:
+nandecc hw
+nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/
+spl export atags /* export ATAGS */
+nand erase 0x680000 0x20000 /* erase - one page */
+nand write 0x80000100 0x680000 0x20000 /* write the image - one page */
+
+call with FDT:
+nandecc hw
+nand read 0x82000000 0x280000 0x400000 /* Read kernel image from NAND*/
+tftpboot 0x80000100 devkit8000.dtb /* Read fdt */
+spl export fdt 0x82000000 - 0x80000100 /* export FDT */
+nand erase 0x680000 0x20000 /* erase - one page */
+nand write <adress shown by spl export> 0x680000 0x20000
=======================================================================
This file contains some handy info regarding U-Boot and the AMCC
-Ebony evalutation board. See the README.ppc440 for additional
+Ebony evaluation board. See the README.ppc440 for additional
information.
c<n> - the controller number, eg. c0, c1
d<n> - the DIMM number, eg. d0, d1
spd - print SPD data
- dimmparms - DIMM paramaters, calcualted from SPD
+ dimmparms - DIMM parameters, calculated from SPD
commonparms - lowest common parameters for all DIMMs
opts - options
addresses - address assignment (not implemented yet)
c<n> - the controller number, eg. c0, c1
d<n> - the DIMM number, eg. d0, d1
spd - print SPD data
- dimmparms - DIMM paramaters, calcualted from SPD
+ dimmparms - DIMM parameters, calculated from SPD
commonparms - lowest common parameters for all DIMMs
opts - options
addresses - address assignment (not implemented yet)
"On" == 0
SW3 is switch 18 as silk-screened onto the board.
- SW4[8] is the bit labled 8 on Switch 4.
+ SW4[8] is the bit labeled 8 on Switch 4.
SW5[1:6] refers to bits labeled 1 through 6 in order on switch 5.
SW6[7:1] refers to bits labeled 7 through 1 in order on switch 6.
SW7[1:8]= 0000_0001 refers to bits labeled 1 through 6 is set as "On"
"On" == 0
SW18 is switch 18 as silk-screened onto the board.
- SW4[8] is the bit labled 8 on Switch 4.
+ SW4[8] is the bit labeled 8 on Switch 4.
SW2[1:6] refers to bits labeled 1 through 6 in order on switch 2.
SW3[7:1] refers to bits labeled 7 through 1 in order on switch 3.
SW3[1:8]= 0000_0001 refers to bits labeled 1 through 6 is set as "On"
"Off" == 1
"On" == 0
- SW4[8] is the bit labled 8 on Switch 4.
+ SW4[8] is the bit labeled 8 on Switch 4.
SW2[1:6] refers to bits labeled 1 through 6 in order on switch 2.
SW2[1:8]= 0000_0001 refers to bits labeled 1 through 7 is set as "On"
and bits labeled 8 is set as "Off".
Memory Map
----------
-0xff80_0000 - 0xffbf_ffff Alernate bank 4MB
+0xff80_0000 - 0xffbf_ffff Alternate bank 4MB
0xffc0_0000 - 0xffff_ffff Boot bank 4MB
0xffb8_0000 Alternate image start 512KB
Memory Map
----------
-0xe800_0000 - 0xebff_ffff Alernate bank 64MB
+0xe800_0000 - 0xebff_ffff Alternate bank 64MB
0xec00_0000 - 0xefff_ffff Boot bank 64MB
0xebf8_0000 - 0xebff_ffff Alternate u-boot address 512KB
- Select "Advanced setup" -> " Prompt for advanced kernel
configuration options"
- Select "Set physical address where the kernel is loaded" and
- set it to 0x20000000, asssuming core1 will start from 512MB.
+ set it to 0x20000000, assuming core1 will start from 512MB.
- Select "Set custom page offset address"
- Select "Set custom kernel base address"
- Select "Set maximum low memory"
"On" == 0
SW18 is switch 18 as silk-screened onto the board.
- SW4[8] is the bit labled 8 on Switch 4.
+ SW4[8] is the bit labeled 8 on Switch 4.
SW2[1:6] refers to bits labeled 1 through 6 in order on switch 2
SW3[7:1] refers to bits labeled 7 through 1 in order on switch 3
2.4 I2C
LM75 @ 0x90 for temperature monitoring.
EEPROM @ 0xA0 for vendor specifics.
- image sensor interface (slave adresses depend on sensor)
+ image sensor interface (slave addresses depend on sensor)
3 Flash layout.
MAX5381 DAC @ 0x60 for 1st digital input threshold.
LM75 @ 0x90 for temperature monitoring.
EEPROM @ 0xA0 for system setup (HRCW etc.) + vendor specifics.
- 1st image sensor interface (slave adresses depend on sensor)
+ 1st image sensor interface (slave addresses depend on sensor)
Bus2:
MAX5381 DAC @ 0x60 for 2nd digital input threshold.
- 2nd image sensor interface (slave adresses depend on sensor)
+ 2nd image sensor interface (slave addresses depend on sensor)
3 Flash layout.
2.4 I2C
EEPROM @ 0xA0 for vendor specifics.
- image sensor interface (slave adresses depend on sensor)
+ image sensor interface (slave addresses depend on sensor)
3 Flash layout.
---------------------------------
The recent mainline U-Boot for the Freescale i.MX6q SabreLite board supports
-boot from SD card only. However, by default, the early version of SabreLite
+boot from SD card only. However, by default, the SabreLite
boards boot from the SPI NOR flash. These boards need to be reflashed with
a small SD card loader to support boot from SD card. This small SD card loader
will be flashed into the SPI NOR. The board will still boot from SPI NOR, but
the loader will in turn request the BootROM to load the U-Boot from SD card.
-At the moment of writing, please check with Freescale on the availablity of
-this small SD loader binary.
+
+The SD card loader is available from
+
+https://wiki.linaro.org/Boards/MX6QSabreLite
+
+under a open-source 3-clause BSD license.
To update the SPI-NOR on the SabreLite board without the Freescale
manufacturing tool use the following procedure:
1. Write this SD card loader onto a large SD card using:
- sudo dd if=MX6_SPI_to_SD_loader.bin of=/dev/sXx
+ sudo dd if=iMX6DQ_SPI_to_uSDHC3.bin of=/dev/sXx
Note: Replace sXx with the device representing the SD card in your system.
=======================================================================
This file contains some handy info regarding U-Boot and the AMCC
-Ocotea 440gx evalutation board. See the README.ppc440 for additional
+Ocotea 440gx evaluation board. See the README.ppc440 for additional
information.
Memory Map
----------
-0xef00_0000 - 0xef7f_ffff Alernate bank 8MB
+0xef00_0000 - 0xef7f_ffff Alternate bank 8MB
0xe800_0000 - 0xefff_ffff Boot bank 8MB
0xef78_0000 - 0xef7f_ffff Alternate u-boot address 512KB
"Prompt for advanced kernel configuration options"
- Select
"Set physical address where the kernel is loaded"
- and set it to 0x20000000, asssuming core1 will
+ and set it to 0x20000000, assuming core1 will
start from 512MB.
- Select "Set custom page offset address"
- Select "Set custom kernel base address"
- SPI ROM 8MB
- 2D Graphic controller
- Ethernet controller
+ - eMMC 2GB
configuration for This board:
--- /dev/null
+Overview of SPL on OMAP3 devices
+================================
+
+Introduction
+------------
+
+This document provides an overview of how SPL functions on OMAP3 (and related
+such as am35x and am37x) processors.
+
+Methodology
+-----------
+
+On these platforms the ROM supports trying a sequence of boot devices. Once
+one has been used successfully to load SPL this information is stored in memory
+and the location stored in a register. We will read this to determine where to
+read U-Boot from in turn.
+
+Memory Map
+----------
+
+This is an example of a typical setup. See top-level README for documentation
+of which CONFIG variables control these values. For a given board and the
+amount of DRAM available to it different values may need to be used.
+Note that the size of the SPL text rodata and data is enforced with a CONFIG
+option and growing over that size results in a link error. The SPL stack
+starts at the top of SRAM (which is configurable) and grows downward. The
+space between the top of SRAM and the enforced upper bound on the size of the
+SPL text, data and rodata is considered the safe stack area. Details on
+confirming this behavior are shown below.
+
+A portion of the system memory map looks as follows:
+SRAM: 0x40200000 - 0x4020FFFF
+DDR1: 0x80000000 - 0xBFFFFFFF
+
+Option 1 (SPL only):
+0x40200800 - 0x4020BBFF: Area for SPL text, data and rodata
+0x4020BC00 - 0x4020FFFC: Area for the SPL stack.
+0x80000000 - 0x8007FFFF: Area for the SPL BSS.
+0x80100000: CONFIG_SYS_TEXT_BASE of U-Boot
+0x80208000 - 0x80307FFF: malloc() pool available to SPL.
+
+Option 2 (SPL or X-Loader):
+0x40200800 - 0x4020BBFF: Area for SPL text, data and rodata
+0x4020BC00 - 0x4020FFFC: Area for the SPL stack.
+0x80008000: CONFIG_SYS_TEXT_BASE of U-Boot
+0x87000000 - 0x8707FFFF: Area for the SPL BSS.
+0x87080000 - 0x870FFFFF: malloc() pool available to SPL.
+
+For the areas that reside within DDR1 they must not be used prior to s_init()
+completing. Note that CONFIG_SYS_TEXT_BASE must be clear of the areas that SPL
+uses while running. This is why we have two versions of the memory map that
+only vary in where the BSS and malloc pool reside.
+
+Estimating stack usage
+----------------------
+
+With gcc 4.6 (and later) and the use of GNU cflow it is possible to estimate
+stack usage at various points in run sequence of SPL. The -fstack-usage option
+to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that
+will give stack usage information and cflow can construct program flow.
+
+Must have gcc 4.6 or later, which supports -fstack-usage
+
+1) Build normally
+2) Perform the following shell command to generate a list of C files used in
+SPL:
+$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list
+3) Execute cflow:
+$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER
+
+cflow will spit out a number of warnings as it does not parse
+the config files and picks functions based on #ifdef. Parsing the '.i'
+files instead introduces another set of headaches. These warnings are
+not usually important to understanding the flow, however.
--- /dev/null
+Device Tree Bindings Staging Area
+=================================
+
+This directory contains device tree bindings for U-Boot.
+
+These follow along with Linux kernel bindings, with a few additions. By
+adding the files here, U-Boot patches can clearly show thees additions.
+This makes it easier for device tree people to review these additions in
+patches sent to the U-Boot mailing list.
+
+The intent IS to commit these files to U-Boot. Hopefully at some point
+the files will be stored in another repo (shared with Linux) which is
+brought in as needed. Changes here are intended to mirror changes in the
+Linux Documentation/devicetree/bindings/ directory.
+
+sjg@chromium.org
+17-Jan-12
--- /dev/null
+NVIDIA Tegra20 Clock And Reset Controller
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
+for muxing and gating Tegra's clocks, and setting their rates.
+
+Required properties :
+- compatible : Should be "nvidia,tegra20-car"
+- reg : Should contain CAR registers location and length
+- clocks : Should contain phandle and clock specifiers for two clocks:
+ the 32 KHz "32k_in", and the board-specific oscillator "osc".
+- #clock-cells : Should be 1.
+ In clock consumers, this cell represents the clock ID exposed by the CAR.
+
+ The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+ registers. These IDs often match those in the CAR's RST_DEVICES registers,
+ but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+ this case, those clocks are assigned IDs above 95 in order to highlight
+ this issue. Implementations that interpret these clock IDs as bit values
+ within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+ explicitly handle these special cases.
+
+ The balance of the clocks controlled by the CAR are assigned IDs of 96 and
+ above.
+
+ 0 cpu
+ 1 unassigned
+ 2 unassigned
+ 3 ac97
+ 4 rtc
+ 5 tmr
+ 6 uart1
+ 7 unassigned (register bit affects uart2 and vfir)
+ 8 gpio
+ 9 sdmmc2
+ 10 unassigned (register bit affects spdif_in and spdif_out)
+ 11 i2s1
+ 12 i2c1
+ 13 ndflash
+ 14 sdmmc1
+ 15 sdmmc4
+ 16 twc
+ 17 pwm
+ 18 i2s2
+ 19 epp
+ 20 unassigned (register bit affects vi and vi_sensor)
+ 21 2d
+ 22 usbd
+ 23 isp
+ 24 3d
+ 25 ide
+ 26 disp2
+ 27 disp1
+ 28 host1x
+ 29 vcp
+ 30 unassigned
+ 31 cache2
+
+ 32 mem
+ 33 ahbdma
+ 34 apbdma
+ 35 unassigned
+ 36 kbc
+ 37 stat_mon
+ 38 pmc
+ 39 fuse
+ 40 kfuse
+ 41 sbc1
+ 42 snor
+ 43 spi1
+ 44 sbc2
+ 45 xio
+ 46 sbc3
+ 47 dvc
+ 48 dsi
+ 49 unassigned (register bit affects tvo and cve)
+ 50 mipi
+ 51 hdmi
+ 52 csi
+ 53 tvdac
+ 54 i2c2
+ 55 uart3
+ 56 unassigned
+ 57 emc
+ 58 usb2
+ 59 usb3
+ 60 mpe
+ 61 vde
+ 62 bsea
+ 63 bsev
+
+ 64 speedo
+ 65 uart4
+ 66 uart5
+ 67 i2c3
+ 68 sbc4
+ 69 sdmmc3
+ 70 pcie
+ 71 owr
+ 72 afi
+ 73 csite
+ 74 unassigned
+ 75 avpucq
+ 76 la
+ 77 unassigned
+ 78 unassigned
+ 79 unassigned
+ 80 unassigned
+ 81 unassigned
+ 82 unassigned
+ 83 unassigned
+ 84 irama
+ 85 iramb
+ 86 iramc
+ 87 iramd
+ 88 cram2
+ 89 audio_2x a/k/a audio_2x_sync_clk
+ 90 clk_d
+ 91 unassigned
+ 92 sus
+ 93 cdev1
+ 94 cdev2
+ 95 unassigned
+
+ 96 uart2
+ 97 vfir
+ 98 spdif_in
+ 99 spdif_out
+ 100 vi
+ 101 vi_sensor
+ 102 tvo
+ 103 cve
+ 104 osc
+ 105 clk_32k a/k/a clk_s
+ 106 clk_m
+ 107 sclk
+ 108 cclk
+ 109 hclk
+ 110 pclk
+ 111 blink
+ 112 pll_a
+ 113 pll_a_out0
+ 114 pll_c
+ 115 pll_c_out1
+ 116 pll_d
+ 117 pll_d_out0
+ 118 pll_e
+ 119 pll_m
+ 120 pll_m_out1
+ 121 pll_p
+ 122 pll_p_out1
+ 123 pll_p_out2
+ 124 pll_p_out3
+ 125 pll_p_out4
+ 126 pll_s
+ 127 pll_u
+ 128 pll_x
+ 129 cop a/k/a avp
+ 130 audio a/k/a audio_sync_clk
+
+Example SoC include file:
+
+/ {
+ tegra_car: clock@60006000 {
+ compatible = "nvidia,tegra20-car";
+ reg = <0x60006000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ usb@c5004000 {
+ clocks = <&tegra_car 58>; /* usb2 */
+ };
+};
+
+Example board file:
+
+/ {
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ osc: clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+ };
+
+ i2c@7000d000 {
+ pmic@34 {
+ compatible = "ti,tps6586x";
+ reg = <0x34>;
+
+ clk_32k: clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+ };
+
+ &tegra_car {
+ clocks = <&clk_32k> <&osc>;
+ };
+};
--- /dev/null
+(Placeholder note while we locate the kernel Tegra20 bindings)
+
+Added in U-Boot:
+
+Required properties:
+ - clocks : Two clocks must be given, each as a phandle to the Tegra's
+ CAR node and the clock number as a parameter:
+ - the I2C clock to use for the peripheral
+ - the pll_p_out3 clock, which can be used for fast operation. This
+ does not change and is the same for all I2C nodes.
+
+Example:
+(TODO: merge with existing example):
+
+ i2c@7000c400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000C400 0x100>;
+ interrupts = < 116 >;
+ /* PERIPH_ID_I2C2, PLL_P_OUT3 */
+ clocks = <&tegra_car 54>, <&tegra_car 124>;
+ };
--- /dev/null
+Tegra SOC USB controllers
+
+The device node for a USB controller that is part of a Tegra
+SOC is as described in the document "Open Firmware Recommended
+Practice : Universal Serial Bus" with the following modifications
+and additions :
+
+Required properties :
+ - compatible : Should be "nvidia,tegra20-ehci" for USB controllers
+ used in host mode.
+ - phy_type : Should be one of "ulpi" or "utmi".
+ - nvidia,vbus-gpio : If present, specifies a gpio that needs to be
+ activated for the bus to be powered.
+
+Optional properties:
+ - dr_mode : dual role mode. Indicates the working mode for
+ nvidia,tegra20-ehci compatible controllers. Can be "host", "peripheral",
+ or "otg". Default to "host" if not defined for backward compatibility.
+ host means this is a host controller
+ peripheral means it is device controller
+ otg means it can operate as either ("on the go")
+ - nvidia,has-legacy-mode : boolean indicates whether this controller can
+ operate in legacy mode (as APX 2500 / 2600). In legacy mode some
+ registers are accessed through the APB_MISC base address instead of
+ the USB controller.
alias tegra2 tegra
alias ti uboot, Sandeep Paulraj <s-paulraj@ti.com>, Tom Rini <trini@ti.com>
-alias avr32 uboot, reinhardm
+alias avr32 uboot, Andreas Bießmann <andreas.devel@googlemail.com>
alias bfin uboot, vapier
alias blackfin bfin
alias mmc uboot, afleming
alias nand uboot, scottwood
alias net uboot, wd
-alias usb uboot, rbohmer
+alias usb uboot, marex
alias video uboot, ag
return tmp;
}
+#ifndef CONFIG_SYS_DCACHE_OFF
+void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+{
+ uint32_t addr;
+ uint32_t size;
+
+ addr = (uint32_t)desc;
+ size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT);
+
+ flush_dcache_range(addr, addr + size);
+}
+#else
+inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {}
+#endif
+
/*
* Enable a DMA channel.
*
struct mxs_dma_desc *mxs_dma_desc_alloc(void)
{
struct mxs_dma_desc *pdesc;
+ uint32_t size;
- pdesc = memalign(MXS_DMA_ALIGNMENT, sizeof(struct mxs_dma_desc));
+ size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT);
+ pdesc = memalign(MXS_DMA_ALIGNMENT, size);
if (pdesc == NULL)
return NULL;
last->cmd.next = mxs_dma_cmd_address(pdesc);
last->cmd.data |= MXS_DMA_DESC_CHAIN;
+
+ mxs_dma_flush_desc(last);
}
pdesc->flags |= MXS_DMA_DESC_READY;
if (pdesc->flags & MXS_DMA_DESC_FIRST)
pchan->pending_num++;
list_add_tail(&pdesc->node, &pchan->active);
+ mxs_dma_flush_desc(pdesc);
+
return ret;
}
COBJS-$(CONFIG_PCA953X) += pca953x.o
COBJS-$(CONFIG_PCA9698) += pca9698.o
COBJS-$(CONFIG_S5P) += s5p_gpio.o
+COBJS-$(CONFIG_SANDBOX_GPIO) += sandbox.o
COBJS-$(CONFIG_TEGRA2_GPIO) += tegra2_gpio.o
COBJS-$(CONFIG_DA8XX_GPIO) += da8xx_gpio.o
COBJS-$(CONFIG_ALTERA_PIO) += altera_pio.o
{
uint32_t bank = PAD_BANK(gpio);
uint32_t offset = PINCTRL_DIN(bank);
- struct mx28_register *reg =
- (struct mx28_register *)(MXS_PINCTRL_BASE + offset);
+ struct mx28_register_32 *reg =
+ (struct mx28_register_32 *)(MXS_PINCTRL_BASE + offset);
return (readl(®->reg) >> PAD_PIN(gpio)) & 1;
}
{
uint32_t bank = PAD_BANK(gpio);
uint32_t offset = PINCTRL_DOUT(bank);
- struct mx28_register *reg =
- (struct mx28_register *)(MXS_PINCTRL_BASE + offset);
+ struct mx28_register_32 *reg =
+ (struct mx28_register_32 *)(MXS_PINCTRL_BASE + offset);
if (value)
writel(1 << PAD_PIN(gpio), ®->reg_set);
{
uint32_t bank = PAD_BANK(gpio);
uint32_t offset = PINCTRL_DOE(bank);
- struct mx28_register *reg =
- (struct mx28_register *)(MXS_PINCTRL_BASE + offset);
+ struct mx28_register_32 *reg =
+ (struct mx28_register_32 *)(MXS_PINCTRL_BASE + offset);
writel(1 << PAD_PIN(gpio), ®->reg_clr);
{
uint32_t bank = PAD_BANK(gpio);
uint32_t offset = PINCTRL_DOE(bank);
- struct mx28_register *reg =
- (struct mx28_register *)(MXS_PINCTRL_BASE + offset);
+ struct mx28_register_32 *reg =
+ (struct mx28_register_32 *)(MXS_PINCTRL_BASE + offset);
writel(1 << PAD_PIN(gpio), ®->reg_set);
--- /dev/null
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/gpio.h>
+
+/* Flags for each GPIO */
+#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
+#define GPIOF_HIGH (1 << 1) /* Currently set high */
+#define GPIOF_RESERVED (1 << 2) /* Is in use / requested */
+
+struct gpio_state {
+ const char *label; /* label given by requester */
+ u8 flags; /* flags (GPIOF_...) */
+};
+
+/*
+ * State of GPIOs
+ * TODO: Put this into sandbox state
+ */
+static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT];
+
+/* Access routines for GPIO state */
+static u8 *get_gpio_flags(unsigned gp)
+{
+ /* assert()'s could be disabled, so make sure we handle that */
+ assert(gp < ARRAY_SIZE(state));
+ if (gp >= ARRAY_SIZE(state)) {
+ static u8 invalid_flags;
+ printf("sandbox_gpio: error: invalid gpio %u\n", gp);
+ return &invalid_flags;
+ }
+
+ return &state[gp].flags;
+}
+
+static int get_gpio_flag(unsigned gp, int flag)
+{
+ return (*get_gpio_flags(gp) & flag) != 0;
+}
+
+static int set_gpio_flag(unsigned gp, int flag, int value)
+{
+ u8 *gpio = get_gpio_flags(gp);
+
+ if (value)
+ *gpio |= flag;
+ else
+ *gpio &= ~flag;
+
+ return 0;
+}
+
+static int check_reserved(unsigned gpio, const char *func)
+{
+ if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
+ printf("sandbox_gpio: %s: error: gpio %u not reserved\n",
+ func, gpio);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Back-channel sandbox-internal-only access to GPIO state
+ */
+
+int sandbox_gpio_get_value(unsigned gp)
+{
+ if (get_gpio_flag(gp, GPIOF_OUTPUT))
+ debug("sandbox_gpio: get_value on output gpio %u\n", gp);
+ return get_gpio_flag(gp, GPIOF_HIGH);
+}
+
+int sandbox_gpio_set_value(unsigned gp, int value)
+{
+ return set_gpio_flag(gp, GPIOF_HIGH, value);
+}
+
+int sandbox_gpio_get_direction(unsigned gp)
+{
+ return get_gpio_flag(gp, GPIOF_OUTPUT);
+}
+
+int sandbox_gpio_set_direction(unsigned gp, int output)
+{
+ return set_gpio_flag(gp, GPIOF_OUTPUT, output);
+}
+
+/*
+ * These functions implement the public interface within U-Boot
+ */
+
+/* set GPIO port 'gp' as an input */
+int gpio_direction_input(unsigned gp)
+{
+ debug("%s: gp:%u\n", __func__, gp);
+
+ if (check_reserved(gp, __func__))
+ return -1;
+
+ return sandbox_gpio_set_direction(gp, 0);
+}
+
+/* set GPIO port 'gp' as an output, with polarity 'value' */
+int gpio_direction_output(unsigned gp, int value)
+{
+ debug("%s: gp:%u, value = %d\n", __func__, gp, value);
+
+ if (check_reserved(gp, __func__))
+ return -1;
+
+ return sandbox_gpio_set_direction(gp, 1) |
+ sandbox_gpio_set_value(gp, value);
+}
+
+/* read GPIO IN value of port 'gp' */
+int gpio_get_value(unsigned gp)
+{
+ debug("%s: gp:%u\n", __func__, gp);
+
+ if (check_reserved(gp, __func__))
+ return -1;
+
+ return sandbox_gpio_get_value(gp);
+}
+
+/* write GPIO OUT value to port 'gp' */
+int gpio_set_value(unsigned gp, int value)
+{
+ debug("%s: gp:%u, value = %d\n", __func__, gp, value);
+
+ if (check_reserved(gp, __func__))
+ return -1;
+
+ if (!sandbox_gpio_get_direction(gp)) {
+ printf("sandbox_gpio: error: set_value on input gpio %u\n", gp);
+ return -1;
+ }
+
+ return sandbox_gpio_set_value(gp, value);
+}
+
+int gpio_request(unsigned gp, const char *label)
+{
+ debug("%s: gp:%u, label:%s\n", __func__, gp, label);
+
+ if (gp >= ARRAY_SIZE(state)) {
+ printf("sandbox_gpio: error: invalid gpio %u\n", gp);
+ return -1;
+ }
+
+ if (get_gpio_flag(gp, GPIOF_RESERVED)) {
+ printf("sandbox_gpio: error: gpio %u already reserved\n", gp);
+ return -1;
+ }
+
+ state[gp].label = label;
+ return set_gpio_flag(gp, GPIOF_RESERVED, 1);
+}
+
+int gpio_free(unsigned gp)
+{
+ debug("%s: gp:%u\n", __func__, gp);
+
+ if (check_reserved(gp, __func__))
+ return -1;
+
+ state[gp].label = NULL;
+ return set_gpio_flag(gp, GPIOF_RESERVED, 0);
+}
+
+/* Display GPIO information */
+void gpio_info(void)
+{
+ unsigned gpio;
+
+ puts("Sandbox GPIOs\n");
+
+ for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) {
+ const char *label = state[gpio].label;
+
+ printf("%4d: %s: %d [%c] %s\n",
+ gpio,
+ sandbox_gpio_get_direction(gpio) ? "out" : " in",
+ sandbox_gpio_get_value(gpio),
+ get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ',
+ label ? label : "");
+ }
+}
COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
+COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o
COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
DECLARE_GLOBAL_DATA_PTR;
-#define I2C_STAT_TIMEO (1 << 31)
-#define I2C_TIMEOUT 10
+#define I2C_TIMEOUT 1000
-static u32 wait_for_bb(void);
-static u32 wait_for_status_mask(u16 mask);
+static void wait_for_bb(void);
+static u16 wait_for_pin(void);
static void flush_fifo(void);
/*
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) &&
sclh = (unsigned int)fssclh;
}
- if (gd->flags & GD_FLG_RELOC)
- bus_initialized[current_bus] = 1;
-
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) {
+ puts("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);
flush_fifo();
writew(0xFFFF, &i2c_base->stat);
writew(0, &i2c_base->cnt);
+
+ if (gd->flags & GD_FLG_RELOC)
+ bus_initialized[current_bus] = 1;
+}
+
+static int i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
+{
+ int i2c_error = 0;
+ u16 status;
+
+ /* wait until bus not busy */
+ wait_for_bb();
+
+ /* one byte only */
+ writew(1, &i2c_base->cnt);
+ /* set slave address */
+ writew(devaddr, &i2c_base->sa);
+ /* no stop bit needed here */
+ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+ I2C_CON_TRX, &i2c_base->con);
+
+ /* send register offset */
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+ goto read_exit;
+ }
+ if (status & I2C_STAT_XRDY) {
+ /* Important: have to use byte access */
+ writeb(regoffset, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
+ }
+ }
+
+ /* set slave address */
+ writew(devaddr, &i2c_base->sa);
+ /* read one byte from slave */
+ writew(1, &i2c_base->cnt);
+ /* need stop bit here */
+ writew(I2C_CON_EN | I2C_CON_MST |
+ I2C_CON_STT | I2C_CON_STP,
+ &i2c_base->con);
+
+ /* receive data */
+ while (1) {
+ status = wait_for_pin();
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+ goto read_exit;
+ }
+ if (status & I2C_STAT_RRDY) {
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
+ defined(CONFIG_OMAP44XX)
+ *value = readb(&i2c_base->data);
+#else
+ *value = readw(&i2c_base->data);
+#endif
+ writew(I2C_STAT_RRDY, &i2c_base->stat);
+ }
+ if (status & I2C_STAT_ARDY) {
+ writew(I2C_STAT_ARDY, &i2c_base->stat);
+ break;
+ }
+ }
+
+read_exit:
+ flush_fifo();
+ writew(0xFFFF, &i2c_base->stat);
+ writew(0, &i2c_base->cnt);
+ return i2c_error;
}
static void flush_fifo(void)
stat = readw(&i2c_base->stat);
if (stat == I2C_STAT_RRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX)
+ defined(CONFIG_OMAP44XX)
readb(&i2c_base->data);
#else
readw(&i2c_base->data);
int i2c_probe(uchar chip)
{
- u32 status;
+ u16 status;
int res = 1; /* default = fail */
if (chip == readw(&i2c_base->oa))
return res;
/* wait until bus not busy */
- status = wait_for_bb();
- /* exit on BUS busy */
- if (status & I2C_STAT_TIMEO)
- return res;
+ wait_for_bb();
/* try to write one byte */
writew(1, &i2c_base->cnt);
/* set slave address */
writew(chip, &i2c_base->sa);
/* stop bit needed here */
- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT
- | I2C_CON_STP, &i2c_base->con);
- /* enough delay for the NACK bit set */
- udelay(9000);
-
- if (!(readw(&i2c_base->stat) & I2C_STAT_NACK)) {
- res = 0; /* success case */
- flush_fifo();
- writew(0xFFFF, &i2c_base->stat);
- } else {
- /* failure, clear sources*/
- writew(0xFFFF, &i2c_base->stat);
- /* finish up xfer */
- writew(readw(&i2c_base->con) | I2C_CON_STP, &i2c_base->con);
- status = wait_for_bb();
- /* exit on BUS busy */
- if (status & I2C_STAT_TIMEO)
- return res;
- }
+ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+ I2C_CON_STP, &i2c_base->con);
+
+ status = wait_for_pin();
+
+ /* check for ACK (!NAK) */
+ if (!(status & I2C_STAT_NACK))
+ res = 0;
+
+ /* abort transfer (force idle state) */
+ writew(0, &i2c_base->con);
+
flush_fifo();
/* don't allow any more data in... we don't want it. */
writew(0, &i2c_base->cnt);
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
- int i2c_error = 0, i;
- u32 status;
+ int i;
- if ((alen > 2) || (alen < 0))
- return 1;
-
- if (alen < 2) {
- if (addr + len > 256)
- return 1;
- } else if (addr + len > 0xFFFF) {
+ if (alen > 1) {
+ printf("I2C read: addr len %d not supported\n", alen);
return 1;
}
- /* wait until bus not busy */
- status = wait_for_bb();
-
- /* exit on BUS busy */
- if (status & I2C_STAT_TIMEO)
+ if (addr + len > 256) {
+ puts("I2C read: address out of range\n");
return 1;
-
- writew((alen & 0xFF), &i2c_base->cnt);
- /* set slave address */
- writew(chip, &i2c_base->sa);
- /* Clear the Tx & Rx FIFOs */
- writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR |
- I2C_TXFIFO_CLEAR), &i2c_base->buf);
- /* no stop bit needed here */
- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX |
- I2C_CON_STT, &i2c_base->con);
-
- /* wait for Transmit ready condition */
- status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
-
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO))
- i2c_error = 1;
-
- if (!i2c_error) {
- if (status & I2C_STAT_XRDY) {
- switch (alen) {
- case 2:
- /* Send address MSByte */
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- writew(((addr >> 8) & 0xFF), &i2c_base->data);
-
- /* Clearing XRDY event */
- writew((status & I2C_STAT_XRDY),
- &i2c_base->stat);
- /* wait for Transmit ready condition */
- status = wait_for_status_mask(I2C_STAT_XRDY |
- I2C_STAT_NACK);
-
- if (status & (I2C_STAT_NACK |
- I2C_STAT_TIMEO)) {
- i2c_error = 1;
- break;
- }
-#endif
- case 1:
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- /* Send address LSByte */
- writew((addr & 0xFF), &i2c_base->data);
-#else
- /* Send address Short word */
- writew((addr & 0xFFFF), &i2c_base->data);
-#endif
- /* Clearing XRDY event */
- writew((status & I2C_STAT_XRDY),
- &i2c_base->stat);
- /*wait for Transmit ready condition */
- status = wait_for_status_mask(I2C_STAT_ARDY |
- I2C_STAT_NACK);
-
- if (status & (I2C_STAT_NACK |
- I2C_STAT_TIMEO)) {
- i2c_error = 1;
- break;
- }
- }
- } else
- i2c_error = 1;
}
- /* Wait for ARDY to set */
- status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK
- | I2C_STAT_AL);
-
- if (!i2c_error) {
- /* set slave address */
- writew(chip, &i2c_base->sa);
- writew((len & 0xFF), &i2c_base->cnt);
- /* Clear the Tx & Rx FIFOs */
- writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR |
- I2C_TXFIFO_CLEAR), &i2c_base->buf);
- /* need stop bit here */
- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
- &i2c_base->con);
-
- for (i = 0; i < len; i++) {
- /* wait for Receive condition */
- status = wait_for_status_mask(I2C_STAT_RRDY |
- I2C_STAT_NACK);
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) {
- i2c_error = 1;
- break;
- }
-
- if (status & I2C_STAT_RRDY) {
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- buffer[i] = readb(&i2c_base->data);
-#else
- *((u16 *)&buffer[i]) =
- readw(&i2c_base->data) & 0xFFFF;
- i++;
-#endif
- writew((status & I2C_STAT_RRDY),
- &i2c_base->stat);
- udelay(1000);
- } else {
- i2c_error = 1;
- }
+ for (i = 0; i < len; i++) {
+ if (i2c_read_byte(chip, addr + i, &buffer[i])) {
+ puts("I2C read: I/O error\n");
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ return 1;
}
}
- /* Wait for ARDY to set */
- status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK
- | I2C_STAT_AL);
-
- if (i2c_error) {
- writew(0, &i2c_base->con);
- return 1;
- }
-
- writew(I2C_CON_EN, &i2c_base->con);
-
- while (readw(&i2c_base->stat)
- || (readw(&i2c_base->con) & I2C_CON_MST)) {
- udelay(10000);
- writew(0xFFFF, &i2c_base->stat);
- }
-
- writew(I2C_CON_EN, &i2c_base->con);
- flush_fifo();
- writew(0xFFFF, &i2c_base->stat);
- writew(0, &i2c_base->cnt);
-
return 0;
}
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
+ int i;
+ u16 status;
+ int i2c_error = 0;
- int i, i2c_error = 0;
- u32 status;
- u16 writelen;
-
- if (alen > 2)
+ if (alen > 1) {
+ printf("I2C write: addr len %d not supported\n", alen);
return 1;
+ }
- if (alen < 2) {
- if (addr + len > 256)
- return 1;
- } else if (addr + len > 0xFFFF) {
+ if (addr + len > 256) {
+ printf("I2C write: address 0x%x + 0x%x out of range\n",
+ addr, len);
return 1;
}
/* wait until bus not busy */
- status = wait_for_bb();
+ wait_for_bb();
- /* exiting on BUS busy */
- if (status & I2C_STAT_TIMEO)
- return 1;
-
- writelen = (len & 0xFFFF) + alen;
-
- /* two bytes */
- writew((writelen & 0xFFFF), &i2c_base->cnt);
- /* Clear the Tx & Rx FIFOs */
- writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR |
- I2C_TXFIFO_CLEAR), &i2c_base->buf);
+ /* start address phase - will write regoffset + len bytes data */
+ /* TODO consider case when !CONFIG_OMAP243X/34XX/44XX */
+ writew(alen + len, &i2c_base->cnt);
/* set slave address */
writew(chip, &i2c_base->sa);
/* stop bit needed here */
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
I2C_CON_STP, &i2c_base->con);
- /* wait for Transmit ready condition */
- status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
+ /* Send address byte */
+ status = wait_for_pin();
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO))
+ if (status == 0 || status & I2C_STAT_NACK) {
i2c_error = 1;
-
- if (!i2c_error) {
- if (status & I2C_STAT_XRDY) {
- switch (alen) {
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- case 2:
- /* send out MSB byte */
- writeb(((addr >> 8) & 0xFF), &i2c_base->data);
-#else
- writeb((addr & 0xFFFF), &i2c_base->data);
- break;
-#endif
- /* Clearing XRDY event */
- writew((status & I2C_STAT_XRDY),
- &i2c_base->stat);
- /*waiting for Transmit ready * condition */
- status = wait_for_status_mask(I2C_STAT_XRDY |
- I2C_STAT_NACK);
-
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) {
- i2c_error = 1;
- break;
- }
- case 1:
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- /* send out MSB byte */
- writeb((addr & 0xFF), &i2c_base->data);
-#else
- writew(((buffer[0] << 8) | (addr & 0xFF)),
- &i2c_base->data);
-#endif
- }
-
- /* Clearing XRDY event */
- writew((status & I2C_STAT_XRDY), &i2c_base->stat);
- }
-
- /* waiting for Transmit ready condition */
- status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK);
-
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO))
- i2c_error = 1;
-
- if (!i2c_error) {
- for (i = ((alen > 1) ? 0 : 1); i < len; i++) {
- if (status & I2C_STAT_XRDY) {
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
- defined(CONFIG_AM33XX)
- writeb((buffer[i] & 0xFF),
- &i2c_base->data);
-#else
- writew((((buffer[i] << 8) |
- buffer[i + 1]) & 0xFFFF),
- &i2c_base->data);
- i++;
-#endif
- } else
- i2c_error = 1;
- /* Clearing XRDY event */
- writew((status & I2C_STAT_XRDY),
- &i2c_base->stat);
- /* waiting for XRDY condition */
- status = wait_for_status_mask(
- I2C_STAT_XRDY |
- I2C_STAT_ARDY |
- I2C_STAT_NACK);
- if (status & (I2C_STAT_NACK |
- I2C_STAT_TIMEO)) {
- i2c_error = 1;
- break;
- }
- if (status & I2C_STAT_ARDY)
- break;
- }
- }
+ printf("error waiting for i2c address ACK (status=0x%x)\n",
+ status);
+ goto write_exit;
}
- status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK |
- I2C_STAT_AL);
-
- if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO))
+ if (status & I2C_STAT_XRDY) {
+ writeb(addr & 0xFF, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ } else {
i2c_error = 1;
-
- if (i2c_error) {
- writew(0, &i2c_base->con);
- return 1;
+ printf("i2c bus not ready for transmit (status=0x%x)\n",
+ status);
+ goto write_exit;
}
- if (!i2c_error) {
- int eout = 200;
+ /* address phase is over, now write data */
+ for (i = 0; i < len; i++) {
+ status = wait_for_pin();
- writew(I2C_CON_EN, &i2c_base->con);
- while ((status = readw(&i2c_base->stat)) ||
- (readw(&i2c_base->con) & I2C_CON_MST)) {
- udelay(1000);
- /* have to read to clear intrrupt */
- writew(0xFFFF, &i2c_base->stat);
- if (--eout == 0)
- /* better leave with error than hang */
- break;
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+ printf("i2c error waiting for data ACK (status=0x%x)\n",
+ status);
+ goto write_exit;
+ }
+
+ if (status & I2C_STAT_XRDY) {
+ writeb(buffer[i], &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ } else {
+ i2c_error = 1;
+ printf("i2c bus not ready for Tx (i=%d)\n", i);
+ goto write_exit;
}
}
+write_exit:
flush_fifo();
writew(0xFFFF, &i2c_base->stat);
- writew(0, &i2c_base->cnt);
- return 0;
+ return i2c_error;
}
-static u32 wait_for_bb(void)
+static void wait_for_bb(void)
{
int timeout = I2C_TIMEOUT;
- u32 stat;
+ u16 stat;
+ writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/
while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
writew(stat, &i2c_base->stat);
udelay(1000);
if (timeout <= 0) {
printf("timed out in wait_for_bb: I2C_STAT=%x\n",
readw(&i2c_base->stat));
- stat |= I2C_STAT_TIMEO;
}
writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/
- return stat;
}
-static u32 wait_for_status_mask(u16 mask)
+static u16 wait_for_pin(void)
{
- u32 status;
+ u16 status;
int timeout = I2C_TIMEOUT;
do {
udelay(1000);
status = readw(&i2c_base->stat);
- } while (!(status & mask) && timeout--);
+ } while (!(status &
+ (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+ I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+ I2C_STAT_AL)) && timeout--);
if (timeout <= 0) {
- printf("timed out in wait_for_status_mask: I2C_STAT=%x\n",
+ printf("timed out in wait_for_pin: I2C_STAT=%x\n",
readw(&i2c_base->stat));
writew(0xFFFF, &i2c_base->stat);
- status |= I2C_STAT_TIMEO;
+ status = 0;
}
+
return status;
}
/* I2C Buffer Configuration Register (I2C_BUF): */
#define I2C_BUF_RDMA_EN (1 << 15) /* Receive DMA channel enable */
-#define I2C_RXFIFO_CLEAR (1 << 14) /* RX FIFO Clear */
#define I2C_BUF_XDMA_EN (1 << 7) /* Transmit DMA channel enable */
-#define I2C_TXFIFO_CLEAR (1 << 6) /* TX FIFO clear */
/* I2C Configuration Register (I2C_CON): */
--- /dev/null
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Copyright (c) 2010-2011 NVIDIA Corporation
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra_i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned int i2c_bus_num;
+
+/* Information about i2c controller */
+struct i2c_bus {
+ int id;
+ enum periph_id periph_id;
+ int speed;
+ int pinmux_config;
+ struct i2c_control *control;
+ struct i2c_ctlr *regs;
+ int is_dvc; /* DVC type, rather than I2C */
+ int inited; /* bus is inited */
+};
+
+static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS];
+
+static void set_packet_mode(struct i2c_bus *i2c_bus)
+{
+ u32 config;
+
+ config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK;
+
+ if (i2c_bus->is_dvc) {
+ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
+
+ writel(config, &dvc->cnfg);
+ } else {
+ writel(config, &i2c_bus->regs->cnfg);
+ /*
+ * program I2C_SL_CNFG.NEWSL to ENABLE. This fixes probe
+ * issues, i.e., some slaves may be wrongly detected.
+ */
+ setbits_le32(&i2c_bus->regs->sl_cnfg, I2C_SL_CNFG_NEWSL_MASK);
+ }
+}
+
+static void i2c_reset_controller(struct i2c_bus *i2c_bus)
+{
+ /* Reset I2C controller. */
+ reset_periph(i2c_bus->periph_id, 1);
+
+ /* re-program config register to packet mode */
+ set_packet_mode(i2c_bus);
+}
+
+static void i2c_init_controller(struct i2c_bus *i2c_bus)
+{
+ /*
+ * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8
+ * here, in section 23.3.1, but in fact we seem to need a factor of
+ * 16 to get the right frequency.
+ */
+ clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
+ i2c_bus->speed * 2 * 8);
+
+ /* Reset I2C controller. */
+ i2c_reset_controller(i2c_bus);
+
+ /* Configure I2C controller. */
+ if (i2c_bus->is_dvc) { /* only for DVC I2C */
+ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
+
+ setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK);
+ }
+
+ funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config);
+}
+
+static void send_packet_headers(
+ struct i2c_bus *i2c_bus,
+ struct i2c_trans_info *trans,
+ u32 packet_id)
+{
+ u32 data;
+
+ /* prepare header1: Header size = 0 Protocol = I2C, pktType = 0 */
+ data = PROTOCOL_TYPE_I2C << PKT_HDR1_PROTOCOL_SHIFT;
+ data |= packet_id << PKT_HDR1_PKT_ID_SHIFT;
+ data |= i2c_bus->id << PKT_HDR1_CTLR_ID_SHIFT;
+ writel(data, &i2c_bus->control->tx_fifo);
+ debug("pkt header 1 sent (0x%x)\n", data);
+
+ /* prepare header2 */
+ data = (trans->num_bytes - 1) << PKT_HDR2_PAYLOAD_SIZE_SHIFT;
+ writel(data, &i2c_bus->control->tx_fifo);
+ debug("pkt header 2 sent (0x%x)\n", data);
+
+ /* prepare IO specific header: configure the slave address */
+ data = trans->address << PKT_HDR3_SLAVE_ADDR_SHIFT;
+
+ /* Enable Read if it is not a write transaction */
+ if (!(trans->flags & I2C_IS_WRITE))
+ data |= PKT_HDR3_READ_MODE_MASK;
+
+ /* Write I2C specific header */
+ writel(data, &i2c_bus->control->tx_fifo);
+ debug("pkt header 3 sent (0x%x)\n", data);
+}
+
+static int wait_for_tx_fifo_empty(struct i2c_control *control)
+{
+ u32 count;
+ int timeout_us = I2C_TIMEOUT_USEC;
+
+ while (timeout_us >= 0) {
+ count = (readl(&control->fifo_status) & TX_FIFO_EMPTY_CNT_MASK)
+ >> TX_FIFO_EMPTY_CNT_SHIFT;
+ if (count == I2C_FIFO_DEPTH)
+ return 1;
+ udelay(10);
+ timeout_us -= 10;
+ }
+
+ return 0;
+}
+
+static int wait_for_rx_fifo_notempty(struct i2c_control *control)
+{
+ u32 count;
+ int timeout_us = I2C_TIMEOUT_USEC;
+
+ while (timeout_us >= 0) {
+ count = (readl(&control->fifo_status) & TX_FIFO_FULL_CNT_MASK)
+ >> TX_FIFO_FULL_CNT_SHIFT;
+ if (count)
+ return 1;
+ udelay(10);
+ timeout_us -= 10;
+ }
+
+ return 0;
+}
+
+static int wait_for_transfer_complete(struct i2c_control *control)
+{
+ int int_status;
+ int timeout_us = I2C_TIMEOUT_USEC;
+
+ while (timeout_us >= 0) {
+ int_status = readl(&control->int_status);
+ if (int_status & I2C_INT_NO_ACK_MASK)
+ return -int_status;
+ if (int_status & I2C_INT_ARBITRATION_LOST_MASK)
+ return -int_status;
+ if (int_status & I2C_INT_XFER_COMPLETE_MASK)
+ return 0;
+
+ udelay(10);
+ timeout_us -= 10;
+ }
+
+ return -1;
+}
+
+static int send_recv_packets(struct i2c_bus *i2c_bus,
+ struct i2c_trans_info *trans)
+{
+ struct i2c_control *control = i2c_bus->control;
+ u32 int_status;
+ u32 words;
+ u8 *dptr;
+ u32 local;
+ uchar last_bytes;
+ int error = 0;
+ int is_write = trans->flags & I2C_IS_WRITE;
+
+ /* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */
+ int_status = readl(&control->int_status);
+ writel(int_status, &control->int_status);
+
+ send_packet_headers(i2c_bus, trans, 1);
+
+ words = DIV_ROUND_UP(trans->num_bytes, 4);
+ last_bytes = trans->num_bytes & 3;
+ dptr = trans->buf;
+
+ while (words) {
+ u32 *wptr = (u32 *)dptr;
+
+ if (is_write) {
+ /* deal with word alignment */
+ if ((unsigned)dptr & 3) {
+ memcpy(&local, dptr, sizeof(u32));
+ writel(local, &control->tx_fifo);
+ debug("pkt data sent (0x%x)\n", local);
+ } else {
+ writel(*wptr, &control->tx_fifo);
+ debug("pkt data sent (0x%x)\n", *wptr);
+ }
+ if (!wait_for_tx_fifo_empty(control)) {
+ error = -1;
+ goto exit;
+ }
+ } else {
+ if (!wait_for_rx_fifo_notempty(control)) {
+ error = -1;
+ goto exit;
+ }
+ /*
+ * for the last word, we read into our local buffer,
+ * in case that caller did not provide enough buffer.
+ */
+ local = readl(&control->rx_fifo);
+ if ((words == 1) && last_bytes)
+ memcpy(dptr, (char *)&local, last_bytes);
+ else if ((unsigned)dptr & 3)
+ memcpy(dptr, &local, sizeof(u32));
+ else
+ *wptr = local;
+ debug("pkt data received (0x%x)\n", local);
+ }
+ words--;
+ dptr += sizeof(u32);
+ }
+
+ if (wait_for_transfer_complete(control)) {
+ error = -1;
+ goto exit;
+ }
+ return 0;
+exit:
+ /* error, reset the controller. */
+ i2c_reset_controller(i2c_bus);
+
+ return error;
+}
+
+static int tegra2_i2c_write_data(u32 addr, u8 *data, u32 len)
+{
+ int error;
+ struct i2c_trans_info trans_info;
+
+ trans_info.address = addr;
+ trans_info.buf = data;
+ trans_info.flags = I2C_IS_WRITE;
+ trans_info.num_bytes = len;
+ trans_info.is_10bit_address = 0;
+
+ error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
+ if (error)
+ debug("tegra2_i2c_write_data: Error (%d) !!!\n", error);
+
+ return error;
+}
+
+static int tegra2_i2c_read_data(u32 addr, u8 *data, u32 len)
+{
+ int error;
+ struct i2c_trans_info trans_info;
+
+ trans_info.address = addr | 1;
+ trans_info.buf = data;
+ trans_info.flags = 0;
+ trans_info.num_bytes = len;
+ trans_info.is_10bit_address = 0;
+
+ error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
+ if (error)
+ debug("tegra2_i2c_read_data: Error (%d) !!!\n", error);
+
+ return error;
+}
+
+#ifndef CONFIG_OF_CONTROL
+#error "Please enable device tree support to use this driver"
+#endif
+
+unsigned int i2c_get_bus_speed(void)
+{
+ return i2c_controllers[i2c_bus_num].speed;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+ struct i2c_bus *i2c_bus;
+
+ i2c_bus = &i2c_controllers[i2c_bus_num];
+ i2c_bus->speed = speed;
+ i2c_init_controller(i2c_bus);
+
+ return 0;
+}
+
+static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
+{
+ i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
+
+ /*
+ * We don't have a binding for pinmux yet. Leave it out for now. So
+ * far no one needs anything other than the default.
+ */
+ i2c_bus->pinmux_config = FUNCMUX_DEFAULT;
+ i2c_bus->speed = fdtdec_get_int(blob, node, "clock-frequency", 0);
+ i2c_bus->periph_id = clock_decode_periph_id(blob, node);
+
+ /*
+ * We can't specify the pinmux config in the fdt, so I2C2 will not
+ * work on Seaboard. It normally has no devices on it anyway.
+ * You could add in this little hack if you need to use it.
+ * The correct solution is a pinmux binding in the fdt.
+ *
+ * if (i2c_bus->periph_id == PERIPH_ID_I2C2)
+ * i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
+ */
+ if (i2c_bus->periph_id == -1)
+ return -FDT_ERR_NOTFOUND;
+
+ return 0;
+}
+
+/*
+ * Process a list of nodes, adding them to our list of I2C ports.
+ *
+ * @param blob fdt blob
+ * @param node_list list of nodes to process (any <=0 are ignored)
+ * @param count number of nodes to process
+ * @param is_dvc 1 if these are DVC ports, 0 if standard I2C
+ * @return 0 if ok, -1 on error
+ */
+static int process_nodes(const void *blob, int node_list[], int count,
+ int is_dvc)
+{
+ struct i2c_bus *i2c_bus;
+ int i;
+
+ /* build the i2c_controllers[] for each controller */
+ for (i = 0; i < count; i++) {
+ int node = node_list[i];
+
+ if (node <= 0)
+ continue;
+
+ i2c_bus = &i2c_controllers[i];
+ i2c_bus->id = i;
+
+ if (i2c_get_config(blob, node, i2c_bus)) {
+ printf("i2c_init_board: failed to decode bus %d\n", i);
+ return -1;
+ }
+
+ i2c_bus->is_dvc = is_dvc;
+ if (is_dvc) {
+ i2c_bus->control =
+ &((struct dvc_ctlr *)i2c_bus->regs)->control;
+ } else {
+ i2c_bus->control = &i2c_bus->regs->control;
+ }
+ debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
+ is_dvc ? "dvc" : "i2c", i, i2c_bus->regs,
+ i2c_bus->periph_id, i2c_bus->speed);
+ i2c_init_controller(i2c_bus);
+ debug("ok\n");
+ i2c_bus->inited = 1;
+
+ /* Mark position as used */
+ node_list[i] = -1;
+ }
+
+ return 0;
+}
+
+/* Sadly there is no error return from this function */
+void i2c_init_board(void)
+{
+ int node_list[TEGRA_I2C_NUM_CONTROLLERS];
+ const void *blob = gd->fdt_blob;
+ int count;
+
+ /* First get the normal i2c ports */
+ count = fdtdec_find_aliases_for_id(blob, "i2c",
+ COMPAT_NVIDIA_TEGRA20_I2C, node_list,
+ TEGRA_I2C_NUM_CONTROLLERS);
+ if (process_nodes(blob, node_list, count, 0))
+ return;
+
+ /* Now look for dvc ports */
+ count = fdtdec_add_aliases_for_id(blob, "i2c",
+ COMPAT_NVIDIA_TEGRA20_DVC, node_list,
+ TEGRA_I2C_NUM_CONTROLLERS);
+ if (process_nodes(blob, node_list, count, 1))
+ return;
+}
+
+void i2c_init(int speed, int slaveaddr)
+{
+ /* This will override the speed selected in the fdt for that port */
+ debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
+ i2c_set_bus_speed(speed);
+}
+
+/* i2c write version without the register address */
+int i2c_write_data(uchar chip, uchar *buffer, int len)
+{
+ int rc;
+
+ debug("i2c_write_data: chip=0x%x, len=0x%x\n", chip, len);
+ debug("write_data: ");
+ /* use rc for counter */
+ for (rc = 0; rc < len; ++rc)
+ debug(" 0x%02x", buffer[rc]);
+ debug("\n");
+
+ /* Shift 7-bit address over for lower-level i2c functions */
+ rc = tegra2_i2c_write_data(chip << 1, buffer, len);
+ if (rc)
+ debug("i2c_write_data(): rc=%d\n", rc);
+
+ return rc;
+}
+
+/* i2c read version without the register address */
+int i2c_read_data(uchar chip, uchar *buffer, int len)
+{
+ int rc;
+
+ debug("inside i2c_read_data():\n");
+ /* Shift 7-bit address over for lower-level i2c functions */
+ rc = tegra2_i2c_read_data(chip << 1, buffer, len);
+ if (rc) {
+ debug("i2c_read_data(): rc=%d\n", rc);
+ return rc;
+ }
+
+ debug("i2c_read_data: ");
+ /* reuse rc for counter*/
+ for (rc = 0; rc < len; ++rc)
+ debug(" 0x%02x", buffer[rc]);
+ debug("\n");
+
+ return 0;
+}
+
+/* Probe to see if a chip is present. */
+int i2c_probe(uchar chip)
+{
+ int rc;
+ uchar reg;
+
+ debug("i2c_probe: addr=0x%x\n", chip);
+ reg = 0;
+ rc = i2c_write_data(chip, ®, 1);
+ if (rc) {
+ debug("Error probing 0x%x.\n", chip);
+ return 1;
+ }
+ return 0;
+}
+
+static int i2c_addr_ok(const uint addr, const int alen)
+{
+ /* We support 7 or 10 bit addresses, so one or two bytes each */
+ return alen == 1 || alen == 2;
+}
+
+/* Read bytes */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ uint offset;
+ int i;
+
+ debug("i2c_read: chip=0x%x, addr=0x%x, len=0x%x\n",
+ chip, addr, len);
+ if (!i2c_addr_ok(addr, alen)) {
+ debug("i2c_read: Bad address %x.%d.\n", addr, alen);
+ return 1;
+ }
+ for (offset = 0; offset < len; offset++) {
+ if (alen) {
+ uchar data[alen];
+ for (i = 0; i < alen; i++) {
+ data[alen - i - 1] =
+ (addr + offset) >> (8 * i);
+ }
+ if (i2c_write_data(chip, data, alen)) {
+ debug("i2c_read: error sending (0x%x)\n",
+ addr);
+ return 1;
+ }
+ }
+ if (i2c_read_data(chip, buffer + offset, 1)) {
+ debug("i2c_read: error reading (0x%x)\n", addr);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Write bytes */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ uint offset;
+ int i;
+
+ debug("i2c_write: chip=0x%x, addr=0x%x, len=0x%x\n",
+ chip, addr, len);
+ if (!i2c_addr_ok(addr, alen)) {
+ debug("i2c_write: Bad address %x.%d.\n", addr, alen);
+ return 1;
+ }
+ for (offset = 0; offset < len; offset++) {
+ uchar data[alen + 1];
+ for (i = 0; i < alen; i++)
+ data[alen - i - 1] = (addr + offset) >> (8 * i);
+ data[alen] = buffer[offset];
+ if (i2c_write_data(chip, data, alen + 1)) {
+ debug("i2c_write: error sending (0x%x)\n", addr);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_I2C_MULTI_BUS)
+/*
+ * Functions for multiple I2C bus handling
+ */
+unsigned int i2c_get_bus_num(void)
+{
+ return i2c_bus_num;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+ if (bus >= TEGRA_I2C_NUM_CONTROLLERS || !i2c_controllers[bus].inited)
+ return -1;
+ i2c_bus_num = bus;
+
+ return 0;
+}
+#endif
case 1:
buf[0] = val & 0xff;
break;
+ default:
+ printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
+ return -1;
}
if (i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num))
case 1:
ret_val = buf[0];
break;
+ default:
+ printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
+ return -1;
}
memcpy(val, &ret_val, sizeof(ret_val));
LIB := $(obj)libmmc.o
-COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
+++ /dev/null
-/*
- * Copyright (C) 2004-2006 Atmel Corporation
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#include <common.h>
-
-#include <part.h>
-#include <mmc.h>
-
-#include <asm/io.h>
-#include <asm/errno.h>
-#include <asm/byteorder.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/hardware.h>
-
-#include "atmel_mci.h"
-
-#ifdef DEBUG
-#define pr_debug(fmt, args...) printf(fmt, ##args)
-#else
-#define pr_debug(...) do { } while(0)
-#endif
-
-#ifndef CONFIG_SYS_MMC_CLK_OD
-#define CONFIG_SYS_MMC_CLK_OD 150000
-#endif
-
-#ifndef CONFIG_SYS_MMC_CLK_PP
-#define CONFIG_SYS_MMC_CLK_PP 5000000
-#endif
-
-#ifndef CONFIG_SYS_MMC_OP_COND
-#define CONFIG_SYS_MMC_OP_COND 0x00100000
-#endif
-
-#define MMC_DEFAULT_BLKLEN 512
-#define MMC_DEFAULT_RCA 1
-
-static unsigned int mmc_rca;
-static int mmc_card_is_sd;
-static block_dev_desc_t mmc_blkdev;
-
-block_dev_desc_t *mmc_get_dev(int dev)
-{
- return &mmc_blkdev;
-}
-
-static void mci_set_mode(unsigned long hz, unsigned long blklen)
-{
- unsigned long bus_hz;
- unsigned long clkdiv;
-
- bus_hz = get_mci_clk_rate();
- clkdiv = (bus_hz / hz) / 2 - 1;
-
- pr_debug("mmc: setting clock %lu Hz, block size %lu\n",
- hz, blklen);
-
- if (clkdiv & ~255UL) {
- clkdiv = 255;
- printf("mmc: clock %lu too low; setting CLKDIV to 255\n",
- hz);
- }
-
- blklen &= 0xfffc;
- mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv)
- | MMCI_BF(BLKLEN, blklen)
- | MMCI_BIT(RDPROOF)
- | MMCI_BIT(WRPROOF)));
-}
-
-#define RESP_NO_CRC 1
-#define R1 MMCI_BF(RSPTYP, 1)
-#define R2 MMCI_BF(RSPTYP, 2)
-#define R3 (R1 | RESP_NO_CRC)
-#define R6 R1
-#define NID MMCI_BF(MAXLAT, 0)
-#define NCR MMCI_BF(MAXLAT, 1)
-#define TRCMD_START MMCI_BF(TRCMD, 1)
-#define TRDIR_READ MMCI_BF(TRDIR, 1)
-#define TRTYP_BLOCK MMCI_BF(TRTYP, 0)
-#define INIT_CMD MMCI_BF(SPCMD, 1)
-#define OPEN_DRAIN MMCI_BF(OPDCMD, 1)
-
-#define ERROR_FLAGS (MMCI_BIT(DTOE) \
- | MMCI_BIT(RDIRE) \
- | MMCI_BIT(RENDE) \
- | MMCI_BIT(RINDE) \
- | MMCI_BIT(RTOE))
-
-static int
-mmc_cmd(unsigned long cmd, unsigned long arg,
- void *resp, unsigned long flags)
-{
- unsigned long *response = resp;
- int i, response_words = 0;
- unsigned long error_flags;
- u32 status;
-
- pr_debug("mmc: CMD%lu 0x%lx (flags 0x%lx)\n",
- cmd, arg, flags);
-
- error_flags = ERROR_FLAGS;
- if (!(flags & RESP_NO_CRC))
- error_flags |= MMCI_BIT(RCRCE);
-
- flags &= ~MMCI_BF(CMDNB, ~0UL);
-
- if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_48_BIT_RESP)
- response_words = 1;
- else if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_136_BIT_RESP)
- response_words = 4;
-
- mmci_writel(ARGR, arg);
- mmci_writel(CMDR, cmd | flags);
- do {
- udelay(40);
- status = mmci_readl(SR);
- } while (!(status & MMCI_BIT(CMDRDY)));
-
- pr_debug("mmc: status 0x%08x\n", status);
-
- if (status & error_flags) {
- printf("mmc: command %lu failed (status: 0x%08x)\n",
- cmd, status);
- return -EIO;
- }
-
- if (response_words)
- pr_debug("mmc: response:");
-
- for (i = 0; i < response_words; i++) {
- response[i] = mmci_readl(RSPR);
- pr_debug(" %08lx", response[i]);
- }
- pr_debug("\n");
-
- return 0;
-}
-
-static int mmc_acmd(unsigned long cmd, unsigned long arg,
- void *resp, unsigned long flags)
-{
- unsigned long aresp[4];
- int ret;
-
- /*
- * Seems like the APP_CMD part of an ACMD has 64 cycles max
- * latency even though the ACMD part doesn't. This isn't
- * entirely clear in the SD Card spec, but some cards refuse
- * to work if we attempt to use 5 cycles max latency here...
- */
- ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp,
- R1 | NCR | (flags & OPEN_DRAIN));
- if (ret)
- return ret;
- if ((aresp[0] & (R1_ILLEGAL_COMMAND | R1_APP_CMD)) != R1_APP_CMD)
- return -ENODEV;
-
- ret = mmc_cmd(cmd, arg, resp, flags);
- return ret;
-}
-
-static unsigned long
-mmc_bread(int dev, unsigned long start, lbaint_t blkcnt,
- void *buffer)
-{
- int ret, i = 0;
- unsigned long resp[4];
- unsigned long card_status, data;
- unsigned long wordcount;
- u32 *p = buffer;
- u32 status;
-
- if (blkcnt == 0)
- return 0;
-
- pr_debug("mmc_bread: dev %d, start %lx, blkcnt %lx\n",
- dev, start, blkcnt);
-
- /* Put the device into Transfer state */
- ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, R1 | NCR);
- if (ret) goto out;
-
- /* Set block length */
- ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, R1 | NCR);
- if (ret) goto out;
-
- pr_debug("MCI_DTOR = %08lx\n", mmci_readl(DTOR));
-
- for (i = 0; i < blkcnt; i++, start++) {
- ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK,
- start * mmc_blkdev.blksz, resp,
- (R1 | NCR | TRCMD_START | TRDIR_READ
- | TRTYP_BLOCK));
- if (ret) goto out;
-
- ret = -EIO;
- wordcount = 0;
- do {
- do {
- status = mmci_readl(SR);
- if (status & (ERROR_FLAGS | MMCI_BIT(OVRE)))
- goto read_error;
- } while (!(status & MMCI_BIT(RXRDY)));
-
- if (status & MMCI_BIT(RXRDY)) {
- data = mmci_readl(RDR);
- /* pr_debug("%x\n", data); */
- *p++ = data;
- wordcount++;
- }
- } while(wordcount < (mmc_blkdev.blksz / 4));
-
- pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount);
-
- do {
- status = mmci_readl(SR);
- } while (!(status & MMCI_BIT(BLKE)));
-
- putc('.');
- }
-
-out:
- /* Put the device back into Standby state */
- mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, NCR);
- return i;
-
-read_error:
- mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR);
- printf("mmc: bread failed, status = %08x, card status = %08lx\n",
- status, card_status);
- goto out;
-}
-
-static void mmc_parse_cid(struct mmc_cid *cid, unsigned long *resp)
-{
- cid->mid = resp[0] >> 24;
- cid->oid = (resp[0] >> 8) & 0xffff;
- cid->pnm[0] = resp[0];
- cid->pnm[1] = resp[1] >> 24;
- cid->pnm[2] = resp[1] >> 16;
- cid->pnm[3] = resp[1] >> 8;
- cid->pnm[4] = resp[1];
- cid->pnm[5] = resp[2] >> 24;
- cid->pnm[6] = 0;
- cid->prv = resp[2] >> 16;
- cid->psn = (resp[2] << 16) | (resp[3] >> 16);
- cid->mdt = resp[3] >> 8;
-}
-
-static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp)
-{
- cid->mid = resp[0] >> 24;
- cid->oid = (resp[0] >> 8) & 0xffff;
- cid->pnm[0] = resp[0];
- cid->pnm[1] = resp[1] >> 24;
- cid->pnm[2] = resp[1] >> 16;
- cid->pnm[3] = resp[1] >> 8;
- cid->pnm[4] = resp[1];
- cid->pnm[5] = 0;
- cid->pnm[6] = 0;
- cid->prv = resp[2] >> 24;
- cid->psn = (resp[2] << 8) | (resp[3] >> 24);
- cid->mdt = (resp[3] >> 8) & 0x0fff;
-}
-
-static void mmc_dump_cid(const struct mmc_cid *cid)
-{
- printf("Manufacturer ID: %02X\n", cid->mid);
- printf("OEM/Application ID: %04X\n", cid->oid);
- printf("Product name: %s\n", cid->pnm);
- printf("Product Revision: %u.%u\n",
- cid->prv >> 4, cid->prv & 0x0f);
- printf("Product Serial Number: %lu\n", cid->psn);
- printf("Manufacturing Date: %02u/%02u\n",
- cid->mdt >> 4, cid->mdt & 0x0f);
-}
-
-static void mmc_dump_csd(const struct mmc_csd *csd)
-{
- unsigned long *csd_raw = (unsigned long *)csd;
- printf("CSD data: %08lx %08lx %08lx %08lx\n",
- csd_raw[0], csd_raw[1], csd_raw[2], csd_raw[3]);
- printf("CSD structure version: 1.%u\n", csd->csd_structure);
- printf("MMC System Spec version: %u\n", csd->spec_vers);
- printf("Card command classes: %03x\n", csd->ccc);
- printf("Read block length: %u\n", 1 << csd->read_bl_len);
- if (csd->read_bl_partial)
- puts("Supports partial reads\n");
- else
- puts("Does not support partial reads\n");
- printf("Write block length: %u\n", 1 << csd->write_bl_len);
- if (csd->write_bl_partial)
- puts("Supports partial writes\n");
- else
- puts("Does not support partial writes\n");
- if (csd->wp_grp_enable)
- printf("Supports group WP: %u\n", csd->wp_grp_size + 1);
- else
- puts("Does not support group WP\n");
- printf("Card capacity: %u bytes\n",
- (csd->c_size + 1) * (1 << (csd->c_size_mult + 2)) *
- (1 << csd->read_bl_len));
- printf("File format: %u/%u\n",
- csd->file_format_grp, csd->file_format);
- puts("Write protection: ");
- if (csd->perm_write_protect)
- puts(" permanent");
- if (csd->tmp_write_protect)
- puts(" temporary");
- putc('\n');
-}
-
-static int mmc_idle_cards(void)
-{
- int ret;
-
- /* Reset and initialize all cards */
- ret = mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0);
- if (ret)
- return ret;
-
- /* Keep the bus idle for 74 clock cycles */
- return mmc_cmd(0, 0, NULL, INIT_CMD);
-}
-
-static int sd_init_card(struct mmc_cid *cid, int verbose)
-{
- unsigned long resp[4];
- int i, ret = 0;
-
- mmc_idle_cards();
- for (i = 0; i < 1000; i++) {
- ret = mmc_acmd(SD_CMD_APP_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND,
- resp, R3 | NID);
- if (ret || (resp[0] & 0x80000000))
- break;
- ret = -ETIMEDOUT;
- }
-
- if (ret)
- return ret;
-
- ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID);
- if (ret)
- return ret;
- sd_parse_cid(cid, resp);
- if (verbose)
- mmc_dump_cid(cid);
-
- /* Get RCA of the card that responded */
- ret = mmc_cmd(SD_CMD_SEND_RELATIVE_ADDR, 0, resp, R6 | NCR);
- if (ret)
- return ret;
-
- mmc_rca = resp[0] >> 16;
- if (verbose)
- printf("SD Card detected (RCA %u)\n", mmc_rca);
- mmc_card_is_sd = 1;
- return 0;
-}
-
-static int mmc_init_card(struct mmc_cid *cid, int verbose)
-{
- unsigned long resp[4];
- int i, ret = 0;
-
- mmc_idle_cards();
- for (i = 0; i < 1000; i++) {
- ret = mmc_cmd(MMC_CMD_SEND_OP_COND, CONFIG_SYS_MMC_OP_COND, resp,
- R3 | NID | OPEN_DRAIN);
- if (ret || (resp[0] & 0x80000000))
- break;
- ret = -ETIMEDOUT;
- }
-
- if (ret)
- return ret;
-
- /* Get CID of all cards. FIXME: Support more than one card */
- ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID | OPEN_DRAIN);
- if (ret)
- return ret;
- mmc_parse_cid(cid, resp);
- if (verbose)
- mmc_dump_cid(cid);
-
- /* Set Relative Address of the card that responded */
- ret = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, mmc_rca << 16, resp,
- R1 | NCR | OPEN_DRAIN);
- return ret;
-}
-
-static void mci_set_data_timeout(struct mmc_csd *csd)
-{
- static const unsigned int dtomul_to_shift[] = {
- 0, 4, 7, 8, 10, 12, 16, 20,
- };
- static const unsigned int taac_exp[] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
- };
- static const unsigned int taac_mant[] = {
- 0, 10, 12, 13, 15, 60, 25, 30,
- 35, 40, 45, 50, 55, 60, 70, 80,
- };
- unsigned int timeout_ns, timeout_clks;
- unsigned int e, m;
- unsigned int dtocyc, dtomul;
- unsigned int shift;
- u32 dtor;
-
- e = csd->taac & 0x07;
- m = (csd->taac >> 3) & 0x0f;
-
- timeout_ns = (taac_exp[e] * taac_mant[m] + 9) / 10;
- timeout_clks = csd->nsac * 100;
-
- timeout_clks += (((timeout_ns + 9) / 10)
- * ((CONFIG_SYS_MMC_CLK_PP + 99999) / 100000) + 9999) / 10000;
- if (!mmc_card_is_sd)
- timeout_clks *= 10;
- else
- timeout_clks *= 100;
-
- dtocyc = timeout_clks;
- dtomul = 0;
- shift = 0;
- while (dtocyc > 15 && dtomul < 8) {
- dtomul++;
- shift = dtomul_to_shift[dtomul];
- dtocyc = (timeout_clks + (1 << shift) - 1) >> shift;
- }
-
- if (dtomul >= 8) {
- dtomul = 7;
- dtocyc = 15;
- puts("Warning: Using maximum data timeout\n");
- }
-
- dtor = (MMCI_BF(DTOMUL, dtomul)
- | MMCI_BF(DTOCYC, dtocyc));
- mmci_writel(DTOR, dtor);
-
- printf("mmc: Using %u cycles data timeout (DTOR=0x%x)\n",
- dtocyc << shift, dtor);
-}
-
-int mmc_legacy_init(int verbose)
-{
- struct mmc_cid cid;
- struct mmc_csd csd;
- unsigned int max_blksz;
- int ret;
-
- /* Initialize controller */
- mmci_writel(CR, MMCI_BIT(SWRST));
- mmci_writel(CR, MMCI_BIT(MCIEN));
- mmci_writel(DTOR, 0x5f);
- mmci_writel(IDR, ~0UL);
- mci_set_mode(CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
-
- mmc_card_is_sd = 0;
-
- ret = sd_init_card(&cid, verbose);
- if (ret) {
- mmc_rca = MMC_DEFAULT_RCA;
- ret = mmc_init_card(&cid, verbose);
- }
- if (ret)
- return ret;
-
- /* Get CSD from the card */
- ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, &csd, R2 | NCR);
- if (ret)
- return ret;
- if (verbose)
- mmc_dump_csd(&csd);
-
- mci_set_data_timeout(&csd);
-
- /* Initialize the blockdev structure */
- mmc_blkdev.if_type = IF_TYPE_MMC;
- mmc_blkdev.part_type = PART_TYPE_DOS;
- mmc_blkdev.block_read = mmc_bread;
- sprintf((char *)mmc_blkdev.vendor,
- "Man %02x%04x Snr %08lx",
- cid.mid, cid.oid, cid.psn);
- strncpy((char *)mmc_blkdev.product, cid.pnm,
- sizeof(mmc_blkdev.product));
- sprintf((char *)mmc_blkdev.revision, "%x %x",
- cid.prv >> 4, cid.prv & 0x0f);
-
- /*
- * If we can't use 512 byte blocks, refuse to deal with the
- * card. Tons of code elsewhere seems to depend on this.
- */
- max_blksz = 1 << csd.read_bl_len;
- if (max_blksz < 512 || (max_blksz > 512 && !csd.read_bl_partial)) {
- printf("Card does not support 512 byte reads, aborting.\n");
- return -ENODEV;
- }
- mmc_blkdev.blksz = 512;
- mmc_blkdev.lba = (csd.c_size + 1) * (1 << (csd.c_size_mult + 2));
-
- mci_set_mode(CONFIG_SYS_MMC_CLK_PP, mmc_blkdev.blksz);
-
-#if 0
- if (fat_register_device(&mmc_blkdev, 1))
- printf("Could not register MMC fat device\n");
-#else
- init_part(&mmc_blkdev);
-#endif
-
- return 0;
-}
int board_mmc_getcd(struct mmc *mmc)__attribute__((weak,
alias("__board_mmc_getcd")));
+#ifdef CONFIG_MMC_BOUNCE_BUFFER
+static int mmc_bounce_need_bounce(struct mmc_data *orig)
+{
+ ulong addr, len;
+
+ if (orig->flags & MMC_DATA_READ)
+ addr = (ulong)orig->dest;
+ else
+ addr = (ulong)orig->src;
+
+ if (addr % ARCH_DMA_MINALIGN) {
+ debug("MMC: Unaligned data destination address %08lx!\n", addr);
+ return 1;
+ }
+
+ len = (ulong)(orig->blocksize * orig->blocks);
+ if (len % ARCH_DMA_MINALIGN) {
+ debug("MMC: Unaligned data destination length %08lx!\n", len);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int mmc_bounce_buffer_start(struct mmc_data *backup,
+ struct mmc_data *orig)
+{
+ ulong origlen, len;
+ void *buffer;
+
+ if (!orig)
+ return 0;
+
+ if (!mmc_bounce_need_bounce(orig))
+ return 0;
+
+ memcpy(backup, orig, sizeof(struct mmc_data));
+
+ origlen = orig->blocksize * orig->blocks;
+ len = roundup(origlen, ARCH_DMA_MINALIGN);
+ buffer = memalign(ARCH_DMA_MINALIGN, len);
+ if (!buffer) {
+ puts("MMC: Error allocating MMC bounce buffer!\n");
+ return 1;
+ }
+
+ if (orig->flags & MMC_DATA_READ) {
+ orig->dest = buffer;
+ } else {
+ memcpy(buffer, orig->src, origlen);
+ orig->src = buffer;
+ }
+
+ return 0;
+}
+
+static void mmc_bounce_buffer_stop(struct mmc_data *backup,
+ struct mmc_data *orig)
+{
+ ulong len;
+
+ if (!orig)
+ return;
+
+ if (!mmc_bounce_need_bounce(backup))
+ return;
+
+ if (backup->flags & MMC_DATA_READ) {
+ len = backup->blocksize * backup->blocks;
+ memcpy(backup->dest, orig->dest, len);
+ free(orig->dest);
+ orig->dest = backup->dest;
+ } else {
+ free((void *)orig->src);
+ orig->src = backup->src;
+ }
+
+ return;
+
+}
+#else
+static inline int mmc_bounce_buffer_start(struct mmc_data *backup,
+ struct mmc_data *orig) { return 0; }
+static inline void mmc_bounce_buffer_stop(struct mmc_data *backup,
+ struct mmc_data *orig) { }
+#endif
+
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
{
-#ifdef CONFIG_MMC_TRACE
+ struct mmc_data backup;
int ret;
+
+ memset(&backup, 0, sizeof(backup));
+
+ ret = mmc_bounce_buffer_start(&backup, data);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_MMC_TRACE
int i;
u8 *ptr;
printf("\t\tERROR MMC rsp not supported\n");
break;
}
- return ret;
#else
- return mmc->send_cmd(mmc, cmd, data);
+ ret = mmc->send_cmd(mmc, cmd, data);
#endif
+ mmc_bounce_buffer_stop(&backup, data);
+ return ret;
}
int mmc_send_status(struct mmc *mmc, int timeout)
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
+#include <asm/arch/dma.h>
struct mxsmmc_priv {
int id;
uint32_t *clkctrl_ssp;
uint32_t buswidth;
int (*mmc_is_wp)(int);
+ struct mxs_dma_desc *desc;
};
#define MXSMMC_MAX_TIMEOUT 10000
struct mx28_ssp_regs *ssp_regs = priv->regs;
uint32_t reg;
int timeout;
- uint32_t data_count;
- uint32_t *data_ptr;
+ uint32_t data_count, cache_data_count;
uint32_t ctrl0;
debug("MMC%d: CMD%d\n", mmc->block_dev.dev, cmd->cmdidx);
if (!data)
return 0;
- /* Process the data */
data_count = data->blocksize * data->blocks;
- timeout = MXSMMC_MAX_TIMEOUT;
+
+ if (data_count % ARCH_DMA_MINALIGN)
+ cache_data_count = roundup(data_count, ARCH_DMA_MINALIGN);
+ else
+ cache_data_count = data_count;
+
if (data->flags & MMC_DATA_READ) {
- data_ptr = (uint32_t *)data->dest;
- while (data_count && --timeout) {
- reg = readl(&ssp_regs->hw_ssp_status);
- if (!(reg & SSP_STATUS_FIFO_EMPTY)) {
- *data_ptr++ = readl(&ssp_regs->hw_ssp_data);
- data_count -= 4;
- timeout = MXSMMC_MAX_TIMEOUT;
- } else
- udelay(1000);
- }
+ priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_WRITE;
+ priv->desc->cmd.address = (dma_addr_t)data->dest;
} else {
- data_ptr = (uint32_t *)data->src;
- timeout *= 100;
- while (data_count && --timeout) {
- reg = readl(&ssp_regs->hw_ssp_status);
- if (!(reg & SSP_STATUS_FIFO_FULL)) {
- writel(*data_ptr++, &ssp_regs->hw_ssp_data);
- data_count -= 4;
- timeout = MXSMMC_MAX_TIMEOUT;
- } else
- udelay(1000);
- }
+ priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ;
+ priv->desc->cmd.address = (dma_addr_t)data->src;
+
+ /* Flush data to DRAM so DMA can pick them up */
+ flush_dcache_range((uint32_t)priv->desc->cmd.address,
+ (uint32_t)(priv->desc->cmd.address + cache_data_count));
}
- if (!timeout) {
- printf("MMC%d: Data timeout with command %d (status 0x%08x)!\n",
- mmc->block_dev.dev, cmd->cmdidx, reg);
+ priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM |
+ (data_count << MXS_DMA_DESC_BYTES_OFFSET);
+
+
+ mxs_dma_desc_append(MXS_DMA_CHANNEL_AHB_APBH_SSP0, priv->desc);
+ if (mxs_dma_go(MXS_DMA_CHANNEL_AHB_APBH_SSP0)) {
+ printf("MMC%d: DMA transfer failed\n", mmc->block_dev.dev);
return COMM_ERR;
}
+ /* The data arrived into DRAM, invalidate cache over them */
+ if (data->flags & MMC_DATA_READ) {
+ invalidate_dcache_range((uint32_t)priv->desc->cmd.address,
+ (uint32_t)(priv->desc->cmd.address + cache_data_count));
+ }
+
/* Check data errors */
reg = readl(&ssp_regs->hw_ssp_status);
if (reg &
/* 8 bits word length in MMC mode */
clrsetbits_le32(&ssp_regs->hw_ssp_ctrl1,
SSP_CTRL1_SSP_MODE_MASK | SSP_CTRL1_WORD_LENGTH_MASK,
- SSP_CTRL1_SSP_MODE_SD_MMC | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS);
+ SSP_CTRL1_SSP_MODE_SD_MMC | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS |
+ SSP_CTRL1_DMA_ENABLE);
/* Set initial bit clock 400 KHz */
mx28_set_ssp_busclock(priv->id, 400);
return -ENOMEM;
}
+ priv->desc = mxs_dma_desc_alloc();
+ if (!priv->desc) {
+ free(priv);
+ free(mmc);
+ return -ENOMEM;
+ }
+
priv->mmc_is_wp = wp;
priv->id = id;
switch (id) {
*/
mmc->f_min = 400000;
mmc->f_max = mxc_get_clock(MXC_SSP0_CLK + id) * 1000 / 2;
- mmc->b_max = 0;
+ mmc->b_max = 0x40;
mmc_register(mmc);
return 0;
struct mmc_host *host = (struct mmc_host *)mmc->priv;
int flags, i;
int result;
- unsigned int mask;
+ unsigned int mask = 0;
unsigned int retry = 0x100000;
debug(" mmc_send_cmd called\n");
void *src = cp;
void *dst = (void *)dest;
void *dst2 = dst;
- int flag = 0;
+ int flag = 1;
uint offset = 0;
unsigned int shift;
uchar write_cmd;
cnt = len >> shift;
- while ((cnt-- > 0) && (flag == 0)) {
+ while ((cnt-- > 0) && (flag == 1)) {
switch (info->portwidth) {
case FLASH_CFI_8BIT:
flag = ((flash_read8(dst2) & flash_read8(src)) ==
COBJS-y += nand_ids.o
COBJS-y += nand_util.o
endif
-COBJS-$(CONFIG_MTD_ECC_SOFT) += nand_ecc.o
+COBJS-y += nand_ecc.o
COBJS-y += nand_base.o
COBJS-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
/* Integrated Flash Controller NAND Machine Driver
*
- * Copyright (c) 2011 Freescale Semiconductor, Inc
+ * Copyright (c) 2012 Freescale Semiconductor, Inc
*
* Authors: Dipen Dudhat <Dipen.Dudhat@freescale.com>
*
u32 *eccstat, unsigned int bufnum)
{
u32 reg = eccstat[bufnum / 4];
- int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
-
- if (errors == 15) { /* uncorrectable */
- /* Blank pages fail hw ECC checks */
- if (is_blank(mtd, ctrl, bufnum))
- return 1;
-
- /*
- * We disable ECCER reporting in hardware due to
- * erratum IFC-A002770 -- so report it now if we
- * see an uncorrectable error in ECCSTAT.
- */
- ctrl->status |= IFC_NAND_EVTER_STAT_ECCER;
- } else if (errors > 0) {
- mtd->ecc_stats.corrected += errors;
- }
+ int errors;
- return 0;
+ errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
+
+ return errors;
}
/*
printf("%s: Write Protect Error\n", __func__);
if (ctrl->eccread) {
- int bufperpage = mtd->writesize / 512;
- int bufnum = (ctrl->page & priv->bufnum_mask) * bufperpage;
- int bufnum_end = bufnum + bufperpage - 1;
+ int errors;
+ int bufnum = ctrl->page & priv->bufnum_mask;
+ int sector = bufnum * chip->ecc.steps;
+ int sector_end = sector + chip->ecc.steps - 1;
- for (i = bufnum / 4; i <= bufnum_end / 4; i++)
+ for (i = sector / 4; i <= sector_end / 4; i++)
eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]);
- for (i = bufnum; i <= bufnum_end; i++) {
- if (check_read_ecc(mtd, ctrl, eccstat, i))
+ for (i = sector; i <= sector_end; i++) {
+ errors = check_read_ecc(mtd, ctrl, eccstat, i);
+
+ if (errors == 15) {
+ /*
+ * Uncorrectable error.
+ * OK only if the whole page is blank.
+ *
+ * We disable ECCER reporting due to erratum
+ * IFC-A002770 -- so report it now if we
+ * see an uncorrectable error in ECCSTAT.
+ */
+ if (!is_blank(mtd, ctrl, bufnum))
+ ctrl->status |=
+ IFC_NAND_EVTER_STAT_ECCER;
break;
+ }
+
+ mtd->ecc_stats.corrected += errors;
}
ctrl->eccread = 0;
out_be32(&ifc->ifc_nand.nand_fir1,
(IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT));
- if (column >= mtd->writesize) {
- /* OOB area --> READOOB */
- column -= mtd->writesize;
- nand_fcr0 |= NAND_CMD_READOOB <<
- IFC_NAND_FCR0_CMD0_SHIFT;
- ctrl->oob = 1;
- } else if (column < 256) {
- /* First 256 bytes --> READ0 */
- nand_fcr0 |= NAND_CMD_READ0 << FCR_CMD0_SHIFT;
- } else {
- /* Second 256 bytes --> READ1 */
- nand_fcr0 |= NAND_CMD_READ1 << FCR_CMD0_SHIFT;
- }
+ if (column >= mtd->writesize)
+ nand_fcr0 |=
+ NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
+ else
+ nand_fcr0 |=
+ NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
}
+ if (column >= mtd->writesize) {
+ /* OOB area --> READOOB */
+ column -= mtd->writesize;
+ ctrl->oob = 1;
+ }
out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
set_addr(mtd, column, page_addr, ctrl->oob);
return;
/* PAGEPROG reuses all of the setup from SEQIN and adds the length */
case NAND_CMD_PAGEPROG:
if (ctrl->oob)
- out_be32(&ifc->ifc_nand.nand_fbcr, ctrl->index);
+ out_be32(&ifc->ifc_nand.nand_fbcr,
+ ctrl->index - ctrl->column);
else
out_be32(&ifc->ifc_nand.nand_fbcr, 0);
int cur_chip;
uint32_t cmd_queue_len;
+ uint32_t data_buf_size;
uint8_t *cmd_buf;
uint8_t *data_buf;
struct nand_ecclayout fake_ecc_layout;
+/*
+ * Cache management functions
+ */
+#ifndef CONFIG_SYS_DCACHE_OFF
+static void mxs_nand_flush_data_buf(struct mxs_nand_info *info)
+{
+ uint32_t addr = (uint32_t)info->data_buf;
+
+ flush_dcache_range(addr, addr + info->data_buf_size);
+}
+
+static void mxs_nand_inval_data_buf(struct mxs_nand_info *info)
+{
+ uint32_t addr = (uint32_t)info->data_buf;
+
+ invalidate_dcache_range(addr, addr + info->data_buf_size);
+}
+
+static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info)
+{
+ uint32_t addr = (uint32_t)info->cmd_buf;
+
+ flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE);
+}
+#else
+static inline void mxs_nand_flush_data_buf(struct mxs_nand_info *info) {}
+static inline void mxs_nand_inval_data_buf(struct mxs_nand_info *info) {}
+static inline void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) {}
+#endif
+
static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
{
struct mxs_dma_desc *desc;
mxs_dma_desc_append(channel, d);
+ /* Flush caches */
+ mxs_nand_flush_cmd_buf(nand_info);
+
/* Execute the DMA chain. */
ret = mxs_dma_go(channel);
if (ret)
goto rtn;
}
+ /* Invalidate caches */
+ mxs_nand_inval_data_buf(nand_info);
+
memcpy(buf, nand_info->data_buf, length);
rtn:
mxs_dma_desc_append(channel, d);
+ /* Flush caches */
+ mxs_nand_flush_data_buf(nand_info);
+
/* Execute the DMA chain. */
ret = mxs_dma_go(channel);
if (ret)
goto rtn;
}
+ /* Invalidate caches */
+ mxs_nand_inval_data_buf(nand_info);
+
/* Read DMA completed, now do the mark swapping. */
mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
mxs_dma_desc_append(channel, d);
+ /* Flush caches */
+ mxs_nand_flush_data_buf(nand_info);
+
/* Execute the DMA chain. */
ret = mxs_dma_go(channel);
if (ret) {
uint8_t *buf;
const int size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE;
+ nand_info->data_buf_size = roundup(size, MXS_DMA_ALIGNMENT);
+
/* DMA buffers */
- buf = memalign(MXS_DMA_ALIGNMENT, size);
+ buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size);
if (!buf) {
printf("MXS NAND: Error allocating DMA buffers\n");
return -ENOMEM;
}
- memset(buf, 0, size);
+ memset(buf, 0, nand_info->data_buf_size);
nand_info->data_buf = buf;
nand_info->oob_buf = buf + NAND_MAX_PAGESIZE;
-
/* Command buffers */
nand_info->cmd_buf = memalign(MXS_DMA_ALIGNMENT,
MXS_NAND_COMMAND_BUFFER_SIZE);
{
struct nand_chip *chip = mtd->priv;
+ if (!(chip->options & NAND_BBT_SCANNED)) {
+ chip->options |= NAND_BBT_SCANNED;
+ chip->scan_bbt(mtd);
+ }
+
if (!chip->bbt)
return chip->block_bad(mtd, ofs, getchip);
chip->ecc.mode = NAND_ECC_SOFT;
case NAND_ECC_SOFT:
- if (!mtd_nand_has_ecc_soft()) {
- printk(KERN_WARNING "CONFIG_MTD_ECC_SOFT not enabled\n");
- return -EINVAL;
- }
chip->ecc.calculate = nand_calculate_ecc;
chip->ecc.correct = nand_correct_data;
chip->ecc.read_page = nand_read_page_swecc;
/* Check, if we should skip the bad block table scan */
if (chip->options & NAND_SKIP_BBTSCAN)
- return 0;
+ chip->options |= NAND_BBT_SCANNED;
- /* Build bad block table */
- return chip->scan_bbt(mtd);
+ return 0;
}
/**
#include <asm/arch/mem.h>
#include <asm/arch/omap_gpmc.h>
#include <linux/mtd/nand_ecc.h>
+#include <linux/compiler.h>
#include <nand.h>
static uint8_t cs;
-static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT;
+static __maybe_unused struct nand_ecclayout hw_nand_oob =
+ GPMC_NAND_HW_ECC_LAYOUT;
/*
* omap_nand_hwcontrol - Set the address pointers corretly for the
* @mtd: MTD device structure
*
*/
-static void omap_hwecc_init(struct nand_chip *chip)
+static void __maybe_unused omap_hwecc_init(struct nand_chip *chip)
{
/*
* Init ECC Control Register
*
* @return 0 if data is OK or corrected, else returns -1
*/
-static int omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
+static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
uint8_t *read_ecc, uint8_t *calc_ecc)
{
uint32_t orig_ecc, new_ecc, res, hm;
* @dat: unused
* @ecc_code: ecc_code buffer
*/
-static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
- uint8_t *ecc_code)
+static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
+ const uint8_t *dat, uint8_t *ecc_code)
{
u_int32_t val;
* @mtd: MTD device structure
* @mode: Read/Write mode
*/
-static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
+static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
{
struct nand_chip *chip = mtd->priv;
uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
volatile struct alt_sgdma_descriptor *tx_desc_cur =
(volatile struct alt_sgdma_descriptor *)&tx_desc[0];
- flush_dcache((unsigned long)packet, length);
+ flush_dcache_range((unsigned long)packet,
+ (unsigned long)packet + length);
alt_sgdma_construct_descriptor_burst(
(volatile struct alt_sgdma_descriptor *)&tx_desc[0],
(volatile struct alt_sgdma_descriptor *)&tx_desc[1],
NetReceive(NetRxPackets[0], packet_length);
/* start descriptor again */
- flush_dcache((unsigned long)(NetRxPackets[0]), PKTSIZE_ALIGN);
+ flush_dcache_range((unsigned long)(NetRxPackets[0]),
+ (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
alt_sgdma_construct_descriptor_burst(
(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
0x0 /* channel */
);
debug("Configuring rx desc\n");
- flush_dcache((unsigned long)(NetRxPackets[0]), PKTSIZE_ALIGN);
+ flush_dcache_range((unsigned long)(NetRxPackets[0]),
+ (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
alt_sgdma_construct_descriptor_burst(
(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
/* Assign ARMADA100 Fast Ethernet Controller Base Address */
darmdfec->regs = (void *)base_addr;
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
strcpy(dev->name, "armd-fec0");
dev->init = armdfec_init;
*/
#include <common.h>
#include <malloc.h>
+#include <linux/compiler.h>
#include <linux/err.h>
#include <asm/io.h>
if (i == priv->num_rx - 1)
bd.stat |= RX_BD_WRAP;
- flush_dcache(bd.addr, PKTSIZE_ALIGN);
+ flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN);
ethoc_write_bd(dev, priv->num_tx + i, &bd);
}
}
/* clear the buffer descriptor so it can be reused */
- flush_dcache(bd.addr, PKTSIZE_ALIGN);
+ flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN);
bd.stat &= ~RX_BD_STATS;
bd.stat |= RX_BD_EMPTY;
ethoc_write_bd(dev, entry, &bd);
bd.stat &= ~TX_BD_PAD;
bd.addr = (u32)packet;
- flush_dcache(bd.addr, length);
+ flush_dcache_range(bd.addr, bd.addr + length);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
bd.stat |= TX_BD_LEN(length);
ethoc_write_bd(dev, entry, &bd);
#error "CONFIG_MII has to be defined!"
#endif
-#ifndef CONFIG_FEC_XCV_TYPE
-#define CONFIG_FEC_XCV_TYPE MII100
+#ifndef CONFIG_FEC_XCV_TYPE
+#define CONFIG_FEC_XCV_TYPE MII100
#endif
/*
* The i.MX28 operates with packets in big endian. We need to swap them before
* sending and after receiving.
*/
-#ifdef CONFIG_MX28
-#define CONFIG_FEC_MXC_SWAP_PACKET
+#ifdef CONFIG_MX28
+#define CONFIG_FEC_MXC_SWAP_PACKET
+#endif
+
+#define RXDESC_PER_CACHELINE (ARCH_DMA_MINALIGN/sizeof(struct fec_bd))
+
+/* Check various alignment issues at compile time */
+#if ((ARCH_DMA_MINALIGN < 16) || (ARCH_DMA_MINALIGN % 16 != 0))
+#error "ARCH_DMA_MINALIGN must be multiple of 16!"
+#endif
+
+#if ((PKTALIGN < ARCH_DMA_MINALIGN) || \
+ (PKTALIGN % ARCH_DMA_MINALIGN != 0))
+#error "PKTALIGN must be multiple of ARCH_DMA_MINALIGN!"
#endif
#undef DEBUG
uint8_t head[16]; /**< MAC header(6 + 6 + 2) + 2(aligned) */
};
-#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
static void swap_packet(uint32_t *packet, int length)
{
int i;
}
#endif
-/*
- * The i.MX28 has two ethernet interfaces, but they are not equal.
- * Only the first one can access the MDIO bus.
- */
-#ifdef CONFIG_MX28
-static inline struct ethernet_regs *fec_miiphy_fec_to_eth(struct fec_priv *fec)
-{
- return (struct ethernet_regs *)MXS_ENET0_BASE;
-}
-#else
-static inline struct ethernet_regs *fec_miiphy_fec_to_eth(struct fec_priv *fec)
-{
- return fec->eth;
-}
-#endif
-
/*
* MII-interface related functions
*/
-static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
- uint16_t *retVal)
+static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
+ uint8_t regAddr)
{
- struct eth_device *edev = eth_get_dev_by_name(dev);
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
- struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
-
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
uint32_t start;
+ int val;
/*
* reading from any PHY's register is done by properly
/*
* it's now safe to read the PHY's register
*/
- *retVal = readl(ð->mii_data);
- debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr,
- regAddr, *retVal);
- return 0;
+ val = (unsigned short)readl(ð->mii_data);
+ debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+ regAddr, val);
+ return val;
}
static void fec_mii_setspeed(struct fec_priv *fec)
*/
writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
&fec->eth->mii_speed);
- debug("fec_init: mii_speed %08x\n",
- readl(&fec->eth->mii_speed));
+ debug("%s: mii_speed %08x\n", __func__, readl(&fec->eth->mii_speed));
}
-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);
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
- struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
+static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
+ uint8_t regAddr, uint16_t data)
+{
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
uint32_t start;
* clear MII interrupt bit
*/
writel(FEC_IEVENT_MII, ð->ievent);
- debug("fec_miiphy_write: phy: %02x reg:%02x val:%#x\n", phyAddr,
+ debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
regAddr, data);
return 0;
}
+int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+{
+ return fec_mdio_read(bus->priv, phyAddr, regAddr);
+}
+
+int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
+ u16 data)
+{
+ return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
+}
+
+#ifndef CONFIG_PHYLIB
static int miiphy_restart_aneg(struct eth_device *dev)
{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct ethernet_regs *eth = fec->bus->priv;
int ret = 0;
/*
* Reset PHY, then delay 300ns
*/
#ifdef CONFIG_MX27
- miiphy_write(dev->name, fec->phy_id, MII_DCOUNTER, 0x00FF);
+ fec_mdio_write(eth, fec->phy_id, MII_DCOUNTER, 0x00FF);
#endif
- miiphy_write(dev->name, fec->phy_id, MII_BMCR,
- BMCR_RESET);
+ fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET);
udelay(1000);
/*
* Set the auto-negotiation advertisement register bits
*/
- miiphy_write(dev->name, fec->phy_id, MII_ADVERTISE,
+ fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE,
LPA_100FULL | LPA_100HALF | LPA_10FULL |
LPA_10HALF | PHY_ANLPAR_PSB_802_3);
- miiphy_write(dev->name, fec->phy_id, MII_BMCR,
+ fec_mdio_write(eth, fec->phy_id, MII_BMCR,
BMCR_ANENABLE | BMCR_ANRESTART);
if (fec->mii_postcall)
static int miiphy_wait_aneg(struct eth_device *dev)
{
uint32_t start;
- uint16_t status;
+ int status;
struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct ethernet_regs *eth = fec->bus->priv;
/*
* Wait for AN completion
return -1;
}
- if (miiphy_read(dev->name, fec->phy_id,
- MII_BMSR, &status)) {
- printf("%s: Autonegotiation failed. status: 0x%04x\n",
+ status = fec_mdio_read(eth, fec->phy_id, MII_BMSR);
+ if (status < 0) {
+ printf("%s: Autonegotiation failed. status: %d\n",
dev->name, status);
return -1;
}
return 0;
}
+#endif
+
static int fec_rx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->r_des_active);
* Initialize receive task's buffer descriptors
* @param[in] fec all we know about the device yet
* @param[in] count receive buffer count to be allocated
- * @param[in] size size of each receive buffer
+ * @param[in] dsize desired size of each receive buffer
* @return 0 on success
*
* For this task we need additional memory for the data buffers. And each
* data buffer requires some alignment. Thy must be aligned to a specific
- * boundary each (DB_DATA_ALIGNMENT).
+ * boundary each.
*/
-static int fec_rbd_init(struct fec_priv *fec, int count, int size)
+static int fec_rbd_init(struct fec_priv *fec, int count, int dsize)
{
- int ix;
- uint32_t p = 0;
-
- /* reserve data memory and consider alignment */
- if (fec->rdb_ptr == NULL)
- fec->rdb_ptr = malloc(size * count + DB_DATA_ALIGNMENT);
- p = (uint32_t)fec->rdb_ptr;
- if (!p) {
- puts("fec_mxc: not enough malloc memory\n");
- return -ENOMEM;
- }
- memset((void *)p, 0, size * count + DB_DATA_ALIGNMENT);
- p += DB_DATA_ALIGNMENT-1;
- p &= ~(DB_DATA_ALIGNMENT-1);
-
- for (ix = 0; ix < count; ix++) {
- writel(p, &fec->rbd_base[ix].data_pointer);
- p += size;
- writew(FEC_RBD_EMPTY, &fec->rbd_base[ix].status);
- writew(0, &fec->rbd_base[ix].data_length);
- }
+ uint32_t size;
+ int i;
+
/*
- * mark the last RBD to close the ring
+ * Allocate memory for the buffers. This allocation respects the
+ * alignment
*/
- writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &fec->rbd_base[ix - 1].status);
+ size = roundup(dsize, ARCH_DMA_MINALIGN);
+ for (i = 0; i < count; i++) {
+ uint32_t data_ptr = readl(&fec->rbd_base[i].data_pointer);
+ if (data_ptr == 0) {
+ uint8_t *data = memalign(ARCH_DMA_MINALIGN,
+ size);
+ if (!data) {
+ printf("%s: error allocating rxbuf %d\n",
+ __func__, i);
+ goto err;
+ }
+ writel((uint32_t)data, &fec->rbd_base[i].data_pointer);
+ } /* needs allocation */
+ writew(FEC_RBD_EMPTY, &fec->rbd_base[i].status);
+ writew(0, &fec->rbd_base[i].data_length);
+ }
+
+ /* Mark the last RBD to close the ring. */
+ writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &fec->rbd_base[i - 1].status);
fec->rbd_index = 0;
return 0;
+
+err:
+ for (; i >= 0; i--) {
+ uint32_t data_ptr = readl(&fec->rbd_base[i].data_pointer);
+ free((void *)data_ptr);
+ }
+
+ return -ENOMEM;
}
/**
*/
static void fec_tbd_init(struct fec_priv *fec)
{
+ unsigned addr = (unsigned)fec->tbd_base;
+ unsigned size = roundup(2 * sizeof(struct fec_bd),
+ ARCH_DMA_MINALIGN);
writew(0x0000, &fec->tbd_base[0].status);
writew(FEC_TBD_WRAP, &fec->tbd_base[1].status);
fec->tbd_index = 0;
+ flush_dcache_range(addr, addr+size);
}
/**
*/
static void fec_rbd_clean(int last, struct fec_bd *pRbd)
{
- /*
- * Reset buffer descriptor as empty
- */
+ unsigned short flags = FEC_RBD_EMPTY;
if (last)
- writew(FEC_RBD_WRAP | FEC_RBD_EMPTY, &pRbd->status);
- else
- writew(FEC_RBD_EMPTY, &pRbd->status);
- /*
- * no data in it
- */
+ flags |= FEC_RBD_WRAP;
+ writew(flags, &pRbd->status);
writew(0, &pRbd->data_length);
}
return 0;
}
+static void fec_eth_phy_config(struct eth_device *dev)
+{
+#ifdef CONFIG_PHYLIB
+ struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct phy_device *phydev;
+
+ phydev = phy_connect(fec->bus, fec->phy_id, dev,
+ PHY_INTERFACE_MODE_RGMII);
+ if (phydev) {
+ fec->phydev = phydev;
+ phy_config(phydev);
+ }
+#endif
+}
+
/**
* Start the FEC engine
* @param[in] dev Our device to handle
static int fec_open(struct eth_device *edev)
{
struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ int speed;
+ uint32_t addr, size;
+ int i;
debug("fec_open: fec_open(dev)\n");
/* full-duplex, heartbeat disabled */
writel(1 << 2, &fec->eth->x_cntrl);
fec->rbd_index = 0;
-#if defined(CONFIG_MX6Q)
+ /* Invalidate all descriptors */
+ for (i = 0; i < FEC_RBD_NUM - 1; i++)
+ fec_rbd_clean(0, &fec->rbd_base[i]);
+ fec_rbd_clean(1, &fec->rbd_base[i]);
+
+ /* Flush the descriptors into RAM */
+ size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
+ ARCH_DMA_MINALIGN);
+ addr = (uint32_t)fec->rbd_base;
+ flush_dcache_range(addr, addr + size);
+
+#ifdef FEC_QUIRK_ENET_MAC
/* Enable ENET HW endian SWAP */
writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
&fec->eth->ecntrl);
}
#endif
+#ifdef CONFIG_PHYLIB
+ if (!fec->phydev)
+ fec_eth_phy_config(edev);
+ if (fec->phydev) {
+ /* Start up the PHY */
+ phy_startup(fec->phydev);
+ speed = fec->phydev->speed;
+ } else {
+ speed = _100BASET;
+ }
+#else
miiphy_wait_aneg(edev);
- miiphy_speed(edev->name, fec->phy_id);
+ speed = miiphy_speed(edev->name, fec->phy_id);
miiphy_duplex(edev->name, fec->phy_id);
+#endif
+
+#ifdef FEC_QUIRK_ENET_MAC
+ {
+ u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
+ u32 rcr = (readl(&fec->eth->r_cntrl) &
+ ~(FEC_RCNTRL_RMII | FEC_RCNTRL_RMII_10T)) |
+ FEC_RCNTRL_RGMII | FEC_RCNTRL_MII_MODE;
+ if (speed == _1000BASET)
+ ecr |= FEC_ECNTRL_SPEED;
+ else if (speed != _100BASET)
+ rcr |= FEC_RCNTRL_RMII_10T;
+ writel(ecr, &fec->eth->ecntrl);
+ writel(rcr, &fec->eth->r_cntrl);
+ }
+#endif
+ debug("%s:Speed=%i\n", __func__, speed);
/*
* Enable SmartDMA receive task
static int fec_init(struct eth_device *dev, bd_t* bd)
{
- uint32_t base;
struct fec_priv *fec = (struct fec_priv *)dev->priv;
uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
uint32_t rcntrl;
- int i;
+ uint32_t size;
+ int i, ret;
/* Initialize MAC address */
fec_set_hwaddr(dev);
/*
- * reserve memory for both buffer descriptor chains at once
- * Datasheet forces the startaddress of each chain is 16 byte
- * aligned
+ * Allocate transmit descriptors, there are two in total. This
+ * allocation respects cache alignment.
*/
- if (fec->base_ptr == NULL)
- fec->base_ptr = malloc((2 + FEC_RBD_NUM) *
- sizeof(struct fec_bd) + DB_ALIGNMENT);
- base = (uint32_t)fec->base_ptr;
- if (!base) {
- puts("fec_mxc: not enough malloc memory\n");
- return -ENOMEM;
+ if (!fec->tbd_base) {
+ size = roundup(2 * sizeof(struct fec_bd),
+ ARCH_DMA_MINALIGN);
+ fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
+ if (!fec->tbd_base) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+ memset(fec->tbd_base, 0, size);
+ fec_tbd_init(fec);
+ flush_dcache_range((unsigned)fec->tbd_base, size);
}
- memset((void *)base, 0, (2 + FEC_RBD_NUM) *
- sizeof(struct fec_bd) + DB_ALIGNMENT);
- base += (DB_ALIGNMENT-1);
- base &= ~(DB_ALIGNMENT-1);
-
- fec->rbd_base = (struct fec_bd *)base;
- base += FEC_RBD_NUM * sizeof(struct fec_bd);
-
- fec->tbd_base = (struct fec_bd *)base;
+ /*
+ * Allocate receive descriptors. This allocation respects cache
+ * alignment.
+ */
+ if (!fec->rbd_base) {
+ size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
+ ARCH_DMA_MINALIGN);
+ fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
+ if (!fec->rbd_base) {
+ ret = -ENOMEM;
+ goto err2;
+ }
+ memset(fec->rbd_base, 0, size);
+ /*
+ * Initialize RxBD ring
+ */
+ if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
+ ret = -ENOMEM;
+ goto err3;
+ }
+ flush_dcache_range((unsigned)fec->rbd_base,
+ (unsigned)fec->rbd_base + size);
+ }
/*
* Set interrupt mask register
writel((uint32_t)fec->tbd_base, &fec->eth->etdsr);
writel((uint32_t)fec->rbd_base, &fec->eth->erdsr);
- /*
- * Initialize RxBD/TxBD rings
- */
- if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
- free(fec->base_ptr);
- fec->base_ptr = NULL;
- return -ENOMEM;
- }
- fec_tbd_init(fec);
-
-
+#ifndef CONFIG_PHYLIB
if (fec->xcv_type != SEVENWIRE)
miiphy_restart_aneg(dev);
-
+#endif
fec_open(dev);
return 0;
+
+err3:
+ free(fec->rbd_base);
+err2:
+ free(fec->tbd_base);
+err1:
+ return ret;
}
/**
* @param[in] length Data count in bytes
* @return 0 on success
*/
-static int fec_send(struct eth_device *dev, volatile void* packet, int length)
+static int fec_send(struct eth_device *dev, volatile void *packet, int length)
{
unsigned int status;
+ uint32_t size;
+ uint32_t addr;
/*
* This routine transmits one frame. This routine only accepts
}
/*
- * Setup the transmit buffer
- * Note: We are always using the first buffer for transmission,
- * the second will be empty and only used to stop the DMA engine
+ * Setup the transmit buffer. We are always using the first buffer for
+ * transmission, the second will be empty and only used to stop the DMA
+ * engine. We also flush the packet to RAM here to avoid cache trouble.
*/
-#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
swap_packet((uint32_t *)packet, length);
#endif
+
+ addr = (uint32_t)packet;
+ size = roundup(length, ARCH_DMA_MINALIGN);
+ flush_dcache_range(addr, addr + size);
+
writew(length, &fec->tbd_base[fec->tbd_index].data_length);
- writel((uint32_t)packet, &fec->tbd_base[fec->tbd_index].data_pointer);
+ writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
+
/*
* update BD's status now
* This block:
status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
writew(status, &fec->tbd_base[fec->tbd_index].status);
+ /*
+ * Flush data cache. This code flushes both TX descriptors to RAM.
+ * After this code, the descriptors will be safely in RAM and we
+ * can start DMA.
+ */
+ size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+ addr = (uint32_t)fec->tbd_base;
+ flush_dcache_range(addr, addr + size);
+
/*
* Enable SmartDMA transmit task
*/
fec_tx_task_enable(fec);
/*
- * wait until frame is sent .
+ * Wait until frame is sent. On each turn of the wait cycle, we must
+ * invalidate data cache to see what's really in RAM. Also, we need
+ * barrier here.
*/
+ invalidate_dcache_range(addr, addr + size);
while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
udelay(1);
+ invalidate_dcache_range(addr, addr + size);
}
+
debug("fec_send: status 0x%x index %d\n",
readw(&fec->tbd_base[fec->tbd_index].status),
fec->tbd_index);
int frame_length, len = 0;
struct nbuf *frame;
uint16_t bd_status;
+ uint32_t addr, size;
+ int i;
uchar buff[FEC_MAX_PKT_SIZE];
/*
}
/*
- * ensure reading the right buffer status
+ * Read the buffer status. Before the status can be read, the data cache
+ * must be invalidated, because the data in RAM might have been changed
+ * by DMA. The descriptors are properly aligned to cachelines so there's
+ * no need to worry they'd overlap.
+ *
+ * WARNING: By invalidating the descriptor here, we also invalidate
+ * the descriptors surrounding this one. Therefore we can NOT change the
+ * contents of this descriptor nor the surrounding ones. The problem is
+ * that in order to mark the descriptor as processed, we need to change
+ * the descriptor. The solution is to mark the whole cache line when all
+ * descriptors in the cache line are processed.
*/
+ addr = (uint32_t)rbd;
+ addr &= ~(ARCH_DMA_MINALIGN - 1);
+ size = roundup(sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(addr, addr + size);
+
bd_status = readw(&rbd->status);
debug("fec_recv: status 0x%x\n", bd_status);
*/
frame = (struct nbuf *)readl(&rbd->data_pointer);
frame_length = readw(&rbd->data_length) - 4;
+ /*
+ * Invalidate data cache over the buffer
+ */
+ addr = (uint32_t)frame;
+ size = roundup(frame_length, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(addr, addr + size);
+
/*
* Fill the buffer and pass it to upper layers
*/
-#ifdef CONFIG_FEC_MXC_SWAP_PACKET
+#ifdef CONFIG_FEC_MXC_SWAP_PACKET
swap_packet((uint32_t *)frame->data, frame_length);
#endif
memcpy(buff, frame->data, frame_length);
(ulong)rbd->data_pointer,
bd_status);
}
+
/*
- * free the current buffer, restart the engine
- * and move forward to the next buffer
+ * Free the current buffer, restart the engine and move forward
+ * to the next buffer. Here we check if the whole cacheline of
+ * descriptors was already processed and if so, we mark it free
+ * as whole.
*/
- fec_rbd_clean(fec->rbd_index == (FEC_RBD_NUM - 1) ? 1 : 0, rbd);
+ size = RXDESC_PER_CACHELINE - 1;
+ if ((fec->rbd_index & size) == size) {
+ i = fec->rbd_index - size;
+ addr = (uint32_t)&fec->rbd_base[i];
+ for (; i <= fec->rbd_index ; i++) {
+ fec_rbd_clean(i == (FEC_RBD_NUM - 1),
+ &fec->rbd_base[i]);
+ }
+ flush_dcache_range(addr,
+ addr + ARCH_DMA_MINALIGN);
+ }
+
fec_rx_task_enable(fec);
fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
}
{
struct eth_device *edev;
struct fec_priv *fec;
+ struct mii_dev *bus;
unsigned char ethaddr[6];
uint32_t start;
int ret = 0;
}
fec->phy_id = phy_id;
- miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
-
+ bus = mdio_alloc();
+ if (!bus) {
+ printf("mdio_alloc failed\n");
+ ret = -ENOMEM;
+ goto err3;
+ }
+ bus->read = fec_phy_read;
+ bus->write = fec_phy_write;
+ sprintf(bus->name, edev->name);
+#ifdef CONFIG_MX28
+ /*
+ * The i.MX28 has two ethernet interfaces, but they are not equal.
+ * Only the first one can access the MDIO bus.
+ */
+ bus->priv = (struct ethernet_regs *)MXS_ENET0_BASE;
+#else
+ bus->priv = fec->eth;
+#endif
+ ret = mdio_register(bus);
+ if (ret) {
+ printf("mdio_register failed\n");
+ free(bus);
+ ret = -ENOMEM;
+ goto err3;
+ }
+ fec->bus = bus;
eth_register(edev);
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);
}
-
+ /* Configure phy */
+ fec_eth_phy_config(edev);
return ret;
err3:
return ret;
}
-#ifndef CONFIG_FEC_MXC_MULTI
+#ifndef CONFIG_FEC_MXC_MULTI
int fecmxc_initialize(bd_t *bd)
{
int lout = 1;
return lout;
}
+#ifndef CONFIG_PHYLIB
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
fec->mii_postcall = cb;
return 0;
}
+#endif
#define FEC_RCNTRL_FCE 0x00000020
#define FEC_RCNTRL_RGMII 0x00000040
#define FEC_RCNTRL_RMII 0x00000100
+#define FEC_RCNTRL_RMII_10T 0x00000200
#define FEC_TCNTRL_GTS 0x00000001
#define FEC_TCNTRL_HBC 0x00000002
#define FEC_ECNTRL_RESET 0x00000001 /* reset the FEC */
#define FEC_ECNTRL_ETHER_EN 0x00000002 /* enable the FEC */
+#define FEC_ECNTRL_SPEED 0x00000020
#define FEC_ECNTRL_DBSWAP 0x00000100
#define FEC_X_WMRK_STRFWD 0x00000100
#define MIIGSK_ENR_EN (1 << 1)
#endif
-/**
- * @brief Descriptor buffer alignment
- *
- * i.MX27 requires a 16 byte alignment (but for the first element only)
- */
-#define DB_ALIGNMENT 16
-
-/**
- * @brief Data buffer alignment
- *
- * i.MX27 requires a four byte alignment for transmit and 16 bits
- * alignment for receive so take 16
- * Note: Valid for member data_pointer in struct buffer_descriptor
- */
-#define DB_DATA_ALIGNMENT 16
-
/**
* @brief Receive & Transmit Buffer Descriptor definitions
*
struct fec_bd *tbd_base; /* TBD ring */
int tbd_index; /* next transmit BD to write */
bd_t *bd;
- void *rdb_ptr;
- void *base_ptr;
+ uint8_t *tdb_ptr;
int dev_id;
int phy_id;
+ struct mii_dev *bus;
+#ifdef CONFIG_PHYLIB
+ struct phy_device *phydev;
+#else
int (*mii_postcall)(int);
+#endif
};
/**
dev = &dmvgbe->dev;
- /* must be less than NAMESIZE (16) */
+ /* must be less than sizeof(dev->name) */
sprintf(dev->name, "egiga%d", devnum);
switch (devnum) {
* author Andy Fleming
*
*/
+#include <config.h>
+#include <common.h>
+#include <micrel.h>
#include <phy.h>
static struct phy_driver KSZ804_driver = {
.shutdown = &genphy_shutdown,
};
+/* ksz9021 PHY Registers */
+#define MII_KSZ9021_EXTENDED_CTRL 0x0b
+#define MII_KSZ9021_EXTENDED_DATAW 0x0c
+#define MII_KSZ9021_EXTENDED_DATAR 0x0d
+#define MII_KSZ9021_PHY_CTL 0x1f
+#define MIIM_KSZ9021_PHYCTL_1000 (1 << 6)
+#define MIIM_KSZ9021_PHYCTL_100 (1 << 5)
+#define MIIM_KSZ9021_PHYCTL_10 (1 << 4)
+#define MIIM_KSZ9021_PHYCTL_DUPLEX (1 << 3)
+
+#define CTRL1000_PREFER_MASTER (1 << 10)
+#define CTRL1000_CONFIG_MASTER (1 << 11)
+#define CTRL1000_MANUAL_CONFIG (1 << 12)
+
+int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
+{
+ /* extended registers */
+ phy_write(phydev, MDIO_DEVAD_NONE,
+ MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
+ return phy_write(phydev, MDIO_DEVAD_NONE,
+ MII_KSZ9021_EXTENDED_DATAW, val);
+}
+
+int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
+{
+ /* extended registers */
+ phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
+ return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
+}
+
+/* Micrel ksz9021 */
+static int ksz9021_config(struct phy_device *phydev)
+{
+ unsigned ctrl1000 = 0;
+ const unsigned master = CTRL1000_PREFER_MASTER |
+ CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
+ unsigned features = phydev->drv->features;
+
+ if (getenv("disable_giga"))
+ features &= ~(SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full);
+ /* force master mode for 1000BaseT due to chip errata */
+ if (features & SUPPORTED_1000baseT_Half)
+ ctrl1000 |= ADVERTISE_1000HALF | master;
+ if (features & SUPPORTED_1000baseT_Full)
+ ctrl1000 |= ADVERTISE_1000FULL | master;
+ phydev->advertising = phydev->supported = features;
+ phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
+ genphy_config_aneg(phydev);
+ genphy_restart_aneg(phydev);
+ return 0;
+}
+
+static int ksz9021_startup(struct phy_device *phydev)
+{
+ unsigned phy_ctl;
+ genphy_update_link(phydev);
+ phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_PHY_CTL);
+
+ if (phy_ctl & MIIM_KSZ9021_PHYCTL_DUPLEX)
+ phydev->duplex = DUPLEX_FULL;
+ else
+ phydev->duplex = DUPLEX_HALF;
+
+ if (phy_ctl & MIIM_KSZ9021_PHYCTL_1000)
+ phydev->speed = SPEED_1000;
+ else if (phy_ctl & MIIM_KSZ9021_PHYCTL_100)
+ phydev->speed = SPEED_100;
+ else if (phy_ctl & MIIM_KSZ9021_PHYCTL_10)
+ phydev->speed = SPEED_10;
+ return 0;
+}
+
+static struct phy_driver ksz9021_driver = {
+ .name = "Micrel ksz9021",
+ .uid = 0x221610,
+ .mask = 0xfffff0,
+ .features = PHY_GBIT_FEATURES,
+ .config = &ksz9021_config,
+ .startup = &ksz9021_startup,
+ .shutdown = &genphy_shutdown,
+};
+
int phy_micrel_init(void)
{
phy_register(&KSZ804_driver);
phy_register(&KS8721_driver);
+ phy_register(&ksz9021_driver);
return 0;
}
static int __board_phy_config(struct phy_device *phydev)
{
+ if (phydev->drv->config)
+ return phydev->drv->config(phydev);
return 0;
}
int phy_config(struct phy_device *phydev)
{
- if (phydev->drv->config)
- phydev->drv->config(phydev);
-
/* Invoke an optional board-specific helper */
board_phy_config(phydev);
/*
* sh_eth.c - Driver for Renesas SH7763's ethernet controler.
*
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Copyright (c) 2008 Nobuhiro Iwamatsu
+ * Copyright (C) 2008, 2011 Renesas Solutions Corp.
+ * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu
* Copyright (c) 2007 Carlos Munoz <carlos@kenati.com>
*
* This program is free software; you can redistribute it and/or modify
#define flush_cache_wback(...)
#endif
-#define SH_ETH_PHY_DELAY 50000
+#define TIMEOUT_CNT 1000
int sh_eth_send(struct eth_device *dev, volatile void *packet, int len)
{
outl(EDTRR_TRNS, EDTRR(port));
/* Wait until packet is transmitted */
- timeout = 1000;
+ timeout = TIMEOUT_CNT;
while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--)
udelay(100);
if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC)
port_info->tx_desc_cur = port_info->tx_desc_base;
- return ret;
err:
return ret;
}
return len;
}
-#define EDMR_INIT_CNT 1000
static int sh_eth_reset(struct sh_eth_dev *eth)
{
int port = eth->port;
/* Perform a software reset and wait for it to complete */
outl(EDMR_SRST, EDMR(port));
- for (i = 0; i < EDMR_INIT_CNT; i++) {
+ for (i = 0; i < TIMEOUT_CNT ; i++) {
if (!(inl(EDMR(port)) & EDMR_SRST))
break;
udelay(1000);
}
- if (i == EDMR_INIT_CNT) {
+ if (i == TIMEOUT_CNT) {
printf(SHETHER_NAME ": Software reset timeout\n");
ret = -EIO;
}
outl(0, TFTR(port));
outl((FIFO_SIZE_T | FIFO_SIZE_R), FDR(port));
outl(RMCR_RST, RMCR(port));
-#ifndef CONFIG_CPU_SH7757
+#if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724)
outl(0, RPADIR(port));
#endif
outl((FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR(port));
outl(val, MALR(port));
outl(RFLR_RFL_MIN, RFLR(port));
-#ifndef CONFIG_CPU_SH7757
+#if !defined(CONFIG_CPU_SH7757) && !defined(CONFIG_CPU_SH7724)
outl(0, PIPR(port));
#endif
+#if !defined(CONFIG_CPU_SH7724)
outl(APR_AP, APR(port));
outl(MPR_MP, MPR(port));
-#ifdef CONFIG_CPU_SH7757
- outl(TPAUSER_UNLIMITED, TPAUSER(port));
-#else
+#endif
+#if defined(CONFIG_CPU_SH7763)
outl(TPAUSER_TPAUSE, TPAUSER(port));
+#elif defined(CONFIG_CPU_SH7757)
+ outl(TPAUSER_UNLIMITED, TPAUSER(port));
#endif
+
/* Configure phy */
ret = sh_eth_phy_config(eth);
if (ret) {
phy = port_info->phydev;
phy_startup(phy);
+ val = 0;
+
/* Set the transfer speed */
-#ifdef CONFIG_CPU_SH7763
if (phy->speed == 100) {
printf(SHETHER_NAME ": 100Base/");
+#ifdef CONFIG_CPU_SH7763
outl(GECMR_100B, GECMR(port));
+#elif defined(CONFIG_CPU_SH7757)
+ outl(1, RTRATE(port));
+#elif defined(CONFIG_CPU_SH7724)
+ val = ECMR_RTM;
+#endif
} else if (phy->speed == 10) {
printf(SHETHER_NAME ": 10Base/");
+#ifdef CONFIG_CPU_SH7763
outl(GECMR_10B, GECMR(port));
- }
-#endif
-#if defined(CONFIG_CPU_SH7757)
- if (phy->speed == 100) {
- printf("100Base/");
- outl(1, RTRATE(port));
- } else if (phy->speed == 10) {
- printf("10Base/");
+#elif defined(CONFIG_CPU_SH7757)
outl(0, RTRATE(port));
- }
#endif
+ }
/* Check if full duplex mode is supported by the phy */
if (phy->duplex) {
printf("Full\n");
- outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port));
+ outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port));
} else {
printf("Half\n");
- outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port));
+ outl(val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port));
}
return ret;
/*
* sh_eth.h - Driver for Renesas SuperH ethernet controler.
*
- * Copyright (C) 2008 Renesas Solutions Corp.
- * Copyright (c) 2008 Nobuhiro Iwamatsu
+ * Copyright (C) 2008, 2011 Renesas Solutions Corp.
+ * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu
* Copyright (c) 2007 Carlos Munoz <carlos@kenati.com>
*
* This program is free software; you can redistribute it and/or modify
#define MAHR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x01c0)
#define MALR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x01c8)
#define RTRATE(port) (BASE_IO_ADDR + 0x800 * (port) + 0x01fc)
+
+#elif defined(CONFIG_CPU_SH7724)
+#define BASE_IO_ADDR 0xA4600000
+
+#define TDLAR(port) (BASE_IO_ADDR + 0x0018)
+#define RDLAR(port) (BASE_IO_ADDR + 0x0020)
+
+#define EDMR(port) (BASE_IO_ADDR + 0x0000)
+#define EDTRR(port) (BASE_IO_ADDR + 0x0008)
+#define EDRRR(port) (BASE_IO_ADDR + 0x0010)
+#define EESR(port) (BASE_IO_ADDR + 0x0028)
+#define EESIPR(port) (BASE_IO_ADDR + 0x0030)
+#define TRSCER(port) (BASE_IO_ADDR + 0x0038)
+#define TFTR(port) (BASE_IO_ADDR + 0x0048)
+#define FDR(port) (BASE_IO_ADDR + 0x0050)
+#define RMCR(port) (BASE_IO_ADDR + 0x0058)
+#define FCFTR(port) (BASE_IO_ADDR + 0x0070)
+#define ECMR(port) (BASE_IO_ADDR + 0x0100)
+#define RFLR(port) (BASE_IO_ADDR + 0x0108)
+#define ECSIPR(port) (BASE_IO_ADDR + 0x0118)
+#define PIR(port) (BASE_IO_ADDR + 0x0120)
+#define APR(port) (BASE_IO_ADDR + 0x0154)
+#define MPR(port) (BASE_IO_ADDR + 0x0158)
+#define TPAUSER(port) (BASE_IO_ADDR + 0x0164)
+#define MAHR(port) (BASE_IO_ADDR + 0x01c0)
+#define MALR(port) (BASE_IO_ADDR + 0x01c8)
#endif
/*
EDMR_SRST = 0x03,
EMDR_DESC_R = 0x30, /* Descriptor reserve size */
EDMR_EL = 0x40, /* Litte endian */
-#elif defined CONFIG_CPU_SH7757
+#elif defined(CONFIG_CPU_SH7757) ||defined (CONFIG_CPU_SH7724)
EDMR_SRST = 0x01,
EMDR_DESC_R = 0x30, /* Descriptor reserve size */
EDMR_EL = 0x40, /* Litte endian */
/* Transfer descriptor bit */
enum TD_STS_BIT {
-#if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7757)
+#if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7757) \
+ || defined(CONFIG_CPU_SH7724)
TD_TACT = 0x80000000,
#else
TD_TACT = 0x7fffffff,
ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002,
ECMR_PRM = 0x00000001,
+#ifdef CONFIG_CPU_SH7724
+ ECMR_RTM = 0x00000010,
+#endif
+
};
#ifdef CONFIG_CPU_SH7763
ECMR_TXF | ECMR_MCT)
#elif CONFIG_CPU_SH7757
#define ECMR_CHG_DM (ECMR_ZPF)
+#elif CONFIG_CPU_SH7724
+#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
#else
#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
#endif
#endif /* !CONFIG_SMC91111_EXT_PHY */
-/*------------------------------------------------------------
- . Waits the specified number of milliseconds - kernel friendly
- .-------------------------------------------------------------*/
-#ifndef CONFIG_SMC91111_EXT_PHY
-static void smc_wait_ms(unsigned int ms)
-{
- udelay(ms*1000);
-}
-#endif /* !CONFIG_SMC91111_EXT_PHY */
-
-
/*------------------------------------------------------------
. Configures the specified PHY using Autonegotiation. Calls
. smc_phy_fixed() if the user has requested a certain config.
break;
}
- smc_wait_ms (500); /* wait 500 millisecs */
+ mdelay(500); /* wait 500 millisecs */
}
if (timeout < 1) {
break;
}
- smc_wait_ms (500); /* wait 500 millisecs */
+ mdelay(500); /* wait 500 millisecs */
/* Restart auto-negotiation if remote fault */
if (status & PHY_STAT_REM_FLT) {
#define FSL_PCIE_CFG_RDY 0x4b0
#define FSL_PROG_IF_AGENT 0x1
-void pciauto_prescan_setup_bridge(struct pci_controller *hose,
- pci_dev_t dev, int sub_bus);
-void pciauto_postscan_setup_bridge(struct pci_controller *hose,
- pci_dev_t dev, int sub_bus);
-void pciauto_config_init(struct pci_controller *hose);
-
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS 0
#endif
* to get the correct result when scanning bridges
*/
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
-extern void pciauto_config_init(struct pci_controller *hose);
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
const char * pci_class_str(u8 class)
COBJS-$(CONFIG_I82365) += i82365.o
COBJS-$(CONFIG_8xx) += mpc8xx_pcmcia.o
-COBJS-$(CONFIG_PXA_PCMCIA) += pxa_pcmcia.o
COBJS-y += rpx_pcmcia.o
COBJS-$(CONFIG_IDE_TI_CARDBUS) += ti_pci1410a.o
COBJS-y += tqm8xx_pcmcia.o
+++ /dev/null
-#include <common.h>
-#include <config.h>
-
-#include <pcmcia.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/io.h>
-
-static inline void msWait(unsigned msVal)
-{
- udelay(msVal*1000);
-}
-
-int pcmcia_on (void)
-{
- unsigned int reg_arr[] = {
- 0x48000028, CONFIG_SYS_MCMEM0_VAL,
- 0x4800002c, CONFIG_SYS_MCMEM1_VAL,
- 0x48000030, CONFIG_SYS_MCATT0_VAL,
- 0x48000034, CONFIG_SYS_MCATT1_VAL,
- 0x48000038, CONFIG_SYS_MCIO0_VAL,
- 0x4800003c, CONFIG_SYS_MCIO1_VAL,
-
- 0, 0
- };
- int i, rc;
-
-#ifdef CONFIG_EXADRON1
- int cardDetect;
- volatile unsigned int *v_pBCRReg =
- (volatile unsigned int *) 0x08000000;
-#endif
-
- debug ("%s\n", __FUNCTION__);
-
- i = 0;
- while (reg_arr[i]) {
- (*(volatile unsigned int *) reg_arr[i]) |= reg_arr[i + 1];
- i += 2;
- }
- udelay (1000);
-
- debug ("%s: programmed mem controller \n", __FUNCTION__);
-
-#ifdef CONFIG_EXADRON1
-
-/*define useful BCR masks */
-#define BCR_CF_INIT_VAL 0x00007230
-#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
-#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
-#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
-#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
-
- /* we see from the GPIO bit if the card is present */
- cardDetect = !(GPLR0 & GPIO_bit (14));
-
- if (cardDetect) {
- printf ("No PCMCIA card found!\n");
- }
-
- /* reset the card via the BCR line */
- *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
- msWait (500);
-
- *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
- msWait (1500);
-
- /* enable address bus */
- GPCR1 = 0x01;
- /* and the first CF slot */
- MECR = 0x00000002;
-
-#endif /* EXADRON 1 */
-
- rc = check_ide_device (0); /* use just slot 0 */
-
- return rc;
-}
-
-#if defined(CONFIG_CMD_PCMCIA)
-int pcmcia_off (void)
-{
- return 0;
-}
-#endif
void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val,
u8 dev_grp, u8 dev_grp_sel)
{
- /* Select the Device Group */
- twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, dev_grp_sel,
- dev_grp);
+ int ret;
/* Select the Voltage */
- twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, vsel_val,
+ ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, vsel_val,
vsel_reg);
+ if (ret != 0) {
+ printf("Could could not write vsel to reg %02x (%d)\n",
+ vsel_reg, ret);
+ return;
+ }
+
+ /* Select the Device Group (enable the supply if dev_grp_sel != 0) */
+ ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, dev_grp_sel,
+ dev_grp);
+ if (ret != 0)
+ printf("Could could not write grp_sel to reg %02x (%d)\n",
+ dev_grp, ret);
}
void twl4030_power_init(void)
#endif
struct fixed_phy_port {
- char name[NAMESIZE]; /* ethernet port name */
+ char name[16]; /* ethernet port name */
unsigned int speed; /* specified speed 10,100 or 1000 */
unsigned int duplex; /* specified duplex FULL or HALF */
};
#define SCBRR_VALUE(bps, clk) scbrr_calc(sh_sci, bps, clk)
#elif defined(__H8300H__) || defined(__H8300S__)
#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
-#elif defined(CONFIG_CPU_SH7264)
-#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps))
#else /* Generic SH */
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
#endif
};
+#if defined(CONFIG_USBD_HS)
+static struct usb_qualifier_descriptor qualifier_descriptor = {
+ .bLength = sizeof(struct usb_qualifier_descriptor),
+ .bDescriptorType = USB_DT_QUAL,
+ .bcdUSB = cpu_to_le16(USB_BCD_VERSION),
+ .bDeviceClass = COMMUNICATIONS_DEVICE_CLASS,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE,
+ .bNumConfigurations = NUM_CONFIGS
+};
+#endif
+
/*
* Static CDC ACM specific descriptors
*/
memset (device_instance, 0, sizeof (struct usb_device_instance));
device_instance->device_state = STATE_INIT;
device_instance->device_descriptor = &device_descriptor;
+#if defined(CONFIG_USBD_HS)
+ device_instance->qualifier_descriptor = &qualifier_descriptor;
+#endif
device_instance->event = usbtty_event_handler;
device_instance->cdc_recv_setup = usbtty_cdc_setup;
device_instance->bus = bus_instance;
device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM);
+#if defined(CONFIG_USBD_HS)
+ qualifier_descriptor.bDeviceClass =
+ COMMUNICATIONS_DEVICE_CLASS;
+#endif
/* Assign endpoint indices */
tx_endpoint = ACM_TX_ENDPOINT;
rx_endpoint = ACM_RX_ENDPOINT;
device_descriptor.bDeviceClass = 0xFF;
device_descriptor.idProduct =
cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL);
-
+#if defined(CONFIG_USBD_HS)
+ qualifier_descriptor.bDeviceClass = 0xFF;
+#endif
/* Assign endpoint indices */
tx_endpoint = GSERIAL_TX_ENDPOINT;
rx_endpoint = GSERIAL_RX_ENDPOINT;
static void usbtty_event_handler (struct usb_device_instance *device,
usb_device_event_t event, int data)
{
+#if defined(CONFIG_USBD_HS)
+ int i;
+#endif
switch (event) {
case DEVICE_RESET:
case DEVICE_BUS_INACTIVE:
break;
case DEVICE_ADDRESS_ASSIGNED:
+#if defined(CONFIG_USBD_HS)
+ /*
+ * is_usbd_high_speed routine needs to be defined by
+ * specific gadget driver
+ * It returns TRUE if device enumerates at High speed
+ * Retuns FALSE otherwise
+ */
+ for (i = 0; i < NUM_ENDPOINTS; i++) {
+ if (((ep_descriptor_ptrs[i]->bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) ==
+ USB_ENDPOINT_XFER_BULK)
+ && is_usbd_high_speed()) {
+
+ ep_descriptor_ptrs[i]->wMaxPacketSize =
+ CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE;
+ }
+
+ endpoint_instance[i + 1].tx_packetSize =
+ ep_descriptor_ptrs[i]->wMaxPacketSize;
+ endpoint_instance[i + 1].rcv_packetSize =
+ ep_descriptor_ptrs[i]->wMaxPacketSize;
+ }
+#endif
usbtty_init_endpoints ();
default:
#include <usb/musb_udc.h>
#elif defined(CONFIG_CPU_PXA27X)
#include <usb/pxa27x_udc.h>
-#elif defined(CONFIG_SPEAR3XX) || defined(CONFIG_SPEAR600)
-#include <usb/spr_udc.h>
+#elif defined(CONFIG_DW_UDC)
+#include <usb/designware_udc.h>
#endif
#include <version.h>
#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE
#define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE
+#if defined(CONFIG_USBD_HS)
+#define CONFIG_USBD_SERIAL_BULK_HS_PKTSIZE UDC_BULK_HS_PACKET_SIZE
+#endif
+
#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS
#define USBTTY_BCD_DEVICE 0x00
#error "i.MX27 CSPI not supported due to drastic differences in register definitions" \
"See linux mxc_spi driver from Freescale for details."
-
-#elif defined(CONFIG_MX31)
-
-#define MXC_CSPICTRL_EN (1 << 0)
-#define MXC_CSPICTRL_MODE (1 << 1)
-#define MXC_CSPICTRL_XCH (1 << 2)
-#define MXC_CSPICTRL_SMC (1 << 3)
-#define MXC_CSPICTRL_POL (1 << 4)
-#define MXC_CSPICTRL_PHA (1 << 5)
-#define MXC_CSPICTRL_SSCTL (1 << 6)
-#define MXC_CSPICTRL_SSPOL (1 << 7)
-#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 24)
-#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0x1f) << 8)
-#define MXC_CSPICTRL_DATARATE(x) (((x) & 0x7) << 16)
-#define MXC_CSPICTRL_TC (1 << 8)
-#define MXC_CSPICTRL_RXOVF (1 << 6)
-#define MXC_CSPICTRL_MAXBITS 0x1f
-
-#define MXC_CSPIPERIOD_32KHZ (1 << 15)
-#define MAX_SPI_BYTES 4
-
-static unsigned long spi_bases[] = {
- 0x43fa4000,
- 0x50010000,
- 0x53f84000,
-};
-
-#elif defined(CONFIG_MX51)
-
-#define MXC_CSPICTRL_EN (1 << 0)
-#define MXC_CSPICTRL_MODE (1 << 1)
-#define MXC_CSPICTRL_XCH (1 << 2)
-#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 12)
-#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0xfff) << 20)
-#define MXC_CSPICTRL_PREDIV(x) (((x) & 0xF) << 12)
-#define MXC_CSPICTRL_POSTDIV(x) (((x) & 0xF) << 8)
-#define MXC_CSPICTRL_SELCHAN(x) (((x) & 0x3) << 18)
-#define MXC_CSPICTRL_MAXBITS 0xfff
-#define MXC_CSPICTRL_TC (1 << 7)
-#define MXC_CSPICTRL_RXOVF (1 << 6)
-
-#define MXC_CSPIPERIOD_32KHZ (1 << 15)
-#define MAX_SPI_BYTES 32
-
-/* Bit position inside CTRL register to be associated with SS */
-#define MXC_CSPICTRL_CHAN 18
-
-/* Bit position inside CON register to be associated with SS */
-#define MXC_CSPICON_POL 4
-#define MXC_CSPICON_PHA 0
-#define MXC_CSPICON_SSPOL 12
-
-static unsigned long spi_bases[] = {
- CSPI1_BASE_ADDR,
- CSPI2_BASE_ADDR,
- CSPI3_BASE_ADDR,
-};
-
-#elif defined(CONFIG_MX35)
-
-#define MXC_CSPICTRL_EN (1 << 0)
-#define MXC_CSPICTRL_MODE (1 << 1)
-#define MXC_CSPICTRL_XCH (1 << 2)
-#define MXC_CSPICTRL_SMC (1 << 3)
-#define MXC_CSPICTRL_POL (1 << 4)
-#define MXC_CSPICTRL_PHA (1 << 5)
-#define MXC_CSPICTRL_SSCTL (1 << 6)
-#define MXC_CSPICTRL_SSPOL (1 << 7)
-#define MXC_CSPICTRL_CHIPSELECT(x) (((x) & 0x3) << 12)
-#define MXC_CSPICTRL_BITCOUNT(x) (((x) & 0xfff) << 20)
-#define MXC_CSPICTRL_DATARATE(x) (((x) & 0x7) << 16)
-#define MXC_CSPICTRL_TC (1 << 7)
-#define MXC_CSPICTRL_RXOVF (1 << 6)
-#define MXC_CSPICTRL_MAXBITS 0xfff
-
-#define MXC_CSPIPERIOD_32KHZ (1 << 15)
-#define MAX_SPI_BYTES 4
+#endif
static unsigned long spi_bases[] = {
- 0x43fa4000,
- 0x50010000,
+ MXC_SPI_BASE_ADDRESSES
};
-#else
-#error "Unsupported architecture"
-#endif
-
#define OUT MXC_GPIO_DIRECTION_OUT
#define reg_read readl
struct spi_slave slave;
unsigned long base;
u32 ctrl_reg;
-#if defined(CONFIG_MX51)
+#if defined(MXC_ECSPI)
u32 cfg_reg;
#endif
int gpio;
return i;
}
-#if defined(CONFIG_MX31) || defined(CONFIG_MX35)
+#ifdef MXC_CSPI
static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
}
#endif
-#if defined(CONFIG_MX51)
+#ifdef MXC_ECSPI
static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
MXC_CSPICTRL_BITCOUNT(bitlen - 1);
reg_write(®s->ctrl, mxcs->ctrl_reg | MXC_CSPICTRL_EN);
-#ifdef CONFIG_MX51
+#ifdef MXC_ECSPI
reg_write(®s->cfg, mxcs->cfg_reg);
#endif
if (mx28_wait_mask_set(&ssp_regs->hw_ssp_ctrl0_reg,
SSP_CTRL0_RUN, MXS_SPI_MAX_TIMEOUT)) {
printf("MXS SPI: Timeout waiting for start\n");
- return -1;
+ return -ETIMEDOUT;
}
if (tx)
if (mx28_wait_mask_clr(&ssp_regs->hw_ssp_status_reg,
SSP_STATUS_FIFO_EMPTY, MXS_SPI_MAX_TIMEOUT)) {
printf("MXS SPI: Timeout waiting for data\n");
- return -1;
+ return -ETIMEDOUT;
}
*rx = readl(&ssp_regs->hw_ssp_data);
if (mx28_wait_mask_clr(&ssp_regs->hw_ssp_ctrl0_reg,
SSP_CTRL0_RUN, MXS_SPI_MAX_TIMEOUT)) {
printf("MXS SPI: Timeout waiting for finish\n");
- return -1;
+ return -ETIMEDOUT;
}
}
return 0;
}
+/*McSPI Transmit Receive Mode*/
+int omap3_spi_txrx(struct spi_slave *slave,
+ unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags)
+{
+ struct omap3_spi_slave *ds = to_omap3_spi(slave);
+ int timeout = SPI_WAIT_TIMEOUT;
+ int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
+ int irqstatus = readl(&ds->regs->irqstatus);
+ int i=0;
+
+ /*Enable SPI channel*/
+ if (flags & SPI_XFER_BEGIN)
+ writel(OMAP3_MCSPI_CHCTRL_EN,
+ &ds->regs->channel[ds->slave.cs].chctrl);
+
+ /*set TRANSMIT-RECEIVE Mode*/
+ chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+ chconf |= OMAP3_MCSPI_CHCONF_FORCE;
+ writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+
+ /*Shift in and out 1 byte at time*/
+ for (i=0; i < len; i++){
+ /* Write: wait for TX empty (TXS == 1)*/
+ irqstatus |= (1<< (4*(ds->slave.bus)));
+ while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
+ OMAP3_MCSPI_CHSTAT_TXS)) {
+ if (--timeout <= 0) {
+ printf("SPI TXS timed out, status=0x%08x\n",
+ readl(&ds->regs->channel[ds->slave.cs].chstat));
+ return -1;
+ }
+ }
+ /* Write the data */
+ writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
+
+ /*Read: wait for RX containing data (RXS == 1)*/
+ while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
+ OMAP3_MCSPI_CHSTAT_RXS)) {
+ if (--timeout <= 0) {
+ printf("SPI RXS timed out, status=0x%08x\n",
+ readl(&ds->regs->channel[ds->slave.cs].chstat));
+ return -1;
+ }
+ }
+ /* Read the data */
+ rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
+ }
+
+ /*if transfer must be terminated disable the channel*/
+ if (flags & SPI_XFER_END) {
+ chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
+ writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+
+ writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+ }
+
+ return 0;
+}
+
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
}
ret = 0;
} else {
- if (dout != NULL)
+ if (dout != NULL && din != NULL)
+ ret = omap3_spi_txrx(slave, len, txp, rxp, flags);
+ else if (dout != NULL)
ret = omap3_spi_write(slave, len, txp, flags);
-
- if (din != NULL)
+ else if (din != NULL)
ret = omap3_spi_read(slave, len, rxp, flags);
}
return ret;
return container_of(slave, struct omap3_spi_slave, slave);
}
+int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, const u8 *txp,
+ u8 *rxp, unsigned long flags);
int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
unsigned long flags);
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
/*
* SH SPI driver
*
- * Copyright (C) 2011 Renesas Solutions Corp.
+ * Copyright (C) 2011-2012 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
{
}
+static void sh_spi_set_cs(struct sh_spi *ss, unsigned int cs)
+{
+ unsigned long val = 0;
+
+ if (cs & 0x01)
+ val |= SH_SPI_SSS0;
+ if (cs & 0x02)
+ val |= SH_SPI_SSS1;
+
+ sh_spi_clear_bit(SH_SPI_SSS0 | SH_SPI_SSS1, &ss->regs->cr4);
+ sh_spi_set_bit(val, &ss->regs->cr4);
+}
+
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
sh_spi_write(0x00, &ss->regs->cr1);
/* CR3 init */
sh_spi_write(0x00, &ss->regs->cr3);
+ sh_spi_set_cs(ss, cs);
clear_fifo(ss);
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
- /* This driver supports "bus = 0" and "cs = 0" only. */
- if (!bus && !cs)
+ if (!bus && cs < SH_SPI_NUM_CS)
return 1;
else
return 0;
#define SH_SPI_TBFI 0x40
#define SH_SPI_RBEI 0x20
#define SH_SPI_RBFI 0x10
+#define SH_SPI_SSS1 0x08
#define SH_SPI_WPABRT 0x04
-#define SH_SPI_SSS 0x01
+#define SH_SPI_SSS0 0x01
#define SH_SPI_FIFO_SIZE 32
+#define SH_SPI_NUM_CS 4
struct sh_spi {
struct spi_slave slave;
old_async = usb_disable_asynch(1); /* asynch transfer not allowed */
- for (i = 0; i < USB_MAX_ETH_DEV; i++)
- memset(&usb_eth[i], 0, sizeof(usb_eth[i]));
+ /* unregister a previously detected device */
+ for (i = 0; i < usb_max_eth_dev; i++)
+ eth_unregister(&usb_eth[i].eth_dev);
+
+ memset(usb_eth, 0, sizeof(usb_eth));
for (i = 0; prob_dev[i].probe; i++) {
if (prob_dev[i].before_probe)
ifdef CONFIG_USB_DEVICE
COBJS-y += core.o
COBJS-y += ep0.o
+COBJS-$(CONFIG_DW_UDC) += designware_udc.o
COBJS-$(CONFIG_OMAP1510) += omap1510_udc.o
COBJS-$(CONFIG_OMAP1610) += omap1510_udc.o
COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
COBJS-$(CONFIG_CPU_PXA27X) += pxa27x_udc.o
-COBJS-$(CONFIG_SPEARUDC) += spr_udc.o
endif
endif
return (device->device_descriptor);
}
-
/**
* usbd_device_configuration_descriptor
* @device: which device
#include <usbdevice.h>
#include "ep0.h"
-#include <usb/spr_udc.h>
+#include <usb/designware_udc.h>
#include <asm/arch/hardware.h>
-#include <asm/arch/spr_misc.h>
#define UDC_INIT_MDELAY 80 /* Device settle delay */
/* Some kind of debugging output... */
-#ifndef DEBUG_SPRUSBTTY
+#ifndef DEBUG_DWUSBTTY
#define UDCDBG(str)
#define UDCDBGA(fmt, args...)
#else
u32 i, nw, nb;
u32 *wrdp;
u8 *bytp;
+ u32 tmp[128];
if (readl(&udc_regs_p->dev_stat) & DEV_STAT_RXFIFO_EMPTY)
return -1;
nw = len / sizeof(u32);
nb = len % sizeof(u32);
- wrdp = (u32 *)bufp;
+ /* use tmp buf if bufp is not word aligned */
+ if ((int)bufp & 0x3)
+ wrdp = (u32 *)&tmp[0];
+ else
+ wrdp = (u32 *)bufp;
+
for (i = 0; i < nw; i++) {
writel(readl(fifo_ptr), wrdp);
wrdp++;
}
readl(&outep_regs_p[epNum].write_done);
+ /* copy back tmp buffer to bufp if bufp is not word aligned */
+ if ((int)bufp & 0x3)
+ memcpy(bufp, tmp, len);
+
return 0;
}
}
/*
- * spear_write_noniso_tx_fifo - Write the next packet to TxFIFO.
+ * dw_write_noniso_tx_fifo - Write the next packet to TxFIFO.
* @endpoint: Endpoint pointer.
*
* If the endpoint has an active tx_urb, then the next packet of data from the
* transmitted in this packet.
*
*/
-static void spear_write_noniso_tx_fifo(struct usb_endpoint_instance
+static void dw_write_noniso_tx_fifo(struct usb_endpoint_instance
*endpoint)
{
struct urb *urb = endpoint->tx_urb;
* Handle SETUP USB interrupt.
* This function implements TRM Figure 14-14.
*/
-static void spear_udc_setup(struct usb_endpoint_instance *endpoint)
+static void dw_udc_setup(struct usb_endpoint_instance *endpoint)
{
u8 *datap = (u8 *)&ep0_urb->device_request;
int ep_addr = endpoint->endpoint_address;
endpoint->tx_urb = ep0_urb;
endpoint->sent = 0;
/*
- * Write packet data to the FIFO. spear_write_noniso_tx_fifo
+ * Write packet data to the FIFO. dw_write_noniso_tx_fifo
* will update endpoint->last with the number of bytes written
* to the FIFO.
*/
- spear_write_noniso_tx_fifo(endpoint);
+ dw_write_noniso_tx_fifo(endpoint);
writel(0x0, &inep_regs_p[ep_addr].write_done);
}
/*
* Handle endpoint 0 RX interrupt
*/
-static void spear_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
+static void dw_udc_ep0_rx(struct usb_endpoint_instance *endpoint)
{
u8 dummy[64];
/*
* Handle endpoint 0 TX interrupt
*/
-static void spear_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
+static void dw_udc_ep0_tx(struct usb_endpoint_instance *endpoint)
{
struct usb_device_request *request = &ep0_urb->device_request;
int ep_addr;
* need a zero-length terminating packet.
*/
UDCDBG("ACK control read data stage packet");
- spear_write_noniso_tx_fifo(endpoint);
+ dw_write_noniso_tx_fifo(endpoint);
ep_addr = endpoint->endpoint_address;
writel(0x0, &inep_regs_p[ep_addr].write_done);
}
}
-static struct usb_endpoint_instance *spear_find_ep(int ep)
+static struct usb_endpoint_instance *dw_find_ep(int ep)
{
int i;
* The ep argument is a physical endpoint number for a non-ISO IN endpoint
* in the range 1 to 15.
*/
-static void spear_udc_epn_rx(int ep)
+static void dw_udc_epn_rx(int ep)
{
int nbytes = 0;
struct urb *urb;
- struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
+ struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
if (endpoint) {
urb = endpoint->rcv_urb;
* The ep argument is a physical endpoint number for a non-ISO IN endpoint
* in the range 16 to 30.
*/
-static void spear_udc_epn_tx(int ep)
+static void dw_udc_epn_tx(int ep)
{
- struct usb_endpoint_instance *endpoint = spear_find_ep(ep);
+ struct usb_endpoint_instance *endpoint = dw_find_ep(ep);
+
+ if (!endpoint)
+ return;
/*
* We need to transmit a terminating zero-length packet now if
* we have sent all of the data in this URB and the transfer
* size was an exact multiple of the packet size.
*/
- if (endpoint && endpoint->tx_urb && endpoint->tx_urb->actual_length) {
- if (endpoint->last == endpoint->tx_packetSize) {
- /* handle zero length packet here */
- writel(0x0, &inep_regs_p[ep].write_done);
- }
+ if (endpoint->tx_urb &&
+ (endpoint->last == endpoint->tx_packetSize) &&
+ (endpoint->tx_urb->actual_length - endpoint->sent -
+ endpoint->last == 0)) {
+ /* handle zero length packet here */
+ writel(0x0, &inep_regs_p[ep].write_done);
+
+ }
+
+ if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
/* retire the data that was just sent */
usbd_tx_complete(endpoint);
/*
*/
if (endpoint->tx_urb && endpoint->tx_urb->actual_length) {
/* write data to FIFO */
- spear_write_noniso_tx_fifo(endpoint);
+ dw_write_noniso_tx_fifo(endpoint);
writel(0x0, &inep_regs_p[ep].write_done);
} else if (endpoint->tx_urb
readl(&plug_regs_p->plug_pending);
- udc_disconnect();
-
for (i = 0; i < UDC_INIT_MDELAY; i++)
udelay(1000);
writel(~0x0, &udc_regs_p->dev_int_mask);
writel(~0x0, &udc_regs_p->endp_int_mask);
+#ifndef CONFIG_USBD_HS
writel(DEV_CONF_FS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
- /* Dev_Conf_SYNCFRAME | */
DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
+#else
+ writel(DEV_CONF_HS_SPEED | DEV_CONF_REMWAKEUP | DEV_CONF_SELFPOW |
+ DEV_CONF_PHYINT_16, &udc_regs_p->dev_conf);
+#endif
- writel(0x0, &udc_regs_p->dev_cntl);
+ writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl);
/* Clear all interrupts pending */
writel(DEV_INT_MSK, &udc_regs_p->dev_int);
return 0;
}
+int is_usbd_high_speed(void)
+{
+ return (readl(&udc_regs_p->dev_stat) & DEV_STAT_ENUM) ? 0 : 1;
+}
+
/*
* udc_setup_ep - setup endpoint
* Associate a physical endpoint with endpoint_instance
char *tt;
u32 endp_intmask;
+ if ((ep != 0) && (udc_device->device_state < STATE_ADDRESSED))
+ return;
+
tt = getenv("usbtty");
if (!tt)
tt = "generic";
writel(packet_size | ((buffer_size / sizeof(int)) << 16),
&out_p->endp_maxpacksize);
- writel((packet_size << 19) | ENDP_EPTYPE_CNTL,
- &udc_regs_p->udc_endp_reg[ep_num]);
-
} else if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
/* Setup the IN endpoint */
writel(0x0, &in_p->endp_status);
/* Turn on the USB connection by enabling the pullup resistor */
void udc_connect(void)
{
- u32 plug_st;
+ u32 plug_st, dev_cntl;
+
+ dev_cntl = readl(&udc_regs_p->dev_cntl);
+ dev_cntl |= DEV_CNTL_SOFTDISCONNECT;
+ writel(dev_cntl, &udc_regs_p->dev_cntl);
+
+ udelay(1000);
+
+ dev_cntl = readl(&udc_regs_p->dev_cntl);
+ dev_cntl &= ~DEV_CNTL_SOFTDISCONNECT;
+ writel(dev_cntl, &udc_regs_p->dev_cntl);
plug_st = readl(&plug_regs_p->plug_state);
plug_st &= ~(PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
{
u32 plug_st;
+ writel(DEV_CNTL_SOFTDISCONNECT, &udc_regs_p->dev_cntl);
+
plug_st = readl(&plug_regs_p->plug_state);
plug_st |= (PLUG_STATUS_PHY_RESET | PLUG_STATUS_PHY_MODE);
writel(plug_st, &plug_regs_p->plug_state);
* DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
* DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
* and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
- * The SPEAr USB client controller has the capability to detect when the
+ * The DW USB client controller has the capability to detect when the
* USB cable is connected to a powered USB bus, so we will defer the
* DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later.
*/
/*
* Plug detection interrupt handling
*/
-void spear_udc_plug_irq(void)
+static void dw_udc_plug_irq(void)
{
if (readl(&plug_regs_p->plug_state) & PLUG_STATUS_ATTACHED) {
/*
UDCDBG("device attached and powered");
udc_state_transition(udc_device->device_state, STATE_POWERED);
} else {
- /*
- * USB cable detached
- * Reset the PHY and switch the mode.
- */
- udc_disconnect();
writel(~0x0, &udc_regs_p->dev_int_mask);
UDCDBG("device detached or unpowered");
/*
* Device interrupt handling
*/
-void spear_udc_dev_irq(void)
+static void dw_udc_dev_irq(void)
{
if (readl(&udc_regs_p->dev_int) & DEV_INT_USBRESET) {
writel(~0x0, &udc_regs_p->endp_int_mask);
- udc_connect();
-
writel(readl(&inep_regs_p[0].endp_cntl) | ENDP_CNTL_FLUSH,
&inep_regs_p[0].endp_cntl);
writel(DEV_INT_USBRESET, &udc_regs_p->dev_int);
+ /*
+ * This endpoint0 specific register can be programmed only
+ * after the phy clock is initialized
+ */
+ writel((EP0_MAX_PACKET_SIZE << 19) | ENDP_EPTYPE_CNTL,
+ &udc_regs_p->udc_endp_reg[0]);
+
UDCDBG("device reset in progess");
udc_state_transition(udc_device->device_state, STATE_DEFAULT);
}
/*
* Endpoint interrupt handling
*/
-void spear_udc_endpoint_irq(void)
+static void dw_udc_endpoint_irq(void)
{
while (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLOUT) {
if ((readl(&outep_regs_p[0].endp_status) & ENDP_STATUS_OUTMSK)
== ENDP_STATUS_OUT_SETUP) {
- spear_udc_setup(udc_device->bus->endpoint_array + 0);
+ dw_udc_setup(udc_device->bus->endpoint_array + 0);
writel(ENDP_STATUS_OUT_SETUP,
&outep_regs_p[0].endp_status);
} else if ((readl(&outep_regs_p[0].endp_status) &
ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
- spear_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
+ dw_udc_ep0_rx(udc_device->bus->endpoint_array + 0);
writel(ENDP_STATUS_OUT_DATA,
&outep_regs_p[0].endp_status);
}
if (readl(&udc_regs_p->endp_int) & ENDP0_INT_CTRLIN) {
- spear_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
+ dw_udc_ep0_tx(udc_device->bus->endpoint_array + 0);
writel(ENDP_STATUS_IN, &inep_regs_p[0].endp_status);
writel(ENDP0_INT_CTRLIN, &udc_regs_p->endp_int);
}
- while (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
+ if (readl(&udc_regs_p->endp_int) & ENDP_INT_NONISOOUT_MSK) {
u32 epnum = 0;
u32 ep_int = readl(&udc_regs_p->endp_int) &
ENDP_INT_NONISOOUT_MSK;
if ((readl(&outep_regs_p[epnum].endp_status) &
ENDP_STATUS_OUTMSK) == ENDP_STATUS_OUT_DATA) {
- spear_udc_epn_rx(epnum);
+ dw_udc_epn_rx(epnum);
writel(ENDP_STATUS_OUT_DATA,
&outep_regs_p[epnum].endp_status);
} else if ((readl(&outep_regs_p[epnum].endp_status) &
if (readl(&inep_regs_p[epnum].endp_status) & ENDP_STATUS_IN) {
writel(ENDP_STATUS_IN,
&outep_regs_p[epnum].endp_status);
- spear_udc_epn_tx(epnum);
+ dw_udc_epn_tx(epnum);
writel(ENDP_STATUS_IN,
&outep_regs_p[epnum].endp_status);
* host requests.
*/
while (readl(&plug_regs_p->plug_pending))
- spear_udc_plug_irq();
+ dw_udc_plug_irq();
while (readl(&udc_regs_p->dev_int))
- spear_udc_dev_irq();
+ dw_udc_dev_irq();
if (readl(&udc_regs_p->endp_int))
- spear_udc_endpoint_irq();
+ dw_udc_endpoint_irq();
}
/* Flow control */
}
break;
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
+#if defined(CONFIG_USBD_HS)
{
- /* If a USB device supports both a full speed and low speed operation
- * we must send a Device_Qualifier descriptor here
- */
- return -1;
+ struct usb_qualifier_descriptor *qualifier_descriptor =
+ device->qualifier_descriptor;
+
+ if (!qualifier_descriptor)
+ return -1;
+
+ /* copy descriptor for this device */
+ copy_config(urb, qualifier_descriptor,
+ sizeof(struct usb_qualifier_descriptor),
+ max);
+
}
+ dbg_ep0(3, "copied qualifier descriptor, actual_length: 0x%x",
+ urb->actual_length);
+#else
+ return -1;
+#endif
+ break;
+
default:
return -1;
}
/* cope with automagic for some standard requests. */
dev->req_std = (usb_ctrl->bRequestType & USB_TYPE_MASK)
== USB_TYPE_STANDARD;
- dev->req_config = 0;
+
dev->req_pending = 1;
/* Handle some SETUP packets ourselves */
DEBUG_SETUP("%s: USB_REQ_SET_CONFIGURATION (%d)\n",
__func__, usb_ctrl->wValue);
- if (usb_ctrl->bRequestType == USB_RECIP_DEVICE) {
+ if (usb_ctrl->bRequestType == USB_RECIP_DEVICE)
reset_available = 1;
- dev->req_config = 1;
- }
+
break;
case USB_REQ_GET_DESCRIPTOR:
DEBUG_SETUP("%s: *** USB_REQ_SET_INTERFACE (%d)\n",
__func__, usb_ctrl->wValue);
- if (usb_ctrl->bRequestType == USB_RECIP_INTERFACE) {
+ if (usb_ctrl->bRequestType == USB_RECIP_INTERFACE)
reset_available = 1;
- dev->req_config = 1;
- }
+
break;
case USB_REQ_GET_CONFIGURATION:
spin_lock(&dev->lock);
if (i < 0) {
- if (dev->req_config) {
- DEBUG_SETUP("\tconfig change 0x%02x fail %d?\n",
- (u32)usb_ctrl->bRequest, i);
- return;
- }
-
/* setup processing failed, force stall */
s3c_udc_ep0_set_stall(ep);
dev->ep0state = WAIT_FOR_SETUP;
# echi
COBJS-$(CONFIG_USB_EHCI) += ehci-hcd.o
+COBJS-$(CONFIG_USB_EHCI_ARMADA100) += ehci-armada100.o utmi-armada100.o
ifdef CONFIG_MPC512X
COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o
else
COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o
COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o
COBJS-$(CONFIG_USB_EHCI_MX5) += ehci-mx5.o
+COBJS-$(CONFIG_USB_EHCI_MX6) += ehci-mx6.o
COBJS-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o
COBJS-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o
COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o
COBJS-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o
COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
+COBJS-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
COBJS := $(COBJS-y)
--- /dev/null
+/*
+ * (C) Copyright 2012
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * This driver is based on Kirkwood echi driver
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include "ehci.h"
+#include "ehci-core.h"
+#include <asm/arch/cpu.h>
+#include <asm/arch/armada100.h>
+#include <asm/arch/utmi-armada100.h>
+
+/*
+ * EHCI host controller init
+ */
+int ehci_hcd_init(void)
+{
+ if (utmi_init() < 0)
+ return -1;
+
+ hccr = (struct ehci_hccr *)(ARMD1_USB_HOST_BASE + 0x100);
+ hcor = (struct ehci_hcor *)((uint32_t) hccr
+ + HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ debug("armada100-ehci: init hccr %x and hcor %x hc_length %d\n",
+ (uint32_t)hccr, (uint32_t)hcor,
+ (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ return 0;
+}
+
+/*
+ * EHCI host controller stop
+ */
+int ehci_hcd_stop(void)
+{
+ return 0;
+}
#include <asm/io.h>
#include <malloc.h>
#include <watchdog.h>
-#ifdef CONFIG_USB_KEYBOARD
-#include <stdio_dev.h>
-extern unsigned char new[];
-#endif
#include "ehci.h"
#endif
ehci_writel(reg_ptr, tmp);
}
+
+#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
+ cmd = ehci_readl(&hcor->or_txfilltuning);
+ cmd &= ~TXFIFO_THRESH(0x3f);
+ cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
+ ehci_writel(&hcor->or_txfilltuning, cmd);
+#endif
out:
return ret;
}
goto unknown;
}
- wait_ms(1);
+ mdelay(1);
len = min3(srclen, le16_to_cpu(req->length), length);
if (srcptr != NULL && len > 0)
memcpy(buffer, srcptr, len);
ehci_writel(&hcor->or_configflag, cmd);
/* unblock posted write */
cmd = ehci_readl(&hcor->or_usbcmd);
- wait_ms(5);
+ mdelay(5);
reg = HC_VERSION(ehci_readl(&hccr->cr_capbase));
printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
return ehci_submit_async(dev, pipe, buffer, length, NULL);
}
-#ifdef CONFIG_SYS_USB_EVENT_POLL
-/*
- * This function polls for USB keyboard data.
- */
-void usb_event_poll()
-{
- struct stdio_dev *dev;
- struct usb_device *usb_kbd_dev;
- struct usb_interface *iface;
- struct usb_endpoint_descriptor *ep;
- int pipe;
- int maxp;
-
- /* Get the pointer to USB Keyboard device pointer */
- dev = stdio_get_by_name("usbkbd");
- usb_kbd_dev = (struct usb_device *)dev->priv;
- iface = &usb_kbd_dev->config.if_desc[0];
- ep = &iface->ep_desc[0];
- pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress);
-
- /* Submit a interrupt transfer request */
- maxp = usb_maxpacket(usb_kbd_dev, pipe);
- usb_submit_int_msg(usb_kbd_dev, pipe, &new[0],
- maxp > 8 ? 8 : maxp, ep->bInterval);
-}
-#endif /* CONFIG_SYS_USB_EVENT_POLL */
--- /dev/null
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <errno.h>
+#include <linux/compiler.h>
+#include <usb/ehci-fsl.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mx6x_pins.h>
+#include <asm/arch/iomux-v3.h>
+
+#include "ehci.h"
+#include "ehci-core.h"
+
+#define USB_OTGREGS_OFFSET 0x000
+#define USB_H1REGS_OFFSET 0x200
+#define USB_H2REGS_OFFSET 0x400
+#define USB_H3REGS_OFFSET 0x600
+#define USB_OTHERREGS_OFFSET 0x800
+
+#define USB_H1_CTRL_OFFSET 0x04
+
+#define USBPHY_CTRL 0x00000030
+#define USBPHY_CTRL_SET 0x00000034
+#define USBPHY_CTRL_CLR 0x00000038
+#define USBPHY_CTRL_TOG 0x0000003c
+
+#define USBPHY_PWD 0x00000000
+#define USBPHY_CTRL_SFTRST 0x80000000
+#define USBPHY_CTRL_CLKGATE 0x40000000
+#define USBPHY_CTRL_ENUTMILEVEL3 0x00008000
+#define USBPHY_CTRL_ENUTMILEVEL2 0x00004000
+
+#define ANADIG_USB2_CHRG_DETECT_EN_B 0x00100000
+#define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B 0x00080000
+
+#define ANADIG_USB2_PLL_480_CTRL_BYPASS 0x00010000
+#define ANADIG_USB2_PLL_480_CTRL_ENABLE 0x00002000
+#define ANADIG_USB2_PLL_480_CTRL_POWER 0x00001000
+#define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040
+
+
+#define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
+#define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
+
+/* USBCMD */
+#define UH1_USBCMD_OFFSET 0x140
+#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
+#define UCMD_RESET (1 << 1) /* controller reset */
+
+static void usbh1_internal_phy_clock_gate(int on)
+{
+ void __iomem *phy_reg = (void __iomem *)USB_PHY1_BASE_ADDR;
+
+ phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET;
+ __raw_writel(USBPHY_CTRL_CLKGATE, phy_reg);
+}
+
+static void usbh1_power_config(void)
+{
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ /*
+ * Some phy and power's special controls for host1
+ * 1. The external charger detector needs to be disabled
+ * or the signal at DP will be poor
+ * 2. The PLL's power and output to usb for host 1
+ * is totally controlled by IC, so the Software only needs
+ * to enable them at initializtion.
+ */
+ __raw_writel(ANADIG_USB2_CHRG_DETECT_EN_B |
+ ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
+ &anatop->usb2_chrg_detect);
+
+ __raw_writel(ANADIG_USB2_PLL_480_CTRL_BYPASS,
+ &anatop->usb2_pll_480_ctrl);
+
+ __raw_writel(ANADIG_USB2_PLL_480_CTRL_ENABLE |
+ ANADIG_USB2_PLL_480_CTRL_POWER |
+ ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+ &anatop->usb2_pll_480_ctrl_set);
+}
+
+static int usbh1_phy_enable(void)
+{
+ void __iomem *phy_reg = (void __iomem *)USB_PHY1_BASE_ADDR;
+ void __iomem *phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
+ void __iomem *usb_cmd = (void __iomem *)(USBOH3_USB_BASE_ADDR +
+ USB_H1REGS_OFFSET +
+ UH1_USBCMD_OFFSET);
+ u32 val;
+
+ /* Stop then Reset */
+ val = __raw_readl(usb_cmd);
+ val &= ~UCMD_RUN_STOP;
+ __raw_writel(val, usb_cmd);
+ while (__raw_readl(usb_cmd) & UCMD_RUN_STOP)
+ ;
+
+ val = __raw_readl(usb_cmd);
+ val |= UCMD_RESET;
+ __raw_writel(val, usb_cmd);
+ while (__raw_readl(usb_cmd) & UCMD_RESET)
+ ;
+
+ /* Reset USBPHY module */
+ val = __raw_readl(phy_ctrl);
+ val |= USBPHY_CTRL_SFTRST;
+ __raw_writel(val, phy_ctrl);
+ udelay(10);
+
+ /* Remove CLKGATE and SFTRST */
+ val = __raw_readl(phy_ctrl);
+ val &= ~(USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST);
+ __raw_writel(val, phy_ctrl);
+ udelay(10);
+
+ /* Power up the PHY */
+ __raw_writel(0, phy_reg + USBPHY_PWD);
+ /* enable FS/LS device */
+ val = __raw_readl(phy_reg + USBPHY_CTRL);
+ val |= (USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3);
+ __raw_writel(val, phy_reg + USBPHY_CTRL);
+
+ return 0;
+}
+
+static void usbh1_oc_config(void)
+{
+ void __iomem *usb_base = (void __iomem *)USBOH3_USB_BASE_ADDR;
+ void __iomem *usbother_base = usb_base + USB_OTHERREGS_OFFSET;
+ u32 val;
+
+ val = __raw_readl(usbother_base + USB_H1_CTRL_OFFSET);
+#if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2
+ /* mx6qarm2 seems to required a different setting*/
+ val &= ~UCTRL_OVER_CUR_POL;
+#else
+ val |= UCTRL_OVER_CUR_POL;
+#endif
+ __raw_writel(val, usbother_base + USB_H1_CTRL_OFFSET);
+
+ val = __raw_readl(usbother_base + USB_H1_CTRL_OFFSET);
+ val |= UCTRL_OVER_CUR_DIS;
+ __raw_writel(val, usbother_base + USB_H1_CTRL_OFFSET);
+}
+
+int ehci_hcd_init(void)
+{
+ struct usb_ehci *ehci;
+
+ enable_usboh3_clk(1);
+ mdelay(1);
+
+ /* Do board specific initialization */
+ board_ehci_hcd_init(CONFIG_MXC_USB_PORT);
+
+#if CONFIG_MXC_USB_PORT == 1
+ /* USB Host 1 */
+ usbh1_power_config();
+ usbh1_oc_config();
+ usbh1_internal_phy_clock_gate(1);
+ usbh1_phy_enable();
+#else
+#error "MXC USB port not yet supported"
+#endif
+
+ ehci = (struct usb_ehci *)(USBOH3_USB_BASE_ADDR +
+ (0x200 * CONFIG_MXC_USB_PORT));
+ hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+ hcor = (struct ehci_hcor *)((uint32_t)hccr +
+ HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+ setbits_le32(&ehci->usbmode, CM_HOST);
+
+ __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
+ setbits_le32(&ehci->portsc, USB_EN);
+
+ mdelay(10);
+
+ return 0;
+}
+
+int ehci_hcd_stop(void)
+{
+ return 0;
+}
int ret;
uint32_t usb_base, cap_base;
- struct mx28_register *digctl_ctrl =
- (struct mx28_register *)HW_DIGCTL_CTRL;
+ struct mx28_register_32 *digctl_ctrl =
+ (struct mx28_register_32 *)HW_DIGCTL_CTRL;
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
{
int ret;
uint32_t tmp;
- struct mx28_register *digctl_ctrl =
- (struct mx28_register *)HW_DIGCTL_CTRL;
+ struct mx28_register_32 *digctl_ctrl =
+ (struct mx28_register_32 *)HW_DIGCTL_CTRL;
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
--- /dev/null
+/*
+ * Copyright (c) 2009 NVIDIA Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <usb.h>
+
+#include "ehci.h"
+#include "ehci-core.h"
+
+#include <asm/errno.h>
+#include <asm/arch/usb.h>
+
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(void)
+{
+ u32 our_hccr, our_hcor;
+
+ /*
+ * Select the first port, as we don't have a way of selecting others
+ * yet
+ */
+ if (tegrausb_start_port(0, &our_hccr, &our_hcor))
+ return -1;
+
+ hccr = (struct ehci_hccr *)our_hccr;
+ hcor = (struct ehci_hcor *)our_hcor;
+
+ return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(void)
+{
+ tegrausb_stop_port();
+ return 0;
+}
uint32_t or_ctrldssegment;
uint32_t or_periodiclistbase;
uint32_t or_asynclistaddr;
- uint32_t _reserved_[9];
+ uint32_t _reserved_0_;
+ uint32_t or_burstsize;
+ uint32_t or_txfilltuning;
+#define TXFIFO_THRESH(p) ((p & 0x3f) << 16)
+ uint32_t _reserved_1_[6];
uint32_t or_configflag;
#define FLAG_CF (1 << 0) /* true: we'll support "high speed" */
uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS];
/* When root hub or any of its ports is going
to come out of suspend, it may take more
than 10ms for status bits to stabilize. */
- wait_ms(20);
+ mdelay(20);
}
if (intstat & HCINT_SO) {
/* Pack data into FIFO ram */
pack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
#ifdef EXTRA_DELAY
- wait_ms(EXTRA_DELAY);
+ mdelay(EXTRA_DELAY);
#endif
/* Start the data transfer */
HCRHPORT1 + wIndex - 1);
if (!(tmp & RH_PS_PRS))
break;
- wait_ms(1);
+ mdelay(1);
}
isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
RH_PS_PRS);
- wait_ms(10);
+ mdelay(10);
len = 0;
break;
isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
while (--retries) {
/* It usually resets within 1 ms */
- wait_ms(1);
+ mdelay(1);
if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
break;
}
clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
if (clkrdy)
break;
- wait_ms(1);
+ mdelay(1);
}
if (!clkrdy) {
ERR("clock not ready after %dms", timeout);
pkt_print(NULL, dev, pipe, buffer, transfer_len,
cmd, "SUB(rh)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (usb_pipeint(pipe)) {
info("Root-Hub submit IRQ: NOT implemented");
OK(0);
case (RH_PORT_POWER):
WR_RH_PORTSTAT(RH_PS_PPS);
- wait_ms(100);
+ mdelay(100);
OK(0);
case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
if (RD_RH_PORTSTAT & RH_PS_CCS)
#ifdef DEBUG
ohci_dump_roothub(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
len = min_t(int, len, leni);
pkt_print(NULL, dev, pipe, buffer,
transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
#else
- wait_ms(1);
+ mdelay(1);
#endif
return stat;
pkt_print(urb, dev, pipe, buffer, transfer_len,
setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_common_message: pipesize for pipe %lx is zero",
}
#if 0
- wait_ms(10);
+ mdelay(10);
/* ohci_dump_status(&gohci); */
#endif
}
if (--timeout) {
- wait_ms(1);
+ mdelay(1);
if (!urb->finished)
dbg("*");
pkt_print(urb, dev, pipe, buffer, transfer_len,
setup, "RET(ctlr)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* free TDs in urb_priv */
pkt_print(NULL, dev, pipe, buffer, transfer_len,
setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_control_message: pipesize for pipe %lx is zero",
ohci_writel(OHCI_OCR, &ohci->regs->cmdstatus);
info("USB HC TakeOver from SMM");
while (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms(10);
+ mdelay(10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
/*-------------------------------------------------------------------------*/
-/* Poll USB interrupt. */
-void usb_event_poll(void)
-{
- hc_interrupt();
-}
-
/* an interrupt happens */
static int hc_interrupt(void)
#ifdef DEBUG
ohci_dump(ohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* FIXME: be optimistic, hope that bug won't repeat often. */
/* Make some non-interrupt context restart the controller. */
}
if (ints & OHCI_INTR_WDH) {
- wait_ms(1);
+ mdelay(1);
ohci_writel(OHCI_INTR_WDH, ®s->intrdisable);
(void)ohci_readl(®s->intrdisable); /* flush */
stat = dl_done_list(&gohci);
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
ohci_writel(OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
ohci_writel(OHCI_INTR_SF, ®s->intrenable);
#ifdef DEBUG
ohci_dump(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
ohci_inited = 1;
return 0;
old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port) & LNST);
while (count > 0) {
- wait_ms(R8A66597_RH_POLL_TIME);
+ mdelay(R8A66597_RH_POLL_TIME);
syssts = r8a66597_read(r8a66597, get_syssts_reg(port) & LNST);
if (syssts == old_syssts) {
static void r8a66597_bus_reset(struct r8a66597 *r8a66597, int port)
{
- wait_ms(10);
+ mdelay(10);
r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, get_dvstctr_reg(port));
- wait_ms(50);
+ mdelay(50);
r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, get_dvstctr_reg(port));
- wait_ms(50);
+ mdelay(50);
}
static int check_usb_device_connecting(struct r8a66597 *r8a66597)
stat = USB_ST_STALLED;
}
- wait_ms(1);
+ mdelay(1);
len = min_t(int, len, leni);
return 0;
}
-void usb_event_poll(void)
-{
- /* no implement */
- R8A66597_DPRINT("%s\n", __func__);
-}
-
int usb_lowlevel_init(void)
{
struct r8a66597 *r8a66597 = &gr8a66597;
r8a66597->reg = CONFIG_R8A66597_BASE_ADDR;
disable_controller(r8a66597);
- wait_ms(100);
+ mdelay(100);
enable_controller(r8a66597);
r8a66597_port_power(r8a66597, 0 , 1);
/* check usb device */
check_usb_device_connecting(r8a66597);
- wait_ms(50);
+ mdelay(50);
return 0;
}
--- /dev/null
+/*
+ * (C) Copyright 2012
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/armada100.h>
+#include <asm/arch/utmi-armada100.h>
+
+static int utmi_phy_init(void)
+{
+ struct armd1usb_phy_reg *phy_regs =
+ (struct armd1usb_phy_reg *)UTMI_PHY_BASE;
+ int timeout;
+
+ setbits_le32(&phy_regs->utmi_ctrl, INPKT_DELAY_SOF | PLL_PWR_UP);
+ udelay(1000);
+ setbits_le32(&phy_regs->utmi_ctrl, PHY_PWR_UP);
+
+ clrbits_le32(&phy_regs->utmi_pll, PLL_FBDIV_MASK | PLL_REFDIV_MASK);
+ setbits_le32(&phy_regs->utmi_pll, N_DIVIDER << PLL_FBDIV | M_DIVIDER);
+
+ setbits_le32(&phy_regs->utmi_tx, PHSEL_VAL << CK60_PHSEL);
+
+ /* Calibrate pll */
+ timeout = 10000;
+ while (--timeout && ((readl(&phy_regs->utmi_pll) & PLL_READY) == 0))
+ ;
+ if (!timeout)
+ return -1;
+
+ udelay(200);
+ setbits_le32(&phy_regs->utmi_pll, VCOCAL_START);
+ udelay(400);
+ clrbits_le32(&phy_regs->utmi_pll, VCOCAL_START);
+
+ udelay(200);
+ setbits_le32(&phy_regs->utmi_tx, RCAL_START);
+ udelay(400);
+ clrbits_le32(&phy_regs->utmi_tx, RCAL_START);
+
+ timeout = 10000;
+ while (--timeout && ((readl(&phy_regs->utmi_pll) & PLL_READY) == 0))
+ ;
+ if (!timeout)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Initialize USB host controller's UTMI Physical interface
+ */
+int utmi_init(void)
+{
+ struct armd1mpmu_registers *mpmu_regs =
+ (struct armd1mpmu_registers *)ARMD1_MPMU_BASE;
+
+ struct armd1apmu_registers *apmu_regs =
+ (struct armd1apmu_registers *)ARMD1_APMU_BASE;
+
+ /* Turn on 26Mhz ref clock for UTMI PLL */
+ setbits_le32(&mpmu_regs->acgr, APB2_26M_EN | AP_26M);
+
+ /* USB Clock reset */
+ writel(USB_SPH_AXICLK_EN, &apmu_regs->usbcrc);
+ writel(USB_SPH_AXICLK_EN | USB_SPH_AXI_RST, &apmu_regs->usbcrc);
+
+ /* Initialize UTMI transceiver */
+ return utmi_phy_init();
+}
dev->act_len = len;
dev->status = stat;
- debug("dev act_len %d, status %d\n", dev->act_len, dev->status);
+ debug("dev act_len %d, status %lu\n", dev->act_len, dev->status);
return stat;
}
dev->act_len = len;
return 0;
}
-
-
-#ifdef CONFIG_SYS_USB_EVENT_POLL
-/*
- * This function polls for USB keyboard data.
- */
-void usb_event_poll()
-{
- struct stdio_dev *dev;
- struct usb_device *usb_kbd_dev;
- struct usb_interface *iface;
- struct usb_endpoint_descriptor *ep;
- int pipe;
- int maxp;
-
- /* Get the pointer to USB Keyboard device pointer */
- dev = stdio_get_by_name("usbkbd");
- usb_kbd_dev = (struct usb_device *)dev->priv;
- iface = &usb_kbd_dev->config.if_desc[0];
- ep = &iface->ep_desc[0];
- pipe = usb_rcvintpipe(usb_kbd_dev, ep->bEndpointAddress);
-
- /* Submit a interrupt transfer request */
- maxp = usb_maxpacket(usb_kbd_dev, pipe);
- usb_submit_int_msg(usb_kbd_dev, pipe, &new[0],
- maxp > 8 ? 8 : maxp, ep->bInterval);
-}
-#endif /* CONFIG_SYS_USB_EVENT_POLL */
$(ELF):
$(obj)%: $(obj)%.o $(LIB)
- $(LD) -g -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) \
+ $(LD) $(LDFLAGS) -g -Ttext $(CONFIG_STANDALONE_LOAD_ADDR) \
-o $@ -e $(SYM_PREFIX)$(notdir $(<:.o=)) $< $(LIB) \
-L$(gcclibdir) -lgcc
}
static int total_sector;
-static int disk_write(__u32 startblock, __u32 getsize, __u8 *bufptr)
+static int disk_write(__u32 block, __u32 nr_blocks, void *buf)
{
- if (cur_dev == NULL)
+ if (!cur_dev || !cur_dev->block_write)
return -1;
- if (startblock + getsize > total_sector) {
+ if (cur_part_info.start + block + nr_blocks >
+ cur_part_info.start + total_sector) {
printf("error: overflow occurs\n");
return -1;
}
- startblock += part_offset;
-
- if (cur_dev->block_read) {
- return cur_dev->block_write(cur_dev->dev, startblock, getsize,
- (unsigned long *) bufptr);
- }
- return -1;
+ return cur_dev->block_write(cur_dev->dev,
+ cur_part_info.start + block, nr_blocks, buf);
}
/*
if (size % mydata->sect_size)
sect_num++;
- if (startsect + sect_num > total_sector)
+ if (startsect + sect_num > cur_part_info.start + total_sector)
return -1;
return 0;
static dir_entry *find_directory_entry(fsdata *mydata, int startsect,
char *filename, dir_entry *retdent, __u32 start)
{
- __u16 prevcksum = 0xffff;
__u32 curclust = (startsect - mydata->data_begin) / mydata->clust_size;
debug("get_dentfromdir: %s\n", filename);
#ifdef CONFIG_SUPPORT_VFAT
if ((dentptr->attr & ATTR_VFAT) &&
(dentptr->name[0] & LAST_LONG_ENTRY_MASK)) {
- prevcksum =
- ((dir_slot *)dentptr)->alias_checksum;
get_long_file_name(mydata, curclust,
get_dentfromdir_block,
&dentptr, l_name);
unsigned long size)
{
dir_entry *dentptr, *retdent;
- dir_slot *slotptr;
__u32 startsect;
__u32 start_cluster;
boot_sector bs;
fsdata datablock;
fsdata *mydata = &datablock;
int cursect;
- int root_cluster, ret = -1, name_len;
+ int ret = -1, name_len;
char l_filename[VFAT_MAXLEN_BYTES];
int write_size = size;
total_sector = bs.total_sect;
if (total_sector == 0)
- total_sector = part_size;
-
- root_cluster = bs.root_cluster;
+ total_sector = cur_part_info.size;
if (mydata->fatsize == 32)
mydata->fatlength = bs.fat32_length;
goto exit;
}
} else {
- slotptr = (dir_slot *)empty_dentptr;
-
/* Set short name to set alias checksum field in dir_slot */
set_name(empty_dentptr, filename);
fill_dir_slot(mydata, &empty_dentptr, filename);
/*
* Device / Head Register Bits
*/
+#ifndef ATA_DEVICE
#define ATA_DEVICE(x) ((x & 1)<<4)
+#endif /* ATA_DEVICE */
#define ATA_LBA 0xE0
/*
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-#ifndef __CPU_AT32AP_ATMEL_MCI_H__
-#define __CPU_AT32AP_ATMEL_MCI_H__
+#ifndef __ATMEL_MCI_H__
+#define __ATMEL_MCI_H__
+
+int atmel_mci_init(void *regs);
#ifndef __ASSEMBLY__
#endif /* __ASSEMBLY__ */
-/*
- * NOTICE: Use of registers offsets is depreciated.
- * These defines will be removed once the old driver
- * is taken out of commision.
- *
- * Atmel MultiMedia Card Interface (MCI) registers
- */
-#define MMCI_CR 0x0000
-#define MMCI_MR 0x0004
-#define MMCI_DTOR 0x0008
-#define MMCI_SDCR 0x000c
-#define MMCI_ARGR 0x0010
-#define MMCI_CMDR 0x0014
-#define MMCI_RSPR 0x0020
-#define MMCI_RSPR1 0x0024
-#define MMCI_RSPR2 0x0028
-#define MMCI_RSPR3 0x002c
-#define MMCI_RDR 0x0030
-#define MMCI_TDR 0x0034
-#define MMCI_SR 0x0040
-#define MMCI_IER 0x0044
-#define MMCI_IDR 0x0048
-#define MMCI_IMR 0x004c
-
/* Bitfields in CR */
#define MMCI_MCIEN_OFFSET 0
#define MMCI_MCIEN_SIZE 1
<< MMCI_##name##_OFFSET)) \
| MMCI_BF(name,value))
-/*
- * NOTICE: Use of registers offsets is depreciated.
- * These defines will be removed once the old driver
- * is taken out of commision.
- *
- * Register access macros
- */
-#define mmci_readl(reg) \
- readl((void *)ATMEL_BASE_MMCI + MMCI_##reg)
-#define mmci_writel(reg,value) \
- writel((value), (void *)ATMEL_BASE_MMCI + MMCI_##reg)
-
-#endif /* __CPU_AT32AP_ATMEL_MCI_H__ */
+#endif /* __ATMEL_MCI_H__ */
--- /dev/null
+/*
+ * This file implements recording of each stage of the boot process. It is
+ * intended to implement timing of each stage, reporting this information
+ * to the user and passing it to the OS for logging / further analysis.
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+#ifndef _BOOTSTAGE_H
+#define _BOOTSTAGE_H
+
+/* The number of boot stage records available for the user */
+#ifndef CONFIG_BOOTSTAGE_USER_COUNT
+#define CONFIG_BOOTSTAGE_USER_COUNT 20
+#endif
+
+/*
+ * A list of boot stages that we know about. Each of these indicates the
+ * state that we are at, and the action that we are about to perform. For
+ * errors, we issue an error for an item when it fails. Therefore the
+ * normal sequence is:
+ *
+ * progress action1
+ * progress action2
+ * progress action3
+ *
+ * and an error condition where action 3 failed would be:
+ *
+ * progress action1
+ * progress action2
+ * progress action3
+ * error on action3
+ */
+enum bootstage_id {
+ BOOTSTAGE_ID_START = 0,
+ BOOTSTAGE_ID_CHECK_MAGIC, /* Checking image magic */
+ BOOTSTAGE_ID_CHECK_HEADER, /* Checking image header */
+ BOOTSTAGE_ID_CHECK_CHECKSUM, /* Checking image checksum */
+ BOOTSTAGE_ID_CHECK_ARCH, /* Checking architecture */
+
+ BOOTSTAGE_ID_CHECK_IMAGETYPE = 5,/* Checking image type */
+ BOOTSTAGE_ID_DECOMP_IMAGE, /* Decompressing image */
+ BOOTSTAGE_ID_KERNEL_LOADED, /* Kernel has been loaded */
+ BOOTSTAGE_ID_DECOMP_UNIMPL = 7, /* Odd decompression algorithm */
+ BOOTSTAGE_ID_CHECK_BOOT_OS, /* Calling OS-specific boot function */
+ BOOTSTAGE_ID_BOOT_OS_RETURNED, /* Tried to boot OS, but it returned */
+ BOOTSTAGE_ID_CHECK_RAMDISK = 9, /* Checking ram disk */
+
+ BOOTSTAGE_ID_RD_MAGIC, /* Checking ram disk magic */
+ BOOTSTAGE_ID_RD_HDR_CHECKSUM, /* Checking ram disk heder checksum */
+ BOOTSTAGE_ID_RD_CHECKSUM, /* Checking ram disk checksum */
+ BOOTSTAGE_ID_COPY_RAMDISK = 12, /* Copying ram disk into place */
+ BOOTSTAGE_ID_RAMDISK, /* Checking for valid ramdisk */
+ BOOTSTAGE_ID_NO_RAMDISK, /* No ram disk found (not an error) */
+
+ BOOTSTAGE_ID_RUN_OS = 15, /* Exiting U-Boot, entering OS */
+
+ BOOTSTAGE_ID_NEED_RESET = 30,
+ BOOTSTAGE_ID_POST_FAIL, /* Post failure */
+ BOOTSTAGE_ID_POST_FAIL_R, /* Post failure reported after reloc */
+
+ /*
+ * This set is reported ony by x86, and the meaning is different. In
+ * this case we are reporting completion of a particular stage.
+ * This should probably change in he x86 code (which doesn't report
+ * errors in any case), but discussion this can perhaps wait until we
+ * have a generic board implementation.
+ */
+ BOOTSTAGE_ID_BOARD_INIT_R, /* We have relocated */
+ BOOTSTAGE_ID_BOARD_GLOBAL_DATA, /* Global data is set up */
+
+ BOOTSTAGE_ID_BOARD_INIT_SEQ, /* We completed the init sequence */
+ BOOTSTAGE_ID_BOARD_FLASH, /* We have configured flash banks */
+ BOOTSTAGE_ID_BOARD_FLASH_37, /* In case you didn't hear... */
+ BOOTSTAGE_ID_BOARD_ENV, /* Environment is relocated & ready */
+ BOOTSTAGE_ID_BOARD_PCI, /* PCI is up */
+
+ BOOTSTAGE_ID_BOARD_INTERRUPTS, /* Exceptions / interrupts ready */
+ BOOTSTAGE_ID_BOARD_DONE, /* Board init done, off to main loop */
+ /* ^^^ here ends the x86 sequence */
+
+ /* Boot stages related to loading a kernel from an IDE device */
+ BOOTSTAGE_ID_IDE_START = 41,
+ BOOTSTAGE_ID_IDE_ADDR,
+ BOOTSTAGE_ID_IDE_BOOT_DEVICE,
+ BOOTSTAGE_ID_IDE_TYPE,
+
+ BOOTSTAGE_ID_IDE_PART,
+ BOOTSTAGE_ID_IDE_PART_INFO,
+ BOOTSTAGE_ID_IDE_PART_TYPE,
+ BOOTSTAGE_ID_IDE_PART_READ,
+ BOOTSTAGE_ID_IDE_FORMAT,
+
+ BOOTSTAGE_ID_IDE_CHECKSUM, /* 50 */
+ BOOTSTAGE_ID_IDE_READ,
+
+ /* Boot stages related to loading a kernel from an NAND device */
+ BOOTSTAGE_ID_NAND_PART,
+ BOOTSTAGE_ID_NAND_SUFFIX,
+ BOOTSTAGE_ID_NAND_BOOT_DEVICE,
+ BOOTSTAGE_ID_NAND_HDR_READ = 55,
+ BOOTSTAGE_ID_NAND_AVAILABLE = 55,
+ BOOTSTAGE_ID_NAND_TYPE = 57,
+ BOOTSTAGE_ID_NAND_READ,
+
+ /* Boot stages related to loading a kernel from an network device */
+ BOOTSTAGE_ID_NET_CHECKSUM = 60,
+ BOOTSTAGE_ID_NET_ETH_START = 64,
+ BOOTSTAGE_ID_NET_ETH_INIT,
+
+ BOOTSTAGE_ID_NET_START = 80,
+ BOOTSTAGE_ID_NET_NETLOOP_OK,
+ BOOTSTAGE_ID_NET_LOADED,
+ BOOTSTAGE_ID_NET_DONE_ERR,
+ BOOTSTAGE_ID_NET_DONE,
+
+ /*
+ * Boot stages related to loading a FIT image. Some of these are a
+ * bit wonky.
+ */
+ BOOTSTAGE_ID_FIT_FORMAT = 100,
+ BOOTSTAGE_ID_FIT_NO_UNIT_NAME,
+ BOOTSTAGE_ID_FIT_UNIT_NAME,
+ BOOTSTAGE_ID_FIT_CONFIG,
+ BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE,
+ BOOTSTAGE_ID_FIT_CHECK_HASH = 104,
+
+ BOOTSTAGE_ID_FIT_CHECK_ARCH,
+ BOOTSTAGE_ID_FIT_CHECK_KERNEL,
+ BOOTSTAGE_ID_FIT_CHECKED,
+
+ BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR = 107,
+ BOOTSTAGE_ID_FIT_KERNEL_INFO,
+ BOOTSTAGE_ID_FIT_TYPE,
+
+ BOOTSTAGE_ID_FIT_COMPRESSION,
+ BOOTSTAGE_ID_FIT_OS,
+ BOOTSTAGE_ID_FIT_LOADADDR,
+ BOOTSTAGE_ID_OVERWRITTEN,
+
+ BOOTSTAGE_ID_FIT_RD_FORMAT = 120,
+ BOOTSTAGE_ID_FIT_RD_FORMAT_OK,
+ BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME,
+ BOOTSTAGE_ID_FIT_RD_UNIT_NAME,
+ BOOTSTAGE_ID_FIT_RD_SUBNODE,
+
+ BOOTSTAGE_ID_FIT_RD_CHECK,
+ BOOTSTAGE_ID_FIT_RD_HASH = 125,
+ BOOTSTAGE_ID_FIT_RD_CHECK_ALL,
+ BOOTSTAGE_ID_FIT_RD_GET_DATA,
+ BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK = 127,
+ BOOTSTAGE_ID_FIT_RD_GET_DATA_OK,
+ BOOTSTAGE_ID_FIT_RD_LOAD,
+
+ BOOTSTAGE_ID_IDE_FIT_READ = 140,
+ BOOTSTAGE_ID_IDE_FIT_READ_OK,
+
+ BOOTSTAGE_ID_NAND_FIT_READ = 150,
+ BOOTSTAGE_ID_NAND_FIT_READ_OK,
+
+ /*
+ * These boot stages are new, higher level, and not directly related
+ * to the old boot progress numbers. They are useful for recording
+ * rough boot timing information.
+ */
+ BOOTSTAGE_ID_AWAKE,
+ BOOTSTAGE_ID_START_UBOOT_F,
+ BOOTSTAGE_ID_START_UBOOT_R,
+ BOOTSTAGE_ID_USB_START,
+ BOOTSTAGE_ID_ETH_START,
+ BOOTSTAGE_ID_BOOTP_START,
+ BOOTSTAGE_ID_BOOTP_STOP,
+ BOOTSTAGE_ID_BOOTM_START,
+ BOOTSTAGE_ID_BOOTM_HANDOFF,
+ BOOTSTAGE_ID_MAIN_LOOP,
+ BOOTSTAGE_KERNELREAD_START,
+ BOOTSTAGE_KERNELREAD_STOP,
+
+ BOOTSTAGE_ID_CPU_AWAKE,
+ BOOTSTAGE_ID_MAIN_CPU_AWAKE,
+ BOOTSTAGE_ID_MAIN_CPU_READY,
+
+ /* a few spare for the user, from here */
+ BOOTSTAGE_ID_USER,
+ BOOTSTAGE_ID_COUNT = BOOTSTAGE_ID_USER + CONFIG_BOOTSTAGE_USER_COUNT,
+ BOOTSTAGE_ID_ALLOC,
+};
+
+/*
+ * Board code can implement show_boot_progress() if needed.
+ *
+ * @param val Progress state (enum bootstage_id), or -id if an error
+ * has occurred.
+ */
+void show_boot_progress(int val);
+
+#ifdef CONFIG_BOOTSTAGE
+/* This is the full bootstage implementation */
+
+/*
+ * Mark a time stamp for the current boot stage.
+ */
+ulong bootstage_mark(enum bootstage_id id);
+
+ulong bootstage_error(enum bootstage_id id);
+
+ulong bootstage_mark_name(enum bootstage_id id, const char *name);
+
+/* Print a report about boot time */
+void bootstage_report(void);
+
+#else
+/*
+ * This is a dummy implementation which just calls show_boot_progress(),
+ * and won't even do that unless CONFIG_SHOW_BOOT_PROGRESS is defined
+ */
+
+static inline ulong bootstage_mark(enum bootstage_id id)
+{
+ show_boot_progress(id);
+ return 0;
+}
+
+static inline ulong bootstage_error(enum bootstage_id id)
+{
+ show_boot_progress(-id);
+ return 0;
+}
+
+static inline ulong bootstage_mark_name(enum bootstage_id id, const char *name)
+{
+ return 0;
+}
+
+
+#endif /* CONFIG_BOOTSTAGE */
+
+#endif
-/*
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- * 2004 (c) MontaVista Software, Inc.
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
*
* See file CREDITS for list of people who contributed to this
* project.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
+#ifndef _NAND_SPL_H_
+#define _NAND_SPL_H_
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(_start)
-SECTIONS
-{
- . = 0x00000000;
+#define SPL_EXPORT (0x00000001)
- . = ALIGN(4);
- .text :
- {
- cpu/sa1100/start.o (.text)
- *(.text)
- }
+#define SPL_EXPORT_FDT (0x00000001)
+#define SPL_EXPORT_ATAGS (0x00000002)
+#define SPL_EXPORT_LAST SPL_EXPORT_ATAGS
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : { *(.data) }
-
- . = ALIGN(4);
- .got : { *(.got) }
-
-
- . = .;
- __u_boot_cmd_start = .;
- .u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
-
- . = ALIGN(4);
- __bss_start = .;
- .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
- __bss_end__ = .;
-}
+#endif /* _NAND_SPL_H_ */
#endif
extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+/*
+ * Error codes that commands return to cmd_process(). We use the standard 0
+ * and 1 for success and failure, but add one more case - failure with a
+ * request to call cmd_usage(). But the cmd_process() function handles
+ * CMD_RET_USAGE itself and after calling cmd_usage() it will return 1.
+ * This is just a convenience for commands to avoid them having to call
+ * cmd_usage() all over the place.
+ */
+enum command_ret_t {
+ CMD_RET_SUCCESS, /* 0 = Success */
+ CMD_RET_FAILURE, /* 1 = Failure */
+ CMD_RET_USAGE = -1, /* Failure, please report 'usage' error */
+};
+
+/**
+ * Process a command with arguments. We look up the command and execute it
+ * if valid. Otherwise we print a usage message.
+ *
+ * @param flag Some flags normally 0 (see CMD_FLAG_.. above)
+ * @param argc Number of arguments (arg 0 must be the command text)
+ * @param argv Arguments
+ * @param repeatable This function sets this to 0 if the command is not
+ * repeatable. If the command is repeatable, the value
+ * is left unchanged.
+ * @return 0 if the command succeeded, 1 if it failed
+ */
+int cmd_process(int flag, int argc, char * const argv[],
+ int *repeatable);
+
#endif /* __ASSEMBLY__ */
/*
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
void fixup_cmdtable(cmd_tbl_t *cmdtp, int size);
#endif
+
#endif /* __COMMAND_H */
#endif /* CONFIG_SERIAL_MULTI */
+/*
+ * Return the time since boot in microseconds, This is needed for bootstage
+ * and should be defined in CPU- or board-specific code. If undefined then
+ * millisecond resolution will be used (the standard get_timer()).
+ */
+ulong timer_get_boot_us(void);
+
/*
* General Purpose Utilities
*/
/* common/main.c */
void main_loop (void);
-int run_command (const char *cmd, int flag);
-#ifdef CONFIG_CMD_PXE
-int run_command2(const char *cmd, int flag);
-#endif
+int run_command(const char *cmd, int flag);
int readline (const char *const prompt);
int readline_into_buffer(const char *const prompt, char *buffer,
int timeout);
extern u8 _binary_dt_dtb_start[]; /* embedded device tree blob */
int set_cpu_clk_info(void);
-/*
- * Called when console output is requested before the console is available.
- * The board should do its best to get the character out to the user any way
- * it can.
- */
-void board_pre_console_putc(int ch);
-
/* common/flash.c */
void flash_perror (int);
#ifdef CONFIG_STATUS_LED
# include <status_led.h>
#endif
-/*
- * Board-specific Platform code can reimplement show_boot_progress () if needed
- */
-void show_boot_progress(int val);
+
+#include <bootstage.h>
/* Multicore arch functions */
#ifdef CONFIG_MP
#define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */
#define CONFIG_CMD_BMP /* BMP support */
#define CONFIG_CMD_BOOTD /* bootd */
+#define CONFIG_CMD_BOOTZ /* boot zImage */
#define CONFIG_CMD_BSP /* Board Specific functions */
#define CONFIG_CMD_CACHE /* icache, dcache */
#define CONFIG_CMD_CDP /* Cisco Discovery Protocol */
#define CONFIG_SYS_I2C_MULTI_EEPROMS
#define CONFIG_SYS_I2C_SPEED 80000 /* I2C speed default */
+#define CONFIG_PRAM 0
+
#define CONFIG_SYS_GT_DUAL_CPU /* also for JTAG even with one cpu */
#define CONFIG_SYS_LONGHELP /* undef to save memory */
#define CONFIG_SYS_PROMPT "=> " /* Monitor Command Prompt */
#define CONFIG_SYS_TCLK 133000000
-/*#define CONFIG_SYS_750FX_HID0 0x8000c084*/
-#define CONFIG_SYS_750FX_HID0 0x80008484
-#define CONFIG_SYS_750FX_HID1 0x54800000
-#define CONFIG_SYS_750FX_HID2 0x00000000
-
/*
* Low Level Configuration Settings
* (address mappings, register initial values, etc.)
#define CONFIG_SYS_ATA_DATA_OFFSET 0x0000 /* Offset for data I/O */
#define CONFIG_SYS_ATA_REG_OFFSET 0x0000 /* Offset for normal register accesses */
#define CONFIG_SYS_ATA_ALT_OFFSET 0x0000 /* Offset for alternate registers */
-
+#ifndef __ASSEMBLY__
+int ata_device(int dev);
+#endif
+#define ATA_DEVICE(dev) ata_device(dev)
+#define CONFIG_ATAPI 1
/*----------------------------------------------------------------------
* Initial BAT mappings
* IBAT4 and DBAT4
* FIXME: ingo disable BATs for Linux Kernel
*/
-#undef SETUP_HIGH_BATS_FX750 /* don't initialize BATS 4-7 */
-/*#define SETUP_HIGH_BATS_FX750*/ /* initialize BATS 4-7 */
+/* #undef SETUP_HIGH_BATS_FX750 */ /* don't initialize BATS 4-7 */
+#define SETUP_HIGH_BATS_FX750 /* initialize BATS 4-7 */
#ifdef SETUP_HIGH_BATS_FX750
#define CONFIG_SYS_IBAT4L (CONFIG_SYS_SDRAM1_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
#define CPCI750_ECC_TEST (((in8(0xf0300000) & 0x02) == 0) ? 1 : 0)
#define CONFIG_SYS_PLD_VER 0xf0e00000
+#define CONFIG_OF_LIBFDT 1
+
#endif /* __CONFIG_H */
#define CONFIG_IXP425 1
#define CONFIG_ACTUX1 1
+#define CONFIG_MACH_TYPE 1479
+
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_IXP425 1
#define CONFIG_ACTUX2 1
+#define CONFIG_MACH_TYPE 1480
+
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_IXP425 1
#define CONFIG_ACTUX3 1
+#define CONFIG_MACH_TYPE 1481
+
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_IXP425 1
#define CONFIG_ACTUX4 1
+#define CONFIG_MACH_TYPE 1532
+
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_SPL_LIBDISK_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
/*
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_ATMEL_SPI
#define CONFIG_SPI_FLASH
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
"console=ttyS0 root=/dev/mmcblk0p1 rootwait"
#define CONFIG_BOOTCOMMAND \
- "mmcinit; ext2load mmc 0:1 0x10400000 /boot/uImage; bootm"
+ "mmc rescan; ext2load mmc 0:1 0x10400000 /boot/uImage; bootm"
/*
* Only interrupt autoboot if <space> is pressed. Otherwise, garbage
#define CONFIG_PORTMUX_PIO
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
"console=ttyS0 root=/dev/mmcblk0p1 rootwait"
#define CONFIG_BOOTCOMMAND \
- "mmcinit; ext2load mmc 0:1 0x10200000 /boot/uImage; bootm"
+ "mmc rescan; ext2load mmc 0:1 0x10200000 /boot/uImage; bootm"
/*
* Only interrupt autoboot if <space> is pressed. Otherwise, garbage
#define CONFIG_PORTMUX_PIO
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
#define CONFIG_MENU
#define CONFIG_MENU_SHOW
#define CONFIG_FIT
-#define CONFIG_CMD_PXE
#define CONFIG_BOARD_IMG_ADDR_R 0x80000000
#ifdef CONFIG_NAND_DAVINCI
#define CONFIG_ENV_SIZE (16 << 10)
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x180000
+#define CONFIG_ENV_RANGE 0x040000
#define CONFIG_ENV_OFFSET_REDUND 0x1c0000
-#define CONFIG_ENV_RANGE 0x020000
#undef CONFIG_ENV_IS_IN_FLASH
#endif
/* Defines for SPL */
#define CONFIG_SPL
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_NAND_SUPPORT
#define CONFIG_SPL_NAND_SIMPLE
#define CONFIG_SPL_NAND_LOAD
#define CONFIG_SPL_LDSCRIPT "$(BOARDDIR)/u-boot-spl.lds"
#define CONFIG_SPL_STACK (0x00010000 + 0x7f00)
-#define CONFIG_SPL_TEXT_BASE 0x0000020 /*CONFIG_SYS_SRAM_START*/
+#define CONFIG_SPL_TEXT_BASE 0x00000020 /*CONFIG_SYS_SRAM_START*/
#define CONFIG_SPL_MAX_SIZE 12320
#ifndef CONFIG_SPL_BUILD
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
#define CONFIG_SYS_NAND_U_BOOT_SIZE 0xa0000
+#define CONFIG_SYS_NAND_U_BOOT_ERA_SIZE 0x100000
/* for UBL header */
#define CONFIG_SYS_UBL_BLOCK (CONFIG_SYS_NAND_PAGE_SIZE)
" 0 3000;nandrbl uboot\0" \
"writeuboot=nandrbl uboot;" \
"nand erase " xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) " " \
- xstr(CONFIG_SYS_NAND_U_BOOT_SIZE) \
+ xstr(CONFIG_SYS_NAND_U_BOOT_ERA_SIZE) \
";nand write " xstr(DVN4XX_UBOOT_ADDR_R_UBOOT) \
" " xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) " " \
xstr(CONFIG_SYS_NAND_U_BOOT_SIZE) "\0" \
"nand write ${img_addr_r} 0 3000;nandrbl uboot\0" \
"img_writeuboot=nandrbl uboot;" \
"nand erase " xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) " " \
- xstr(CONFIG_SYS_NAND_U_BOOT_SIZE) \
+ xstr(CONFIG_SYS_NAND_U_BOOT_ERA_SIZE) \
";nand write ${img_addr_r} " \
xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) " " \
xstr(CONFIG_SYS_NAND_U_BOOT_SIZE) "\0" \
"img_writedfenv=ubi part ubi 2048;" \
"ubi write ${img_addr_r} default ${filesize}\0" \
"img_volume=rootfs1\0" \
- "img_writeramdisk=ubi part ubi 2048;ubifsmount ${img_volume};" \
+ "img_writeramdisk=ubi part ubi 2048;" \
"ubi write ${img_addr_r} ${img_volume} ${filesize}\0" \
"load_img=tftp ${fit_addr_r} ${img_file}\0" \
"net_nfs=run load_kernel; " \
+++ /dev/null
-/*
- * Copyright (C) 2011 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., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Spectrum Digital TMS320DM6467T EVM board */
-#define DAVINCI_DM6467EVM
-#define DAVINCI_DM6467TEVM
-#define CONFIG_SYS_USE_NAND
-#define CONFIG_SYS_NAND_SMALLPAGE
-
-#define CONFIG_SKIP_LOWLEVEL_INIT
-
-/* SoC Configuration */
-#define CONFIG_ARM926EJS /* arm926ejs CPU */
-
-/* Clock rates detection */
-#ifndef __ASSEMBLY__
-extern unsigned int davinci_arm_clk_get(void);
-#endif
-
-#define CFG_REFCLK_FREQ 33000000
-/* Arm Clock frequency */
-#define CONFIG_SYS_CLK_FREQ davinci_arm_clk_get()
-/* Timer Input clock freq */
-#define CONFIG_SYS_HZ_CLOCK (CONFIG_SYS_CLK_FREQ/2)
-#define CONFIG_SYS_TIMERBASE 0x01c21400 /* use timer 0 */
-#define CONFIG_SYS_HZ 1000
-#define CONFIG_SOC_DM646X
-
-/* EEPROM definitions for EEPROM */
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
-#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20
-
-/* Memory Info */
-#define CONFIG_SYS_MALLOC_LEN (1 << 20) /* 1 MiB */
-#define CONFIG_SYS_MEMTEST_START 0x80000000
-#define CONFIG_SYS_MEMTEST_END 0x81000000 /* 16MB RAM test */
-#define CONFIG_NR_DRAM_BANKS 1
-#define CONFIG_STACKSIZE (256 << 10) /* 256 KiB */
-#define PHYS_SDRAM_1 0x80000000 /* DDR Start */
-#define PHYS_SDRAM_1_SIZE (256 << 20) /* DDR size 256MB */
-
-/* Linux interfacing */
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_SYS_BARGSIZE 1024 /* Bootarg Size */
-#define CONFIG_SYS_LOAD_ADDR 0x80700000 /* kernel address */
-#define CONFIG_REVISION_TAG
-
-/* Serial Driver info */
-#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE 4
-#define CONFIG_SYS_NS16550_COM1 0x01c20000
-#define CONFIG_SYS_NS16550_CLK 24000000
-#define CONFIG_CONS_INDEX 1
-#define CONFIG_BAUDRATE 115200
-#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-
-/* I2C Configuration */
-#define CONFIG_HARD_I2C
-#define CONFIG_DRIVER_DAVINCI_I2C
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 10
-
-/* Network & Ethernet Configuration */
-#define CONFIG_DRIVER_TI_EMAC
-#define CONFIG_EMAC_MDIO_PHY_NUM 1
-#define CONFIG_MII
-#define CONFIG_BOOTP_DEFAULT
-#define CONFIG_BOOTP_DNS
-#define CONFIG_BOOTP_DNS2
-#define CONFIG_BOOTP_SEND_HOSTNAME
-#define CONFIG_NET_RETRY_COUNT 10
-#define CONFIG_CMD_NET
-
-/* Flash & Environment */
-#define CONFIG_SYS_NO_FLASH
-#ifdef CONFIG_SYS_USE_NAND
-#define CONFIG_NAND_DAVINCI
-#define CONFIG_SYS_NAND_CS 2
-#undef CONFIG_ENV_IS_IN_FLASH
-#define CONFIG_ENV_IS_IN_NAND
-#define CONFIG_ENV_SIZE (16 << 10) /* 16 KiB */
-#define CONFIG_SYS_NAND_BASE_LIST {0x42000000, }
-#define CONFIG_SYS_NAND_HW_ECC
-#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_ENV_OFFSET 0
-#else
-#define CONFIG_ENV_IS_NOWHERE
-#define CONFIG_ENV_SIZE (4 << 10) /* 4 KiB */
-#endif
-
-/* U-Boot general configuration */
-#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot */
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage" /* Boot file name */
-#define CONFIG_SYS_PROMPT "DM6467 EVM > " /* Monitor Command Prompt */
-#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
-#define CONFIG_SYS_PBSIZE \
- (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
-#define CONFIG_SYS_MAXARGS 16
-#define CONFIG_VERSION_VARIABLE
-#define CONFIG_AUTO_COMPLETE
-#define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
-#define CONFIG_CMDLINE_EDITING
-#define CONFIG_SYS_LONGHELP
-#define CONFIG_CRC32_VERIFY
-#define CONFIG_MX_CYCLIC
-#define CONFIG_BOOTCOMMAND "source 0x82080000; dhcp; bootm"
-#define CONFIG_BOOTARGS \
- "mem=120M console=ttyS0,115200n8 " \
- "root=/dev/hda1 rw noinitrd ip=dhcp"
-
-/* U-Boot commands */
-#include <config_cmd_default.h>
-#define CONFIG_CMD_ASKENV
-#define CONFIG_CMD_DIAG
-#define CONFIG_CMD_I2C
-#define CONFIG_CMD_MII
-#define CONFIG_CMD_SAVES
-#define CONFIG_CMD_EEPROM
-#define CONFIG_CMD_PING
-#define CONFIG_CMD_DHCP
-#undef CONFIG_CMD_BDI
-#undef CONFIG_CMD_FPGA
-#undef CONFIG_CMD_SETGETDCR
-#ifdef CONFIG_SYS_USE_NAND
-#undef CONFIG_CMD_FLASH
-#undef CONFIG_CMD_IMLS
-#define CONFIG_CMD_NAND
-#endif
-
-#ifdef CONFIG_CMD_BDI
-#define CONFIG_CLOCKS
-#endif
-
-#define CONFIG_MAX_RAM_BANK_SIZE (256 << 20) /* 256 MB */
-
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
-#define CONFIG_SYS_INIT_RAM_SIZE 0x1000
-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
- CONFIG_SYS_INIT_RAM_SIZE - \
- GENERATED_GBL_DATA_SIZE)
-
-#endif /* __CONFIG_H */
extern unsigned int davinci_arm_clk_get(void);
#endif
-#define CFG_REFCLK_FREQ 27000000
/* Arm Clock frequency */
#define CONFIG_SYS_CLK_FREQ davinci_arm_clk_get()
/* Timer Input clock freq */
#define CONFIG_OMAP 1 /* in a TI OMAP core */
#define CONFIG_OMAP34XX 1 /* which is a 34XX */
#define CONFIG_OMAP3_DEVKIT8000 1 /* working with DevKit8000 */
-
+#define CONFIG_MACH_TYPE MACH_TYPE_DEVKIT8000
/*
* 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
* 64 bytes before this address should be set aside for u-boot.img's
#define CONFIG_SPL_MAX_SIZE 0xB400 /* 45 K */
#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK
-#define CONFIG_SPL_BSS_START_ADDR 0x80000000 /*CONFIG_SYS_SDRAM_BASE*/
+#define CONFIG_SPL_BSS_START_ADDR 0x80000500 /* leave space for bootargs*/
#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
/* NAND boot config */
#define CONFIG_SYS_SPL_MALLOC_START 0x80208000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x100000 /* 1 MB */
+/* SPL OS boot options */
+#define CONFIG_SPL_OS_BOOT
+#define CONFIG_SPL_OS_BOOT_KEY 26
+
+#define CONFIG_CMD_SPL
+#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */
+#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
+ 0x400000)
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000
+#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100)
+
#endif /* __CONFIG_H */
#define CONFIG_IXP425 1
#define CONFIG_DVLHOST 1
+#define CONFIG_MACH_TYPE 1343
+
#define CONFIG_DISPLAY_CPUINFO 1
#define CONFIG_DISPLAY_BOARDINFO 1
#define CONFIG_SYS_HZ 1000
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_TEXT_BASE 0xc1080000
+#define CONFIG_DA8XX_GPIO
/*
* Memory Info
#define CONFIG_CMD_SAVES
#define CONFIG_CMD_MEMORY
#define CONFIG_CMD_I2C
+#define CONFIG_CMD_GPIO
#ifdef CONFIG_CMD_BDI
#define CONFIG_CLOCKS
#define CONFIG_SH_ETHER 1
#define CONFIG_SH_ETHER_USE_PORT (0)
#define CONFIG_SH_ETHER_PHY_ADDR (0x1f)
+#define CONFIG_PHY_SMSC 1
#define CONFIG_PHYLIB
#define CONFIG_BITBANGMII
#define CONFIG_BITBANGMII_MULTI
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_SST
-#define CONFIG_SPI_FLASH_CS (1 | 121 << 8)
+#define CONFIG_SF_DEFAULT_CS (1 | 121 << 8)
#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
#define CONFIG_SYS_MEMTEST_START 0x90000000
-#define CONFIG_SYS_MEMTEST_END 0x10000
+#define CONFIG_SYS_MEMTEST_END 0x90010000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
#define CONFIG_CMD_I2C
#define CONFIG_CMD_AUTOSCRIPT
#undef CONFIG_CMD_FPGA
+#define CONFIG_CMD_USB
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
/* Disable DCACHE */
#define CONFIG_SYS_DCACHE_OFF
#define CONFIG_CMD_EDITENV
#define CONFIG_CMD_SAVEENV
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_ARMADA100
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#endif /* CONFIG_CMD_USB */
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_ISO_PARTITION
+#define CONFIG_SUPPORT_VFAT
+
#endif /* __CONFIG_GPLUGD_H */
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#define CONFIG_SYS_DCACHE_LINESZ 32
#define CONFIG_SYS_ICACHE_LINESZ 32
#define CONFIG_BAUDRATE 38400
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_BOOTCOUNT_LIMIT
+#define CONFIG_SYS_BOOTCOUNT_ADDR 0xfff3cf0c
+
#define CONFIG_MISC_INIT_R
#define CONFIG_SCSI_AHCI
#define CONFIG_SCSI_AHCI_PLAT
#define CONFIG_SYS_LOAD_ADDR 0x800000
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "fdtaddr_r=0x600000\0" \
- "pxefile_addr_r=0x700000\0" \
- "kernel_addr_r=0x800000\0" \
- "ramdisk_addr_r=0x01000000\0" \
-
/*-----------------------------------------------------------------------
* Stack sizes
*
#define CONFIG_SYS_MEMTEST_START 0x100000
#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_1_SIZE - 0x100000)
-/* Room required on the stack for the environment data */
-#define CONFIG_ENV_SIZE 0x2000
-#define CONFIG_ENV_IS_NOWHERE
+/* Environment data setup
+*/
+#define CONFIG_ENV_IS_IN_NVRAM
+#define CONFIG_SYS_NVRAM_BASE_ADDR 0xfff88000 /* NVRAM base address */
+#define CONFIG_SYS_NVRAM_SIZE 0x8000 /* NVRAM size */
+#define CONFIG_ENV_SIZE 0x2000 /* Size of Environ */
+#define CONFIG_ENV_ADDR CONFIG_SYS_NVRAM_BASE_ADDR
#define CONFIG_SYS_SDRAM_BASE 0x00000000
-#define CONFIG_SYS_TEXT_BASE 0x00001000
+#define CONFIG_SYS_TEXT_BASE 0x00008000
#define CONFIG_SYS_INIT_SP_ADDR 0x01000000
#define CONFIG_SKIP_LOWLEVEL_INIT
/*
* Command line configuration.
*/
-
-
-#define CONFIG_CMD_IMI
-#define CONFIG_CMD_BDI
-#define CONFIG_CMD_BOOTD
-#define CONFIG_CMD_MEMORY
-#define CONFIG_CMD_FLASH
-#define CONFIG_CMD_IMLS
-#define CONFIG_CMD_LOADB
-#define CONFIG_CMD_LOADS
-
+#include <config_cmd_default.h>
#define CONFIG_BOOTDELAY 2
#define CONFIG_BOOTARGS "root=/dev/mtdblock0 console=ttyAM0 console=tty"
* PCI definitions
*/
-#ifdef CONFIG_PCI /* pci support */
-#undef CONFIG_PCI_PNP
-#define CONFIG_PCI_SCAN_SHOW 1 /* show pci devices on startup */
-#define DEBUG
+#define CONFIG_PCI
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_NET_MULTI
+#define CONFIG_TULIP
#define CONFIG_EEPRO100
#define CONFIG_SYS_RX_ETH_BUFFER 8 /* use 8 rx buffer on eepro100 */
-#define INTEGRATOR_BOOT_ROM_BASE 0x20000000
-#define INTEGRATOR_HDR0_SDRAM_BASE 0x80000000
-
-/* PCI Base area */
-#define INTEGRATOR_PCI_BASE 0x40000000
-#define INTEGRATOR_PCI_SIZE 0x3FFFFFFF
-
-/* memory map as seen by the CPU on the local bus */
-#define CPU_PCI_IO_ADRS 0x60000000 /* PCI I/O space base */
-#define CPU_PCI_IO_SIZE 0x10000
-
-#define CPU_PCI_CNFG_ADRS 0x61000000 /* PCI config space */
-#define CPU_PCI_CNFG_SIZE 0x1000000
-
-#define PCI_MEM_BASE 0x40000000 /* 512M to xxx */
-/* unused 256M from A0000000-AFFFFFFF might be used for I2O ??? */
-#define INTEGRATOR_PCI_IO_BASE 0x60000000 /* 16M to xxx */
-/* unused (128-16)M from B1000000-B7FFFFFF */
-#define PCI_CONFIG_BASE 0x61000000 /* 16M to xxx */
-/* unused ((128-16)M - 64K) from XXX */
-
-#define PCI_V3_BASE 0x62000000
-
-/* V3 PCI bridge controller */
-#define V3_BASE 0x62000000 /* V360EPC registers */
-
-#define PCI_ENET0_IOADDR (CPU_PCI_IO_ADRS)
-#define PCI_ENET0_MEMADDR (PCI_MEM_BASE)
-
-
-#define V3_PCI_VENDOR 0x00000000
-#define V3_PCI_DEVICE 0x00000002
-#define V3_PCI_CMD 0x00000004
-#define V3_PCI_STAT 0x00000006
-#define V3_PCI_CC_REV 0x00000008
-#define V3_PCI_HDR_CF 0x0000000C
-#define V3_PCI_IO_BASE 0x00000010
-#define V3_PCI_BASE0 0x00000014
-#define V3_PCI_BASE1 0x00000018
-#define V3_PCI_SUB_VENDOR 0x0000002C
-#define V3_PCI_SUB_ID 0x0000002E
-#define V3_PCI_ROM 0x00000030
-#define V3_PCI_BPARAM 0x0000003C
-#define V3_PCI_MAP0 0x00000040
-#define V3_PCI_MAP1 0x00000044
-#define V3_PCI_INT_STAT 0x00000048
-#define V3_PCI_INT_CFG 0x0000004C
-#define V3_LB_BASE0 0x00000054
-#define V3_LB_BASE1 0x00000058
-#define V3_LB_MAP0 0x0000005E
-#define V3_LB_MAP1 0x00000062
-#define V3_LB_BASE2 0x00000064
-#define V3_LB_MAP2 0x00000066
-#define V3_LB_SIZE 0x00000068
-#define V3_LB_IO_BASE 0x0000006E
-#define V3_FIFO_CFG 0x00000070
-#define V3_FIFO_PRIORITY 0x00000072
-#define V3_FIFO_STAT 0x00000074
-#define V3_LB_ISTAT 0x00000076
-#define V3_LB_IMASK 0x00000077
-#define V3_SYSTEM 0x00000078
-#define V3_LB_CFG 0x0000007A
-#define V3_PCI_CFG 0x0000007C
-#define V3_DMA_PCI_ADR0 0x00000080
-#define V3_DMA_PCI_ADR1 0x00000090
-#define V3_DMA_LOCAL_ADR0 0x00000084
-#define V3_DMA_LOCAL_ADR1 0x00000094
-#define V3_DMA_LENGTH0 0x00000088
-#define V3_DMA_LENGTH1 0x00000098
-#define V3_DMA_CSR0 0x0000008B
-#define V3_DMA_CSR1 0x0000009B
-#define V3_DMA_CTLB_ADR0 0x0000008C
-#define V3_DMA_CTLB_ADR1 0x0000009C
-#define V3_DMA_DELAY 0x000000E0
-#define V3_MAIL_DATA 0x000000C0
-#define V3_PCI_MAIL_IEWR 0x000000D0
-#define V3_PCI_MAIL_IERD 0x000000D2
-#define V3_LB_MAIL_IEWR 0x000000D4
-#define V3_LB_MAIL_IERD 0x000000D6
-#define V3_MAIL_WR_STAT 0x000000D8
-#define V3_MAIL_RD_STAT 0x000000DA
-#define V3_QBA_MAP 0x000000DC
-
-/* SYSTEM register bits */
-#define V3_SYSTEM_M_RST_OUT (1 << 15)
-#define V3_SYSTEM_M_LOCK (1 << 14)
-
-/* PCI_CFG bits */
-#define V3_PCI_CFG_M_RETRY_EN (1 << 10)
-#define V3_PCI_CFG_M_AD_LOW1 (1 << 9)
-#define V3_PCI_CFG_M_AD_LOW0 (1 << 8)
-
-/* PCI MAP register bits (PCI -> Local bus) */
-#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000
-#define V3_PCI_MAP_M_RD_POST_INH (1 << 15)
-#define V3_PCI_MAP_M_ROM_SIZE (1 << 11 | 1 << 10)
-#define V3_PCI_MAP_M_SWAP (1 << 9 | 1 << 8)
-#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0
-#define V3_PCI_MAP_M_REG_EN (1 << 1)
-#define V3_PCI_MAP_M_ENABLE (1 << 0)
-
-/* 9 => 512M window size */
-#define V3_PCI_MAP_M_ADR_SIZE_512M 0x00000090
-
-/* A => 1024M window size */
-#define V3_PCI_MAP_M_ADR_SIZE_1024M 0x000000A0
-
-/* LB_BASE register bits (Local bus -> PCI) */
-#define V3_LB_BASE_M_MAP_ADR 0xFFF00000
-#define V3_LB_BASE_M_SWAP (1 << 8 | 1 << 9)
-#define V3_LB_BASE_M_ADR_SIZE 0x000000F0
-#define V3_LB_BASE_M_PREFETCH (1 << 3)
-#define V3_LB_BASE_M_ENABLE (1 << 0)
-
-/* PCI COMMAND REGISTER bits */
-#define V3_COMMAND_M_FBB_EN (1 << 9)
-#define V3_COMMAND_M_SERR_EN (1 << 8)
-#define V3_COMMAND_M_PAR_EN (1 << 6)
-#define V3_COMMAND_M_MASTER_EN (1 << 2)
-#define V3_COMMAND_M_MEM_EN (1 << 1)
-#define V3_COMMAND_M_IO_EN (1 << 0)
-
-#define INTEGRATOR_SC_BASE 0x11000000
-#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
-#define INTEGRATOR_SC_PCIENABLE \
- (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
-#endif /* CONFIG_PCI */
/*-----------------------------------------------------------------------
* There are various dependencies on the core module (CM) fitted
* Users should refer to their CM user guide
#ifndef __CONFIG_H
#define __CONFIG_H
+/* Integrator-specific configuration */
#define CONFIG_INTEGRATOR
-#define CONFIG_ARCH_INTEGRATOR
+#define CONFIG_ARCH_CINTEGRATOR
+#define CONFIG_CM_INIT
+#define CONFIG_CM_REMAP
+#define CONFIG_CM_SPD_DETECT
+
/*
* High Level Configuration Options
* (easy to change)
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_MISC_INIT_R 1 /* call misc_init_r during start up */
+
/*
* Size of malloc() pool
*/
/*
* Command line configuration.
*/
-#define CONFIG_CMD_BDI
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_SAVEENV
-#define CONFIG_CMD_FLASH
-#define CONFIG_CMD_IMI
-#define CONFIG_CMD_MEMORY
-#define CONFIG_CMD_NET
-#define CONFIG_CMD_PING
-
+#include <config_cmd_default.h>
-#if 0
#define CONFIG_BOOTDELAY 2
-#define CONFIG_BOOTARGS "root=/dev/nfs nfsroot=<IP address>:/<exported rootfs> mem=128M ip=dhcp netdev=27,0,0xfc800000,0xfc800010,eth0 video=clcdfb:0"
-#define CONFIG_BOOTCOMMAND "bootp ; bootm"
-#endif
-/* The kernel command line & boot command below are for a platform flashed with afu.axf
-
-Image 666 Block 0 End Block 0 address 0x24000000 exec 0x24000000- name u-boot
-Image 667 Block 1 End Block 13 address 0x24040000 exec 0x24040000- name u-linux
-Image 668 Block 14 End Block 33 address 0x24380000 exec 0x24380000- name rootfs
-SIB at Block62 End Block62 address 0x24f80000
-
-*/
-#define CONFIG_BOOTDELAY 2
-#define CONFIG_BOOTARGS "root=/dev/mtdblock2 mem=128M ip=dhcp netdev=27,0,0xfc800000,0xfc800010,eth0 video=clcdfb:0 console=ttyAMA0"
-#define CONFIG_BOOTCOMMAND "cp 0x24080000 0x7fc0 0x100000; bootm"
+#define CONFIG_BOOTARGS "root=/dev/mtdblock0 console=ttyAMA0 console=tty ip=dhcp netdev=27,0,0xfc800000,0xfc800010,eth0 video=clcdfb:0"
+#define CONFIG_BOOTCOMMAND "tftpboot ; bootm"
+#define CONFIG_SERVERIP 192.168.1.100
+#define CONFIG_IPADDR 192.168.1.104
+#define CONFIG_BOOTFILE "uImage"
/*
* Miscellaneous configurable options
#define CONFIG_ENV_SECT_SIZE 0x40000 /* 256KB */
#define CONFIG_ENV_SIZE 8192 /* 8KB */
-/*-----------------------------------------------------------------------
- * CP control registers
- */
-#define CPCR_BASE 0xCB000000 /* CP Registers*/
-#define OS_FLASHPROG 0x00000004 /* Flash register*/
-#define CPMASK_EXTRABANK 0x8
-#define CPMASK_FLASHSIZE 0x4
-#define CPMASK_FLWREN 0x2
-#define CPMASK_FLVPPEN 0x1
/*
* The ARM boot monitor initializes the board.
*/
#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
+#define CONFIG_MMC_BOUNCE_BUFFER
#define CONFIG_GENERIC_MMC
#define CONFIG_MXS_MMC
#endif
#ifdef CONFIG_CMD_SF
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO
-#define CONFIG_SPI_FLASH_CS 2
+#define CONFIG_SF_DEFAULT_CS 2
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#define CONFIG_SF_DEFAULT_SPEED 24000000
"else run nandboot; fi"
#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+
/*
* Miscellaneous configurable options
*/
#define CONFIG_SYS_NAND_ECCSIZE 256
#define CONFIG_SYS_NAND_ECCBYTES 3
-#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
- CONFIG_SYS_NAND_ECCSIZE)
-#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
- CONFIG_SYS_NAND_ECCSTEPS)
-
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
#else
# define CONFIG_CMD_PING
# define CONFIG_CMD_DHCP
+# define CONFIG_CMD_TFTPPUT
#endif
#if defined(CONFIG_SYSTEMACE)
#define CONFIG_FIT 1
#define CONFIG_OF_LIBFDT 1
+#if defined(CONFIG_XILINX_AXIEMAC)
+# define CONFIG_MII 1
+# define CONFIG_CMD_MII 1
+# define CONFIG_PHY_GIGE 1
+# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN 1
+# define CONFIG_PHYLIB 1
+# define CONFIG_PHY_ATHEROS 1
+# define CONFIG_PHY_BROADCOM 1
+# define CONFIG_PHY_DAVICOM 1
+# define CONFIG_PHY_LXT 1
+# define CONFIG_PHY_MARVELL 1
+# define CONFIG_PHY_MICREL 1
+# define CONFIG_PHY_NATSEMI 1
+# define CONFIG_PHY_REALTEK 1
+# define CONFIG_PHY_VITESSE 1
+#else
+# undef CONFIG_MII
+# undef CONFIG_CMD_MII
+# undef CONFIG_PHYLIB
+#endif
+
#endif /* __CONFIG_H */
#define CONFIG_SYS_NR_PIOS 5
#define CONFIG_SYS_HSDRAMC
#define CONFIG_MMC
-#define CONFIG_ATMEL_MCI
+#define CONFIG_GENERIC_ATMEL_MCI
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1
#if defined(CONFIG_LCD)
#define CONFIG_CMD_BMP
#define V_PROMPT "mt_ventoux => "
#define CONFIG_SYS_PROMPT V_PROMPT
+/*
+ * Set its own mtdparts, different from common
+ */
+#undef MTDIDS_DEFAULT
+#undef MTDPARTS_DEFAULT
+#define MTDIDS_DEFAULT "nand0=omap2-nand.0"
+#define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:512k(MLO)," \
+ "1m(u-boot),256k(env1)," \
+ "256k(env2),8m(ubisystem),-(rootfs)"
+
/*
* FPGA
*/
#define CONFIG_CMD_FAT
#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_GPIO
#define CONFIG_CMD_MII
#define CONFIG_CMD_NET
#define CONFIG_CMD_NFS
#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_USB
/*
* Memory configurations
#define CONFIG_BAUDRATE 115200 /* Default baud rate */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+/*
+ * DMA
+ */
+#define CONFIG_APBH_DMA
+
/*
* MMC Driver
*/
#define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET (256 * 1024)
-#define CONFIG_ENV_SIZE (16 * 1024)
-#define CONFIG_SYS_MMC_ENV_DEV 0
+#ifdef CONFIG_ENV_IS_IN_MMC
+ #define CONFIG_ENV_OFFSET (256 * 1024)
+ #define CONFIG_ENV_SIZE (16 * 1024)
+ #define CONFIG_SYS_MMC_ENV_DEV 0
+#endif
#define CONFIG_CMD_SAVEENV
#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
+#define CONFIG_MMC_BOUNCE_BUFFER
#define CONFIG_MXS_MMC
#endif
#define CONFIG_MX28_FEC_MAC_IN_OCOTP
#endif
+/*
+ * RTC
+ */
+#ifdef CONFIG_CMD_DATE
+#define CONFIG_RTC_MXS
+#endif
+
+/*
+ * USB
+ */
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MXS
+#define CONFIG_EHCI_MXS_PORT 1
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#endif
+
+/*
+ * SPI
+ */
+#ifdef CONFIG_CMD_SPI
+#define CONFIG_HARD_SPI
+#define CONFIG_MXS_SPI
+#define CONFIG_SPI_HALF_DUPLEX
+#define CONFIG_DEFAULT_SPI_BUS 2
+#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
+
+/* SPI Flash */
+#ifdef CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH
+#define CONFIG_SF_DEFAULT_BUS 2
+#define CONFIG_SF_DEFAULT_CS 0
+/* this may vary and depends on the installed chip */
+#define CONFIG_SPI_FLASH_SST
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED 24000000
+
+/* (redundant) environemnt in SPI flash */
+#undef CONFIG_ENV_IS_IN_SPI_FLASH
+#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_SIZE 0x1000 /* 4KB */
+#define CONFIG_ENV_OFFSET 0x40000 /* 256K */
+#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
+#define CONFIG_ENV_SECT_SIZE 0x1000
+#define CONFIG_ENV_SPI_CS 0
+#define CONFIG_ENV_SPI_BUS 2
+#define CONFIG_ENV_SPI_MAX_HZ 24000000
+#define CONFIG_ENV_SPI_MODE SPI_MODE_0
+#endif
+#endif
+#endif
+
/*
* Boot Linux
*/
/* memtest works on */
#define CONFIG_SYS_MEMTEST_START 0x80000000
-#define CONFIG_SYS_MEMTEST_END 0x10000
+#define CONFIG_SYS_MEMTEST_END 0x80010000
/* default load address */
#define CONFIG_SYS_LOAD_ADDR 0x81000000
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
#define CONFIG_SYS_MEMTEST_START 0x90000000
-#define CONFIG_SYS_MEMTEST_END 0x10000
+#define CONFIG_SYS_MEMTEST_END 0x90010000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
#define CONFIG_SYS_MEMTEST_START 0x70000000
-#define CONFIG_SYS_MEMTEST_END 0x10000
+#define CONFIG_SYS_MEMTEST_END 0x70010000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
#define CONFIG_SYS_MEMTEST_START 0x70000000
-#define CONFIG_SYS_MEMTEST_END 0x10000
+#define CONFIG_SYS_MEMTEST_END 0x70010000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_MACH_TYPE 3769
+
#include <asm/arch/imx-regs.h>
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART2_BASE
+#define CONFIG_CMD_SF
+#ifdef CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_SST
+#define CONFIG_MXC_SPI
+#define CONFIG_SF_DEFAULT_BUS 0
+#define CONFIG_SF_DEFAULT_CS (0|(GPIO_NUMBER(3, 19)<<8))
+#define CONFIG_SF_DEFAULT_SPEED 25000000
+#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
+#endif
+
/* MMC Configs */
#define CONFIG_FSL_ESDHC
#define CONFIG_FSL_USDHC
#define CONFIG_MMC
#define CONFIG_CMD_MMC
#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_FAT
#define CONFIG_DOS_PARTITION
#define CONFIG_FEC_XCV_TYPE RGMII
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_FEC_MXC_PHYADDR 6
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MICREL
+
+/* USB Configs */
+#define CONFIG_CMD_USB
+#define CONFIG_CMD_FAT
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MX6
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_MXC_USB_PORT 1
+#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_MXC_USB_FLAGS 0
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
/* FLASH and environment organization */
#define CONFIG_SYS_NO_FLASH
-#define CONFIG_ENV_OFFSET (6 * 64 * 1024)
-#define CONFIG_ENV_SIZE (8 * 1024)
+#define CONFIG_ENV_SIZE (8 * 1024)
+
#define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_SYS_MMC_ENV_DEV 0
+/* #define CONFIG_ENV_IS_IN_SPI_FLASH */
+
+#if defined(CONFIG_ENV_IS_IN_MMC)
+#define CONFIG_ENV_OFFSET (6 * 64 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
+#define CONFIG_ENV_OFFSET (768 * 1024)
+#define CONFIG_ENV_SECT_SIZE (8 * 1024)
+#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS
+#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
+#define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE
+#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#endif
#define CONFIG_OF_LIBFDT
+++ /dev/null
-/*
- * (C) Copyright 2004
- * Texas Instruments.
- * Kshitij Gupta <kshitij@ti.com>
- * Configuration settings for the TI OMAP 1610 H2 board.
- *
- * 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
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/*
- * High Level Configuration Options
- * (easy to change)
- */
-#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU core */
-#define CONFIG_OMAP 1 /* in a TI OMAP core */
-#define CONFIG_OMAP1610 1 /* which is in a 1610 */
-#define CONFIG_H2_OMAP1610 1 /* on an H2 Board */
-
-#define CONFIG_MACH_TYPE MACH_TYPE_OMAP_H2
-
-/* input clock of PLL */
-/* the OMAP1610 H2 has 12MHz input clock */
-#define CONFIG_SYS_CLK_FREQ 12000000
-
-#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
-
-#define CONFIG_MISC_INIT_R
-
-#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
-#define CONFIG_SETUP_MEMORY_TAGS 1
-#define CONFIG_INITRD_TAG 1
-
-/*
- * Size of malloc() pool
- */
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
-
-/*
- * Hardware drivers
- */
-#define CONFIG_LAN91C96
-#define CONFIG_LAN91C96_BASE 0x04000300
-#define CONFIG_LAN91C96_EXT_PHY
-
-/*
- * NS16550 Configuration
- */
-#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE (-4)
-#define CONFIG_SYS_NS16550_CLK (48000000) /* can be 12M/32Khz or 48Mhz */
-#define CONFIG_SYS_NS16550_COM1 0xfffb0000 /* uart1, bluetooth uart */
-
-/*
- * select serial console configuration
- */
-#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on OMAP1610 H2 */
-
-/* allow to overwrite serial and ethaddr */
-#define CONFIG_ENV_OVERWRITE
-#define CONFIG_CONS_INDEX 1
-#define CONFIG_BAUDRATE 115200
-#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-
-
-/*
- * Command line configuration.
- */
-#include <config_cmd_default.h>
-
-#define CONFIG_CMD_DHCP
-
-
-/*
- * BOOTP options
- */
-#define CONFIG_BOOTP_SUBNETMASK
-#define CONFIG_BOOTP_GATEWAY
-#define CONFIG_BOOTP_HOSTNAME
-#define CONFIG_BOOTP_BOOTPATH
-
-
-#include <configs/omap1510.h>
-
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTARGS "console=ttyS0,115200n8 noinitrd root=/dev/nfs ip=dhcp"
-#define CONFIG_BOOTCOMMAND "bootp;tftp;bootm"
-#define CONFIG_SYS_AUTOLOAD "n" /* No autoload */
-
-#if defined(CONFIG_CMD_KGDB)
-#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
-#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
-#endif
-
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_LONGHELP /* undef to save memory */
-#define CONFIG_SYS_PROMPT "OMAP1610 H2 # " /* Monitor Command Prompt */
-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
-/* Print Buffer Size */
-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
-
-#define CONFIG_SYS_MEMTEST_START 0x10000000 /* memtest works on */
-#define CONFIG_SYS_MEMTEST_END 0x12000000 /* 32 MB in DRAM */
-
-#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-
-/* The 1610 has 6 timers, they can be driven by the RefClk (12Mhz) or by
- * DPLL1. This time is further subdivided by a local divisor.
- */
-#define CONFIG_SYS_TIMERBASE 0xFFFEC500 /* use timer 1 */
-#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */
-#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV))
-
-/*-----------------------------------------------------------------------
- * Stack sizes
- *
- * The stack sizes are set up in start.S using the settings below
- */
-#define CONFIG_STACKSIZE (128*1024) /* regular stack */
-#ifdef CONFIG_USE_IRQ
-#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
-#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
-#endif
-
-/*-----------------------------------------------------------------------
- * Physical Memory Map
- */
-#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x10000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */
-
-#define PHYS_FLASH_1_BM1 0x00000000 /* Flash Bank #1 if booting from flash */
-#define PHYS_FLASH_1_BM0 0x0C000000 /* Flash Bank #1 if booting from RAM */
-
-#ifdef CONFIG_CS_AUTOBOOT /* Determine CS assignment in runtime */
-
-#ifndef __ASSEMBLY__
-extern unsigned long omap_flash_base; /* set in flash__init */
-#endif
-#define CONFIG_SYS_FLASH_BASE omap_flash_base
-
-#elif defined(CONFIG_CS0_BOOT)
-
-#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1_BM0
-
-#else
-
-#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1_BM1
-
-#endif
-
-#define PHYS_SRAM 0x20000000
-
-/*-----------------------------------------------------------------------
- * FLASH and environment organization
- */
-#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
-#define PHYS_FLASH_SIZE 0x02000000 /* 32MB */
-#define CONFIG_SYS_MAX_FLASH_SECT (259) /* max number of sectors on one chip */
-/* addr of environment */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x020000)
-
-/* timeout values are in ticks */
-#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
-#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
-
-#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
-#define CONFIG_ENV_OFFSET 0x20000 /* environment starts here */
-
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
-#define CONFIG_SYS_INIT_SP_ADDR PHYS_SRAM
-
-#endif /* __CONFIG_H */
+++ /dev/null
-/*
- * (C) Copyright 2003
- * Texas Instruments.
- * Kshitij Gupta <kshitij@ti.com>
- * Configuation settings for the TI OMAP Innovator board.
- *
- * 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
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/*
- * High Level Configuration Options
- * (easy to change)
- */
-#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU core */
-#define CONFIG_OMAP 1 /* in a TI OMAP core */
-#define CONFIG_OMAP1610 1 /* which is in a 1610 */
-#define CONFIG_INNOVATOROMAP1610 1 /* a Innovator Board */
-
-#define CONFIG_MACH_TYPE MACH_TYPE_OMAP_INNOVATOR
-
-/* input clock of PLL */
-/* the OMAP1610 Innovator has 12MHz input clock */
-#define CONFIG_SYS_CLK_FREQ 12000000
-
-#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
-
-#define CONFIG_MISC_INIT_R
-
-#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
-#define CONFIG_SETUP_MEMORY_TAGS 1
-
-/*
- * Size of malloc() pool
- */
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
-
-/*
- * Hardware drivers
- */
-/*
-*/
-#define CONFIG_LAN91C96
-#define CONFIG_LAN91C96_BASE 0x04000300
-#define CONFIG_LAN91C96_EXT_PHY
-
-/*
- * NS16550 Configuration
- */
-#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE (-4)
-#define CONFIG_SYS_NS16550_CLK (48000000) /* can be 12M/32Khz or 48Mhz */
-#define CONFIG_SYS_NS16550_COM1 0xfffb0000 /* uart1, bluetooth uart on helen */
-
-/*
- * select serial console configuration
- */
-#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on OMAP1610 Innovator */
-
-/* allow to overwrite serial and ethaddr */
-#define CONFIG_ENV_OVERWRITE
-#define CONFIG_CONS_INDEX 1
-#define CONFIG_BAUDRATE 115200
-#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
-
-
-/*
- * Command line configuration.
- */
-#include <config_cmd_default.h>
-
-#define CONFIG_CMD_DHCP
-
-
-/*
- * BOOTP options
- */
-#define CONFIG_BOOTP_SUBNETMASK
-#define CONFIG_BOOTP_GATEWAY
-#define CONFIG_BOOTP_HOSTNAME
-#define CONFIG_BOOTP_BOOTPATH
-
-
-#include <configs/omap1510.h>
-
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTARGS "mem=32M console=ttyS0,115200n8 noinitrd \
- root=/dev/nfs rw nfsroot=157.87.82.48:\
- /home/a0875451/mwd/myfs/target ip=dhcp"
-#define CONFIG_NETMASK 255.255.254.0 /* talk on MY local net */
-#define CONFIG_IPADDR 156.117.97.156 /* static IP I currently own */
-#define CONFIG_SERVERIP 156.117.97.139 /* current IP of my dev pc */
-#define CONFIG_BOOTFILE "uImage" /* file to load */
-
-#if defined(CONFIG_CMD_KGDB)
-#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */
-#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
-#endif
-
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_LONGHELP /* undef to save memory */
-#define CONFIG_SYS_PROMPT "OMAP1610 Innovator # " /* Monitor Command Prompt */
-#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
-/* Print Buffer Size */
-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
-
-#define CONFIG_SYS_MEMTEST_START 0x10000000 /* memtest works on */
-#define CONFIG_SYS_MEMTEST_END 0x12000000 /* 32 MB in DRAM */
-
-#define CONFIG_SYS_LOAD_ADDR 0x10000000 /* default load address */
-
-/* The 1610 has 6 timers, they can be driven by the RefClk (12Mhz) or by
- * DPLL1. This time is further subdivided by a local divisor.
- */
-#define CONFIG_SYS_TIMERBASE 0xFFFEC500 /* use timer 1 */
-#define CONFIG_SYS_PTV 7 /* 2^(PTV+1), divide by 256 */
-#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV))
-
-/*-----------------------------------------------------------------------
- * Stack sizes
- *
- * The stack sizes are set up in start.S using the settings below
- */
-#define CONFIG_STACKSIZE (128*1024) /* regular stack */
-#ifdef CONFIG_USE_IRQ
-#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
-#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
-#endif
-
-/*-----------------------------------------------------------------------
- * Physical Memory Map
- */
-#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x10000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_1_SIZE 0x02000000 /* 32 MB */
-
-#define PHYS_FLASH_1_BM1 0x00000000 /* Flash Bank #1 if booting from flash */
-#define PHYS_FLASH_1_BM0 0x0C000000 /* Flash Bank #1 if booting from RAM */
-
-#ifdef CONFIG_CS_AUTOBOOT /* Determine CS assignment in runtime */
-
-#ifndef __ASSEMBLY__
-extern unsigned long omap_flash_base; /* set in flash__init */
-#endif
-#define CONFIG_SYS_FLASH_BASE omap_flash_base
-
-#elif defined(CONFIG_CS0_BOOT)
-
-#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1_BM0
-
-#else
-
-#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1_BM1
-
-#endif
-
-#define PHYS_SRAM 0x20000000
-
-/*-----------------------------------------------------------------------
- * FLASH and environment organization
- */
-#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
-#define PHYS_FLASH_SIZE 0x02000000 /* 32MB */
-#define CONFIG_SYS_MAX_FLASH_SECT (259) /* max number of sectors on one chip */
-/* addr of environment */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x020000)
-
-/* timeout values are in ticks */
-#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
-#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
-
-#define CONFIG_ENV_IS_IN_FLASH 1
-#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
-#define CONFIG_ENV_OFFSET 0x20000 /* environment starts here */
-
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
-#define CONFIG_SYS_INIT_SP_ADDR PHYS_SRAM
-
-#endif /* __CONFIG_H */
10, 11, 12, 13}
#define CONFIG_SYS_NAND_ECCSIZE 512
#define CONFIG_SYS_NAND_ECCBYTES 3
-#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
- CONFIG_SYS_NAND_ECCSIZE)
-#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
- CONFIG_SYS_NAND_ECCSTEPS)
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
#define CONFIG_IXP425 1 /* This is an IXP425 CPU */
#define CONFIG_PDNB3 1 /* on an PDNB3 board */
+#define CONFIG_MACH_TYPE 1002
+
#define CONFIG_DISPLAY_CPUINFO 1 /* display cpu info (and speed) */
#define CONFIG_DISPLAY_BOARDINFO 1 /* display board info */
#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
/* Board Clock */
-#define CONFIG_SYS_CLK_FREQ 33333333
+#define CONFIG_SYS_CLK_FREQ 36000000
#define CMT_CLK_DIVIDER 32 /* 8 (default), 32, 128 or 512 */
#define CONFIG_SYS_HZ (CONFIG_SYS_CLK_FREQ / CMT_CLK_DIVIDER)
/* Number of bits in a C 'long' on this architecture */
#define CONFIG_SANDBOX_BITS_PER_LONG 64
+#define CONFIG_OF_CONTROL
+#define CONFIG_OF_LIBFDT
+#define CONFIG_LMB
+
+#define CONFIG_SYS_VSNPRINTF
+
+#define CONFIG_CMD_GPIO
+#define CONFIG_SANDBOX_GPIO
+#define CONFIG_SANDBOX_GPIO_COUNT 20
+
/*
* Size of malloc() pool, although we don't actually use this yet.
*/
#include <asm/sizes.h>
#include "tegra2-common.h"
+/* Enable fdt support for Seaboard. Flash the image in u-boot-dtb.bin */
+#define CONFIG_DEFAULT_DEVICE_TREE tegra2-seaboard
+#define CONFIG_OF_CONTROL
+#define CONFIG_OF_SEPARATE
+
/* High-level configuration options */
#define TEGRA2_SYSMEM "mem=384M@0M nvmem=128M@384M mem=512M@512M"
#define V_PROMPT "Tegra2 (SeaBoard) # "
#define CONFIG_CMD_SF
#define CONFIG_SPI_FLASH_SIZE (4 << 20)
+/* I2C */
+#define CONFIG_TEGRA_I2C
+#define CONFIG_SYS_I2C_INIT_BOARD
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_MAX_I2C_BUS 4
+#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_CMD_I2C
+
/* SD/MMC */
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
#define CONFIG_ENV_OFFSET (CONFIG_SPI_FLASH_SIZE - CONFIG_ENV_SECT_SIZE)
+
+/* USB Host support */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_TEGRA
+#define CONFIG_USB_STORAGE
+#define CONFIG_CMD_USB
+
#endif /* __CONFIG_H */
#define CONFIG_CMD_MD5SUM
#define CONFIG_MD5
#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_EXT2
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTDELAY 3
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO 1
+/* MMCIF */
+#define CONFIG_MMC 1
+#define CONFIG_GENERIC_MMC 1
+#define CONFIG_SH_MMCIF 1
+#define CONFIG_SH_MMCIF_ADDR 0xffcb0000
+#define CONFIG_SH_MMCIF_CLK 48000000
+
/* SH7757 board */
#define SH7757LCR_SDRAM_PHYS_TOP 0x40000000
#define SH7757LCR_GRA_OFFSET 0x1f000000
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_LONGHELP
-#define CONFIG_SYS_EXTBDINFO
#define CONFIG_CMDLINE_EDITING
#define CONFIG_AUTO_COMPLETE
#define CONFIG_SYS_HUSH_PARSER
*/
/* USBD driver configuration */
-#define CONFIG_SPEARUDC
+#define CONFIG_DW_UDC
#define CONFIG_USB_DEVICE
#define CONFIG_USB_TTY
#define CONFIG_USBD_PRODUCT_NAME "SPEAr SoC"
#define CONFIG_USBD_MANUFACTURER "ST Microelectronics"
+#if defined(CONFIG_USB_TTY)
#define CONFIG_EXTRA_ENV_USBTTY "usbtty=cdc_acm\0"
+#endif
/* I2C driver configuration */
#define CONFIG_HARD_I2C
#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
115200}
+/*
+ * This parameter affects a TXFILLTUNING field that controls how much data is
+ * sent to the latency fifo before it is sent to the wire. Without this
+ * parameter, the default (2) causes occasional Data Buffer Errors in OUT
+ * packets depending on the buffer address and size.
+ */
+#define CONFIG_USB_EHCI_TXFIFO_THRESH 10
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_EHCI_DCACHE
+
+/* Total I2C ports on Tegra2 */
+#define TEGRA_I2C_NUM_CONTROLLERS 4
+
/* include default commands */
#include <config_cmd_default.h>
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=0x82000000\0" \
"console=ttyO2,115200n8\0" \
+ "mmcdev=0\0" \
"vram=12M\0" \
"lcdmode=800x600\0" \
"defaultdisplay=lcd\0" \
"root=ubi0:rootfs " \
"rootfstype=ubifs " \
"${kernelopts}\0" \
- "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \
+ "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \
"bootscript=echo Running bootscript from mmc ...; " \
"source ${loadaddr}\0" \
- "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \
+ "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \
"eraseenv=nand unlock 0x260000 0x20000; nand erase 0x260000 0x20000\0" \
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \
"run nandargs; " \
"nand read ${loadaddr} 280000 400000; " \
"bootm ${loadaddr}\0" \
- "autoboot=if mmc init 0; then " \
+ "autoboot=if mmc rescan ${mmcdev}; then " \
"if run loadbootscript; then " \
"run bootscript; " \
"else " \
#define CONFIG_SYS_NAND_ECCSIZE 512
#define CONFIG_SYS_NAND_ECCBYTES 3
-#define CONFIG_SYS_NAND_ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \
- CONFIG_SYS_NAND_ECCSIZE)
-#define CONFIG_SYS_NAND_ECCTOTAL (CONFIG_SYS_NAND_ECCBYTES * \
- CONFIG_SYS_NAND_ECCSTEPS)
-
#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SECT_SIZE (128 * 1024)
-#define CONFIG_ENV_SIZE (8 * 1024) /* smaller for faster access */
+#define CONFIG_ENV_SIZE (128 * 1024)
/* Address and size of Redundant Environment Sector */
#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
#define CONFIG_GENERIC_MMC
#define CONFIG_MXC_MMC
#define CONFIG_MXC_MCI_REGS_BASE SDHC1_BASE_ADDR
+
+/* video support */
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_MX3
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO_LOGO
+/* splash image won't work with NAND boot, use preboot script */
+#define CONFIG_VIDEO_SW_CURSOR
+#define CONFIG_CONSOLE_EXTRA_INFO /* display additional board info */
+#define CONFIG_VGA_AS_SINGLE_DEVICE /* display is an output only device */
+
+/* allow stdin, stdout and stderr variables to redirect output */
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SILENT_CONSOLE /* UARTs used externally (release) */
+#define CONFIG_SYS_DEVICE_NULLDEV /* allow console to be turned off */
+#define CONFIG_PREBOOT
+
+/* allow decompressing max. 4MB */
+#define CONFIG_VIDEO_BMP_GZIP
+/* this is not only used by cfb_console.c for the logo, but also in cmd_bmp.c */
+#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE (4*1024*1024)
+
/*
* Command definition
*/
* the NAND_CMD_LOCK_STATUS command, however the NFC of i.MX31 supports
* a software locking scheme.
*/
+#define CONFIG_CMD_BMP
#define CONFIG_BOOTDELAY 3
* currently a default setting for booting via script is implemented
* set user to login name and serverip to tftp host, define your
* boot behaviour in bootscript.loginname
+ *
+ * TT-01 board specific TFT setup (used by drivers/video/mx3fb.c)
+ *
+ * This set-up is for the L5F30947T04 by Epson, which is
+ * 800x480, 33MHz pixel clock, 60Hz vsync, 31.6kHz hsync
+ * sync must be set to: DI_D3_DRDY_SHARP_POL | DI_D3_CLK_POL
*/
#define CONFIG_EXTRA_ENV_SETTINGS \
- "bootcmd=dhcp bootscript.$(user); source\0"
+"videomode=epson\0" \
+"epson=video=ctfb:x:800,y:480,depth:16,mode:0,pclk:30076," \
+ "le:215,ri:1,up:32,lo:13,hs:7,vs:10,sync:100663296,vmode:0\0" \
+"bootcmd=dhcp bootscript.${user}; source\0"
#define CONFIG_BOOTP_SERVERIP /* tftp serverip not overruled by dhcp server */
#define CONFIG_BOOTP_SEND_HOSTNAME /* if env-var 'hostname' is set, send it */
/* Miscellaneous configurable options */
-#define CONFIG_HUSH_PARSER
-#define CONFIG_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
#define CONFIG_SYS_LONGHELP /* undef to save memory */
#define CONFIG_SYS_PROMPT "TT01> "
#define CONFIG_EXTRA_ENV_SETTINGS CONFIG_TAM3517_SETTINGS \
"bootcmd=run nandboot\0"
+/* SPL OS boot options */
+#define CONFIG_CMD_SPL
+#define CONFIG_CMD_SPL_WRITE_SIZE 0x400 /* 1024 byte */
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x00200000
+#define CONFIG_CMD_SPL_NAND_OFS (CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
+ 0x600000)
+#define CONFIG_SPL_OS_BOOT
+#define CONFIG_SPL_OS_BOOT_KEY 55
+
+#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_1 + 0x100)
+#define CONFIG_SPL_BOARD_INIT
+
#endif /* __CONFIG_H */
#include <asm/sizes.h>
#include "tegra2-common.h"
+/* Enable fdt support for Ventana. Flash the image in u-boot-dtb.bin */
+#define CONFIG_DEFAULT_DEVICE_TREE tegra2-seaboard
+#define CONFIG_OF_CONTROL
+#define CONFIG_OF_SEPARATE
+
/* High-level configuration options */
#define TEGRA2_SYSMEM "mem=384M@0M nvmem=128M@384M mem=512M@512M"
#define V_PROMPT "Tegra2 (Ventana) # "
* Use gpio 4 pin 25 as chip select for SPI flash
* This corresponds to gpio 121
*/
-#define CONFIG_SPI_FLASH_CS (1 | (121 << 8))
+#define CONFIG_SF_DEFAULT_CS (1 | (121 << 8))
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_ARCH_CPU_INIT
#define CONFIG_BOOTCOMMAND \
- "if mmc init && fatload mmc 0 0xa0000000 uboot.script ; then " \
+ "if mmc rescan && ext2load mmc 0 0xa0000000 boot/uboot.script ;"\
+ "then " \
"source 0xa0000000; " \
"else " \
"bootm 0x60000; " \
*/
#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
-#define CONFIG_PXA_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_PXA_MMC_GENERIC
#define CONFIG_SYS_MMC_BASE 0xF0000000
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
#endif
+/*
+ * SRAM Map
+ */
+#define PHYS_SRAM 0x5c000000 /* SRAM Bank #1 */
+#define PHYS_SRAM_SIZE 0x00040000 /* 256k */
+
/*
* DRAM Map
*/
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_DRAM_BASE
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
-#define CONFIG_SYS_INIT_SP_ADDR (GENERATED_GBL_DATA_SIZE + PHYS_SDRAM_1 + 2048)
+#define CONFIG_SYS_INIT_SP_ADDR (GENERATED_GBL_DATA_SIZE + PHYS_SRAM + 2048)
/*
* NOR FLASH
*/
enum fdt_compat_id {
COMPAT_UNKNOWN,
+ COMPAT_NVIDIA_TEGRA20_USB, /* Tegra2 USB port */
+ COMPAT_NVIDIA_TEGRA20_I2C, /* Tegra2 i2c */
+ COMPAT_NVIDIA_TEGRA20_DVC, /* Tegra2 dvc (really just i2c) */
COMPAT_COUNT,
};
+/* GPIOs are numbered from 0 */
+enum {
+ FDT_GPIO_NONE = -1U, /* an invalid GPIO used to end our list */
+
+ FDT_GPIO_ACTIVE_LOW = 1 << 0, /* input is active low (else high) */
+};
+
+/* This is the state of a GPIO pin as defined by the fdt */
+struct fdt_gpio_state {
+ const char *name; /* name of the fdt property defining this */
+ uint gpio; /* GPIO number, or FDT_GPIO_NONE if none */
+ u8 flags; /* FDT_GPIO_... flags */
+};
+
+/* This tells us whether a fdt_gpio_state record is valid or not */
+#define fdt_gpio_isvalid(x) ((x)->gpio != FDT_GPIO_NONE)
+
/**
* Find the next numbered alias for a peripheral. This is used to enumerate
* all the peripherals of a certain type.
int fdtdec_next_alias(const void *blob, const char *name,
enum fdt_compat_id id, int *upto);
+/**
+ * Find the next compatible node for a peripheral.
+ *
+ * Do the first call with node = 0. This function will return a pointer to
+ * the next compatible node. Next time you call this function, pass the
+ * value returned, and the next node will be provided.
+ *
+ * @param blob FDT blob to use
+ * @param node Start node for search
+ * @param id Compatible ID to look for (enum fdt_compat_id)
+ * @return offset of next compatible node, or -FDT_ERR_NOTFOUND if no more
+ */
+int fdtdec_next_compatible(const void *blob, int node,
+ enum fdt_compat_id id);
+
/**
* Look up an address property in a node and return it as an address.
* The property must hold either one address with no trailing data or
* Checks whether a node is enabled.
* This looks for a 'status' property. If this exists, then returns 1 if
* the status is 'ok' and 0 otherwise. If there is no status property,
- * it returns the default value.
+ * it returns 1 on the assumption that anything mentioned should be enabled
+ * by default.
*
* @param blob FDT blob
* @param node node to examine
- * @param default_val default value to return if no 'status' property exists
- * @return integer value 0/1, if found, or default_val if not
+ * @return integer value 0 (not enabled) or 1 (enabled)
*/
-int fdtdec_get_is_enabled(const void *blob, int node, int default_val);
+int fdtdec_get_is_enabled(const void *blob, int node);
/**
- * Checks whether we have a valid fdt available to control U-Boot, and panic
- * if not.
+ * Make sure we have a valid fdt available to control U-Boot.
+ *
+ * If not, a message is printed to the console if the console is ready.
+ *
+ * @return 0 if all ok, -1 if not
+ */
+int fdtdec_prepare_fdt(void);
+
+/**
+ * Checks that we have a valid fdt available to control U-Boot.
+
+ * However, if not then for the moment nothing is done, since this function
+ * is called too early to panic().
+ *
+ * @returns 0
*/
int fdtdec_check_fdt(void);
+
+/**
+ * Find the nodes for a peripheral and return a list of them in the correct
+ * order. This is used to enumerate all the peripherals of a certain type.
+ *
+ * To use this, optionally set up a /aliases node with alias properties for
+ * a peripheral. For example, for usb you could have:
+ *
+ * aliases {
+ * usb0 = "/ehci@c5008000";
+ * usb1 = "/ehci@c5000000";
+ * };
+ *
+ * Pass "usb" as the name to this function and will return a list of two
+ * nodes offsets: /ehci@c5008000 and ehci@c5000000.
+ *
+ * All nodes returned will match the compatible ID, as it is assumed that
+ * all peripherals use the same driver.
+ *
+ * If no alias node is found, then the node list will be returned in the
+ * order found in the fdt. If the aliases mention a node which doesn't
+ * exist, then this will be ignored. If nodes are found with no aliases,
+ * they will be added in any order.
+ *
+ * If there is a gap in the aliases, then this function return a 0 node at
+ * that position. The return value will also count these gaps.
+ *
+ * This function checks node properties and will not return nodes which are
+ * marked disabled (status = "disabled").
+ *
+ * @param blob FDT blob to use
+ * @param name Root name of alias to search for
+ * @param id Compatible ID to look for
+ * @param node_list Place to put list of found nodes
+ * @param maxcount Maximum number of nodes to find
+ * @return number of nodes found on success, FTD_ERR_... on error
+ */
+int fdtdec_find_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount);
+
+/*
+ * This function is similar to fdtdec_find_aliases_for_id() except that it
+ * adds to the node_list that is passed in. Any 0 elements are considered
+ * available for allocation - others are considered already used and are
+ * skipped.
+ *
+ * You can use this by calling fdtdec_find_aliases_for_id() with an
+ * uninitialised array, then setting the elements that are returned to -1,
+ * say, then calling this function, perhaps with a different compat id.
+ * Any elements you get back that are >0 are new nodes added by the call
+ * to this function.
+ *
+ * Note that if you have some nodes with aliases and some without, you are
+ * sailing close to the wind. The call to fdtdec_find_aliases_for_id() with
+ * one compat_id may fill in positions for which you have aliases defined
+ * for another compat_id. When you later call *this* function with the second
+ * compat_id, the alias positions may already be used. A debug warning may
+ * be generated in this case, but it is safest to define aliases for all
+ * nodes when you care about the ordering.
+ */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount);
+
+/*
+ * Get the name for a compatible ID
+ *
+ * @param id Compatible ID to look for
+ * @return compatible string for that id
+ */
+const char *fdtdec_get_compatible(enum fdt_compat_id id);
+
+/* Look up a phandle and follow it to its node. Then return the offset
+ * of that node.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @return node offset if found, -ve error code on error
+ */
+int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name);
+
+/**
+ * Look up a property in a node and return its contents in an integer
+ * array of given length. The property must have at least enough data for
+ * the array (4*count bytes). It may have more, but this will be ignored.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @param array array to fill with data
+ * @param count number of array elements
+ * @return 0 if ok, or -FDT_ERR_NOTFOUND if the property is not found,
+ * or -FDT_ERR_BADLAYOUT if not enough data
+ */
+int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
+ u32 *array, int count);
+
+/**
+ * Look up a boolean property in a node and return it.
+ *
+ * A boolean properly is true if present in the device tree and false if not
+ * present, regardless of its value.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @return 1 if the properly is present; 0 if it isn't present
+ */
+int fdtdec_get_bool(const void *blob, int node, const char *prop_name);
+
+/**
+ * Decode a single GPIOs from an FDT.
+ *
+ * If the property is not found, then the GPIO structure will still be
+ * initialised, with gpio set to FDT_GPIO_NONE. This makes it easy to
+ * provide optional GPIOs.
+ *
+ * @param blob FDT blob to use
+ * @param node Node to look at
+ * @param prop_name Node property name
+ * @param gpio gpio elements to fill from FDT
+ * @return 0 if ok, -FDT_ERR_NOTFOUND if the property is missing.
+ */
+int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
+ struct fdt_gpio_state *gpio);
+
+/**
+ * Set up a GPIO pin according to the provided gpio information. At present this
+ * just requests the GPIO.
+ *
+ * If the gpio is FDT_GPIO_NONE, no action is taken. This makes it easy to
+ * deal with optional GPIOs.
+ *
+ * @param gpio GPIO info to use for set up
+ * @return 0 if all ok or gpio was FDT_GPIO_NONE; -1 on error
+ */
+int fdtdec_setup_gpio(struct fdt_gpio_state *gpio);
#endif
} bootm_headers_t;
+extern bootm_headers_t images;
+
/*
* Some systems (for example LWMON) have very short watchdog periods;
* we must make sure to split long operations like memmove() or
#define NAND_CREATE_EMPTY_BBT 0x01000000
/* Options set by nand scan */
+/* bbt has already been read */
+#define NAND_BBT_SCANNED 0x40000000
/* Nand scan has allocated controller struct */
#define NAND_CONTROLLER_ALLOC 0x80000000
struct mtd_info;
-#if defined(CONFIG_MTD_ECC_SOFT)
-
-static inline int mtd_nand_has_ecc_soft(void) { return 1; }
-
/*
* Calculate 3 byte ECC code for 256 byte block
*/
*/
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-#else
-
-static inline int mtd_nand_has_ecc_soft(void) { return 0; }
-
-static inline int
-nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-{
- return -1;
-}
-
-static inline int
-nand_correct_data(struct mtd_info *mtd,
- u_char *dat,
- u_char *read_ecc,
- u_char *calc_ecc)
-{
- return -1;
-}
-
-#endif
-
#endif /* __MTD_NAND_ECC_H__ */
--- /dev/null
+#ifndef _MICREL_H
+
+#define MII_KSZ9021_EXT_COMMON_CTRL 0x100
+#define MII_KSZ9021_EXT_STRAP_STATUS 0x101
+#define MII_KSZ9021_EXT_OP_STRAP_OVERRIDE 0x102
+#define MII_KSZ9021_EXT_OP_STRAP_STATUS 0x103
+#define MII_KSZ9021_EXT_RGMII_CLOCK_SKEW 0x104
+#define MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW 0x105
+#define MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW 0x106
+#define MII_KSZ9021_EXT_ANALOG_TEST 0x107
+
+struct phy_device;
+int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val);
+int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum);
+
+#endif
#define BB_MII_DEVNAME "bb_miiphy"
struct bb_miiphy_bus {
- char name[NAMESIZE];
+ char name[16];
int (*init)(struct bb_miiphy_bus *bus);
int (*mdio_active)(struct bb_miiphy_bus *bus);
int (*mdio_tristate)(struct bb_miiphy_bus *bus);
int mmc_getcd(struct mmc *mmc);
#ifdef CONFIG_GENERIC_MMC
-int atmel_mci_init(void *regs);
#define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI)
struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
#else
#include <commproc.h>
#endif /* CONFIG_8xx */
+#include <asm/cache.h>
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
# define PKTBUFSRX 4
#endif
-#define PKTALIGN 32
+#define PKTALIGN ARCH_DMA_MINALIGN
/* IPv4 addresses are always 32 bits in size */
typedef u32 IPaddr_t;
*/
typedef void thand_f(void);
-#define NAMESIZE 16
-
enum eth_state_t {
ETH_STATE_INIT,
ETH_STATE_PASSIVE,
};
struct eth_device {
- char name[NAMESIZE];
+ char name[16];
unsigned char enetaddr[6];
int iobase;
int state;
extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */
extern int eth_register(struct eth_device* dev);/* Register network device */
+extern int eth_unregister(struct eth_device *dev);/* Remove network device */
extern void eth_try_another(int first_restart); /* Change the device */
extern void eth_set_current(void); /* set nterface to ethcur var */
extern struct eth_device *eth_get_dev(void); /* get the current device MAC */
/*
+ * Operating System Interface
+ *
+ * This provides access to useful OS routines for the sandbox architecture.
+ * They are kept in a separate file so we can include system headers.
+ *
* Copyright (c) 2011 The Chromium OS Authors.
* See file CREDITS for list of people who contributed to this
* project.
* MA 02111-1307 USA
*/
-/*
- * Operating System Interface
- *
- * This provides access to useful OS routines from the sandbox architecture
- */
+#ifndef __OS_H__
+#define __OS_H__
+
+struct sandbox_state;
/**
* Access to the OS read() system call
*/
ssize_t os_write(int fd, const void *buf, size_t count);
+/**
+ * Access to the OS lseek() system call
+ *
+ * \param fd File descriptor as returned by os_open()
+ * \param offset File offset (based on whence)
+ * \param whence Position offset is relative to (see below)
+ * \return new file offset
+ */
+off_t os_lseek(int fd, off_t offset, int whence);
+
+/* Defines for "whence" in os_lseek() */
+#define OS_SEEK_SET 0
+#define OS_SEEK_CUR 1
+#define OS_SEEK_END 2
+
/**
* Access to the OS open() system call
*
*/
int os_open(const char *pathname, int flags);
+#define OS_O_RDONLY 0
+#define OS_O_WRONLY 1
+#define OS_O_RDWR 2
+#define OS_O_MASK 3 /* Mask for read/write flags */
+#define OS_O_CREAT 0100
+
/**
* Access to the OS close() system call
*
*
* @param exit_code exit code for U-Boot
*/
-void os_exit(int exit_code);
+void os_exit(int exit_code) __attribute__((noreturn));
/**
* Put tty into raw mode to mimic serial console better
* \return A monotonic increasing time scaled in nano seconds
*/
u64 os_get_nsec(void);
+
+/**
+ * Parse arguments and update sandbox state.
+ *
+ * @param state Sandbox state to update
+ * @param argc Argument count
+ * @param argv Argument vector
+ * @return 0 if ok, and program should continue;
+ * 1 if ok, but program should stop;
+ * -1 on error: program should terminate.
+ */
+int os_parse_args(struct sandbox_state *state, int argc, char *argv[]);
+
+#endif
struct pci_region *mem,
struct pci_region *prefetch,
struct pci_region *io);
-int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
+extern void pciauto_prescan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus);
+extern void pciauto_postscan_setup_bridge(struct pci_controller *hose,
+ pci_dev_t dev, int sub_bus);
+extern void pciauto_config_init(struct pci_controller *hose);
+extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
#endif
-#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) \
- || defined(CONFIG_PXA_PCMCIA)
+#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
extern int check_ide_device(int slot);
#endif
int phy_shutdown(struct phy_device *phydev);
int phy_register(struct phy_driver *drv);
int genphy_config_aneg(struct phy_device *phydev);
+int genphy_restart_aneg(struct phy_device *phydev);
int genphy_update_link(struct phy_device *phydev);
int genphy_config(struct phy_device *phydev);
int genphy_startup(struct phy_device *phydev);
#include <post.h>
-#define NAMESIZE 16
-
struct serial_device {
- char name[NAMESIZE];
+ /* enough bytes to match alignment of following func pointer */
+ char name[16];
int (*init) (void);
int (*uninit) (void);
int transfer_len, struct devrequest *setup);
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval);
-void usb_event_poll(void);
/* Defines */
#define USB_UHCI_VEND_ID 0x8086
void *buffer, int transfer_len, int interval);
int usb_disable_asynch(int disable);
int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
-inline void wait_ms(unsigned long ms);
int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer,
int cfgno);
int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
struct usb_hub_descriptor desc;
};
+int usb_hub_probe(struct usb_device *dev, int ifnum);
+void usb_hub_reset(void);
+int hub_port_reset(struct usb_device *dev, int port,
+ unsigned short *portstat);
+
+struct usb_device *usb_alloc_new_device(void);
+int usb_new_device(struct usb_device *dev);
+
#endif /*_USB_H_ */
* MA 02111-1307 USA
*/
-#ifndef __SPR_UDC_H
-#define __SPR_UDC_H
+#ifndef __DW_UDC_H
+#define __DW_UDC_H
/*
* Defines for USBD
#define UDC_INT_PACKET_SIZE 64
#define UDC_OUT_ENDPOINT 2
#define UDC_BULK_PACKET_SIZE 64
+#define UDC_BULK_HS_PACKET_SIZE 512
#define UDC_IN_ENDPOINT 3
#define UDC_OUT_PACKET_SIZE 64
#define UDC_IN_PACKET_SIZE 64
void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
struct usb_endpoint_instance *endpoint);
-#endif /* __SPR_UDC_H */
+#endif /* __DW_UDC_H */
unsigned char usb_address;
- unsigned req_pending:1, req_std:1, req_config:1;
+ unsigned req_pending:1, req_std:1;
};
extern struct s3c_udc *the_controller;
u8 bNumConfigurations;
} __attribute__ ((packed));
+#if defined(CONFIG_USBD_HS)
+struct usb_qualifier_descriptor {
+ u8 bLength;
+ u8 bDescriptorType;
+
+ u16 bcdUSB;
+ u8 bDeviceClass;
+ u8 bDeviceSubClass;
+ u8 bDeviceProtocol;
+ u8 bMaxPacketSize0;
+ u8 bNumConfigurations;
+ u8 breserved;
+} __attribute__ ((packed));
+#endif
+
struct usb_string_descriptor {
u8 bLength;
u8 bDescriptorType; /* 0x03 */
#define USB_DT_INTERFACE 0x04
#define USB_DT_ENDPOINT 0x05
+#if defined(CONFIG_USBD_HS)
+#define USB_DT_QUAL 0x06
+#endif
+
#define USB_DT_HID (USB_TYPE_CLASS | 0x01)
#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
* USB Spec Release number
*/
+#if defined(CONFIG_USBD_HS)
+#define USB_BCD_VERSION 0x0200
+#else
#define USB_BCD_VERSION 0x0110
+#endif
/*
/* generic */
char *name;
struct usb_device_descriptor *device_descriptor; /* per device descriptor */
+#if defined(CONFIG_USBD_HS)
+ struct usb_qualifier_descriptor *qualifier_descriptor;
+#endif
void (*event) (struct usb_device_instance *device, usb_device_event_t event, int data);
struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *, int, int, int, int, int);
int usbd_device_endpoint_transfersize (struct usb_device_instance *, int, int, int, int, int);
struct usb_string_descriptor *usbd_get_string (u8);
-struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *, int);
+struct usb_device_descriptor *usbd_device_device_descriptor(struct
+ usb_device_instance *, int);
+#if defined(CONFIG_USBD_HS)
+/*
+ * is_usbd_high_speed routine needs to be defined by specific gadget driver
+ * It returns TRUE if device enumerates at High speed
+ * Retuns FALSE otherwise
+ */
+int is_usbd_high_speed(void);
+#endif
int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint);
void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad);
void usbd_tx_complete (struct usb_endpoint_instance *endpoint);
COBJS-y += display_options.o
COBJS-y += errno.o
COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o
+COBJS-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
COBJS-$(CONFIG_GZIP) += gunzip.o
COBJS-y += hashtable.o
COBJS-$(CONFIG_LMB) += lmb.o
COBJS-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += display_options.o
endif
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
+endif
COBJS-y += ctype.o
COBJS-y += div64.o
COBJS-y += string.o
#include <libfdt.h>
#include <fdtdec.h>
+/* we need the generic GPIO interface here */
+#include <asm-generic/gpio.h>
+
DECLARE_GLOBAL_DATA_PTR;
/*
*/
#define COMPAT(id, name) name
static const char * const compat_names[COMPAT_COUNT] = {
+ COMPAT(UNKNOWN, "<none>"),
+ COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
+ COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"),
+ COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"),
};
+const char *fdtdec_get_compatible(enum fdt_compat_id id)
+{
+ /* We allow reading of the 'unknown' ID for testing purposes */
+ assert(id >= 0 && id < COMPAT_COUNT);
+ return compat_names[id];
+}
+
/**
* Look in the FDT for an alias with the given name and return its node.
*
return default_val;
}
-int fdtdec_get_is_enabled(const void *blob, int node, int default_val)
+int fdtdec_get_is_enabled(const void *blob, int node)
{
const char *cell;
+ /*
+ * It should say "okay", so only allow that. Some fdts use "ok" but
+ * this is a bug. Please fix your device tree source file. See here
+ * for discussion:
+ *
+ * http://www.mail-archive.com/u-boot@lists.denx.de/msg71598.html
+ */
cell = fdt_getprop(blob, node, "status", NULL);
if (cell)
- return 0 == strcmp(cell, "ok");
- return default_val;
+ return 0 == strcmp(cell, "okay");
+ return 1;
}
enum fdt_compat_id fd_dec_lookup(const void *blob, int node)
/* snprintf() is not available */
assert(strlen(name) < MAX_STR_LEN);
sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto);
- (*upto)++;
node = find_alias_node(blob, str);
if (node < 0)
return node;
err = fdt_node_check_compatible(blob, node, compat_names[id]);
if (err < 0)
return err;
- return err ? -FDT_ERR_NOTFOUND : node;
+ if (err)
+ return -FDT_ERR_NOTFOUND;
+ (*upto)++;
+ return node;
+}
+
+int fdtdec_find_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount)
+{
+ memset(node_list, '\0', sizeof(*node_list) * maxcount);
+
+ return fdtdec_add_aliases_for_id(blob, name, id, node_list, maxcount);
+}
+
+/* TODO: Can we tighten this code up a little? */
+int fdtdec_add_aliases_for_id(const void *blob, const char *name,
+ enum fdt_compat_id id, int *node_list, int maxcount)
+{
+ int name_len = strlen(name);
+ int nodes[maxcount];
+ int num_found = 0;
+ int offset, node;
+ int alias_node;
+ int count;
+ int i, j;
+
+ /* find the alias node if present */
+ alias_node = fdt_path_offset(blob, "/aliases");
+
+ /*
+ * start with nothing, and we can assume that the root node can't
+ * match
+ */
+ memset(nodes, '\0', sizeof(nodes));
+
+ /* First find all the compatible nodes */
+ for (node = count = 0; node >= 0 && count < maxcount;) {
+ node = fdtdec_next_compatible(blob, node, id);
+ if (node >= 0)
+ nodes[count++] = node;
+ }
+ if (node >= 0)
+ debug("%s: warning: maxcount exceeded with alias '%s'\n",
+ __func__, name);
+
+ /* Now find all the aliases */
+ for (offset = fdt_first_property_offset(blob, alias_node);
+ offset > 0;
+ offset = fdt_next_property_offset(blob, offset)) {
+ const struct fdt_property *prop;
+ const char *path;
+ int number;
+ int found;
+
+ node = 0;
+ prop = fdt_get_property_by_offset(blob, offset, NULL);
+ path = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
+ if (prop->len && 0 == strncmp(path, name, name_len))
+ node = fdt_path_offset(blob, prop->data);
+ if (node <= 0)
+ continue;
+
+ /* Get the alias number */
+ number = simple_strtoul(path + name_len, NULL, 10);
+ if (number < 0 || number >= maxcount) {
+ debug("%s: warning: alias '%s' is out of range\n",
+ __func__, path);
+ continue;
+ }
+
+ /* Make sure the node we found is actually in our list! */
+ found = -1;
+ for (j = 0; j < count; j++)
+ if (nodes[j] == node) {
+ found = j;
+ break;
+ }
+
+ if (found == -1) {
+ debug("%s: warning: alias '%s' points to a node "
+ "'%s' that is missing or is not compatible "
+ " with '%s'\n", __func__, path,
+ fdt_get_name(blob, node, NULL),
+ compat_names[id]);
+ continue;
+ }
+
+ /*
+ * Add this node to our list in the right place, and mark
+ * it as done.
+ */
+ if (fdtdec_get_is_enabled(blob, node)) {
+ if (node_list[number]) {
+ debug("%s: warning: alias '%s' requires that "
+ "a node be placed in the list in a "
+ "position which is already filled by "
+ "node '%s'\n", __func__, path,
+ fdt_get_name(blob, node, NULL));
+ continue;
+ }
+ node_list[number] = node;
+ if (number >= num_found)
+ num_found = number + 1;
+ }
+ nodes[found] = 0;
+ }
+
+ /* Add any nodes not mentioned by an alias */
+ for (i = j = 0; i < maxcount; i++) {
+ if (!node_list[i]) {
+ for (; j < maxcount; j++)
+ if (nodes[j] &&
+ fdtdec_get_is_enabled(blob, nodes[j]))
+ break;
+
+ /* Have we run out of nodes to add? */
+ if (j == maxcount)
+ break;
+
+ assert(!node_list[i]);
+ node_list[i] = nodes[j++];
+ if (i >= num_found)
+ num_found = i + 1;
+ }
+ }
+
+ return num_found;
+}
+
+int fdtdec_check_fdt(void)
+{
+ /*
+ * We must have an FDT, but we cannot panic() yet since the console
+ * is not ready. So for now, just assert(). Boards which need an early
+ * FDT (prior to console ready) will need to make their own
+ * arrangements and do their own checks.
+ */
+ assert(!fdtdec_prepare_fdt());
+ return 0;
}
/*
* point if the architecture board.c files merge this will make more sense.
* Even now, it is common code.
*/
-int fdtdec_check_fdt(void)
+int fdtdec_prepare_fdt(void)
+{
+ if (((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) {
+ printf("No valid FDT found - please append one to U-Boot "
+ "binary, use u-boot-dtb.bin or define "
+ "CONFIG_OF_EMBED\n");
+ return -1;
+ }
+ return 0;
+}
+
+int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name)
+{
+ const u32 *phandle;
+ int lookup;
+
+ phandle = fdt_getprop(blob, node, prop_name, NULL);
+ if (!phandle)
+ return -FDT_ERR_NOTFOUND;
+
+ lookup = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*phandle));
+ return lookup;
+}
+
+/**
+ * Look up a property in a node and check that it has a minimum length.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @param min_len minimum property length in bytes
+ * @param err 0 if ok, or -FDT_ERR_NOTFOUND if the property is not
+ found, or -FDT_ERR_BADLAYOUT if not enough data
+ * @return pointer to cell, which is only valid if err == 0
+ */
+static const void *get_prop_check_min_len(const void *blob, int node,
+ const char *prop_name, int min_len, int *err)
{
- /* We must have an fdt */
- if (fdt_check_header(gd->fdt_blob))
- panic("No valid fdt found - please append one to U-Boot\n"
- "binary or define CONFIG_OF_EMBED\n");
+ const void *cell;
+ int len;
+
+ debug("%s: %s\n", __func__, prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ if (!cell)
+ *err = -FDT_ERR_NOTFOUND;
+ else if (len < min_len)
+ *err = -FDT_ERR_BADLAYOUT;
+ else
+ *err = 0;
+ return cell;
+}
+
+int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
+ u32 *array, int count)
+{
+ const u32 *cell;
+ int i, err = 0;
+
+ debug("%s: %s\n", __func__, prop_name);
+ cell = get_prop_check_min_len(blob, node, prop_name,
+ sizeof(u32) * count, &err);
+ if (!err) {
+ for (i = 0; i < count; i++)
+ array[i] = fdt32_to_cpu(cell[i]);
+ }
+ return err;
+}
+
+int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
+{
+ const s32 *cell;
+ int len;
+
+ debug("%s: %s\n", __func__, prop_name);
+ cell = fdt_getprop(blob, node, prop_name, &len);
+ return cell != NULL;
+}
+
+/**
+ * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
+ * terminating item.
+ *
+ * @param blob FDT blob to use
+ * @param node Node to look at
+ * @param prop_name Node property name
+ * @param gpio Array of gpio elements to fill from FDT. This will be
+ * untouched if either 0 or an error is returned
+ * @param max_count Maximum number of elements allowed
+ * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
+ * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
+ */
+static int fdtdec_decode_gpios(const void *blob, int node,
+ const char *prop_name, struct fdt_gpio_state *gpio,
+ int max_count)
+{
+ const struct fdt_property *prop;
+ const u32 *cell;
+ const char *name;
+ int len, i;
+
+ debug("%s: %s\n", __func__, prop_name);
+ assert(max_count > 0);
+ prop = fdt_get_property(blob, node, prop_name, &len);
+ if (!prop) {
+ debug("FDT: %s: property '%s' missing\n", __func__, prop_name);
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ /* We will use the name to tag the GPIO */
+ name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
+ cell = (u32 *)prop->data;
+ len /= sizeof(u32) * 3; /* 3 cells per GPIO record */
+ if (len > max_count) {
+ debug("FDT: %s: too many GPIOs / cells for "
+ "property '%s'\n", __func__, prop_name);
+ return -FDT_ERR_BADLAYOUT;
+ }
+
+ /* Read out the GPIO data from the cells */
+ for (i = 0; i < len; i++, cell += 3) {
+ gpio[i].gpio = fdt32_to_cpu(cell[1]);
+ gpio[i].flags = fdt32_to_cpu(cell[2]);
+ gpio[i].name = name;
+ }
+
+ return len;
+}
+
+int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
+ struct fdt_gpio_state *gpio)
+{
+ int err;
+
+ debug("%s: %s\n", __func__, prop_name);
+ gpio->gpio = FDT_GPIO_NONE;
+ gpio->name = NULL;
+ err = fdtdec_decode_gpios(blob, node, prop_name, gpio, 1);
+ return err == 1 ? 0 : err;
+}
+
+int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
+{
+ /*
+ * Return success if there is no GPIO defined. This is used for
+ * optional GPIOs)
+ */
+ if (!fdt_gpio_isvalid(gpio))
+ return 0;
+
+ if (gpio_request(gpio->gpio, gpio->name))
+ return -1;
return 0;
}
--- /dev/null
+/*
+ * Some very basic tests for fdtdec, accessed through test_fdtdec command.
+ * They are easiest to use with sandbox.
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <os.h>
+
+/* The size of our test fdt blob */
+#define FDT_SIZE (16 * 1024)
+
+/**
+ * Check if an operation failed, and if so, print an error
+ *
+ * @param oper_name Name of operation
+ * @param err Error code to check
+ *
+ * @return 0 if ok, -1 if there was an error
+ */
+static int fdt_checkerr(const char *oper_name, int err)
+{
+ if (err) {
+ printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err));
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check the result of an operation and if incorrect, print an error
+ *
+ * @param oper_name Name of operation
+ * @param expected Expected value
+ * @param value Actual value
+ *
+ * @return 0 if ok, -1 if there was an error
+ */
+static int checkval(const char *oper_name, int expected, int value)
+{
+ if (expected != value) {
+ printf("%s: %s: expected %d, but returned %d\n", __func__,
+ oper_name, expected, value);
+ return -1;
+ }
+
+ return 0;
+}
+
+#define CHECK(op) if (fdt_checkerr(#op, op)) return -1
+#define CHECKVAL(op, expected) \
+ if (checkval(#op, expected, op)) \
+ return -1
+#define CHECKOK(op) CHECKVAL(op, 0)
+
+/* maximum number of nodes / aliases to generate */
+#define MAX_NODES 20
+
+/*
+ * Make a test fdt
+ *
+ * @param fdt Device tree pointer
+ * @param size Size of device tree blob
+ * @param aliases Specifies alias assignments. Format is a list of items
+ * separated by space. Items are #a where
+ * # is the alias number
+ * a is the node to point to
+ * @param nodes Specifies nodes to generate (a=0, b=1), upper case
+ * means to create a disabled node
+ */
+static int make_fdt(void *fdt, int size, const char *aliases,
+ const char *nodes)
+{
+ char name[20], value[20];
+ const char *s;
+ int fd;
+
+ CHECK(fdt_create(fdt, size));
+ CHECK(fdt_finish_reservemap(fdt));
+ CHECK(fdt_begin_node(fdt, ""));
+
+ CHECK(fdt_begin_node(fdt, "aliases"));
+ for (s = aliases; *s;) {
+ sprintf(name, "i2c%c", *s);
+ sprintf(value, "/i2c%d@0", s[1] - 'a');
+ CHECK(fdt_property_string(fdt, name, value));
+ s += 2 + (s[2] != '\0');
+ }
+ CHECK(fdt_end_node(fdt));
+
+ for (s = nodes; *s; s++) {
+ sprintf(value, "i2c%d@0", (*s & 0xdf) - 'A');
+ CHECK(fdt_begin_node(fdt, value));
+ CHECK(fdt_property_string(fdt, "compatible",
+ fdtdec_get_compatible(COMPAT_UNKNOWN)));
+ if (*s <= 'Z')
+ CHECK(fdt_property_string(fdt, "status", "disabled"));
+ CHECK(fdt_end_node(fdt));
+ }
+
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_finish(fdt));
+ CHECK(fdt_pack(fdt));
+#if defined(DEBUG) && defined(CONFIG_SANDBOX)
+ fd = os_open("/tmp/fdtdec-text.dtb", OS_O_CREAT | OS_O_WRONLY);
+ if (fd == -1) {
+ printf("Could not open .dtb file to write\n");
+ return -1;
+ }
+ os_write(fd, fdt, size);
+ os_close(fd);
+#endif
+ return 0;
+}
+
+static int run_test(const char *aliases, const char *nodes, const char *expect)
+{
+ int list[MAX_NODES];
+ const char *s;
+ void *blob;
+ int i;
+
+ blob = malloc(FDT_SIZE);
+ if (!blob) {
+ printf("%s: out of memory\n", __func__);
+ return 1;
+ }
+
+ printf("aliases=%s, nodes=%s, expect=%s: ", aliases, nodes, expect);
+ CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0);
+ CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c",
+ COMPAT_UNKNOWN,
+ list, ARRAY_SIZE(list)), strlen(expect));
+
+ /* Check we got the right ones */
+ for (i = 0, s = expect; *s; s++, i++) {
+ int want = *s;
+ const char *name;
+ int got = ' ';
+
+ name = list[i] ? fdt_get_name(blob, list[i], NULL) : NULL;
+ if (name)
+ got = name[3] + 'a' - '0';
+
+ if (got != want) {
+ printf("Position %d: Expected '%c', got '%c' ('%s')\n",
+ i, want, got, name);
+ return 1;
+ }
+ }
+
+ printf("pass\n");
+ return 0;
+}
+
+static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ /* basic tests */
+ CHECKOK(run_test("", "", ""));
+ CHECKOK(run_test("1e 3d", "", ""));
+
+ /*
+ * 'a' represents 0, 'b' represents 1, etc.
+ * The first character is the alias number, the second is the node
+ * number. So the params mean:
+ * 0a 1b : point alias 0 to node 0 (a), alias 1 to node 1(b)
+ * ab : to create nodes 0 and 1 (a and b)
+ * ab : we expect the function to return two nodes, in
+ * the order 0, 1
+ */
+ CHECKOK(run_test("0a 1b", "ab", "ab"));
+
+ CHECKOK(run_test("0a 1c", "ab", "ab"));
+ CHECKOK(run_test("1c", "ab", "ab"));
+ CHECKOK(run_test("1b", "ab", "ab"));
+ CHECKOK(run_test("0b", "ab", "ba"));
+ CHECKOK(run_test("0b 2d", "dbc", "bcd"));
+ CHECKOK(run_test("0d 3a 1c 2b", "dbac", "dcba"));
+
+ /* things with holes */
+ CHECKOK(run_test("1b 3d", "dbc", "cb d"));
+ CHECKOK(run_test("1e 3d", "dbc", "bc d"));
+
+ /* no aliases */
+ CHECKOK(run_test("", "dbac", "dbac"));
+
+ /* disabled nodes */
+ CHECKOK(run_test("0d 3a 1c 2b", "dBac", "dc a"));
+ CHECKOK(run_test("0b 2d", "DBc", "c"));
+ CHECKOK(run_test("0b 4d 2c", "DBc", " c"));
+
+ /* conflicting aliases - first one gets it */
+ CHECKOK(run_test("2a 1a 0a", "a", " a"));
+ CHECKOK(run_test("0a 1a 2a", "a", "a"));
+
+ printf("Test passed\n");
+ return 0;
+}
+
+U_BOOT_CMD(
+ test_fdtdec, 3, 1, do_test_fdtdec,
+ "test_fdtdec",
+ "Run tests for fdtdec library");
}
}
- debug ("LZMA: Uncompresed size............ 0x%x\n", outSizeFull);
- debug ("LZMA: Compresed size.............. 0x%x\n", compressedSize);
+ debug("LZMA: Uncompresed size............ 0x%zx\n", outSizeFull);
+ debug("LZMA: Compresed size.............. 0x%zx\n", compressedSize);
g_Alloc.Alloc = SzAlloc;
g_Alloc.Free = SzFree;
while (msec--)
udelay(1000);
}
+
+ulong __timer_get_boot_us(void)
+{
+ static ulong base_time;
+
+ /*
+ * We can't implement this properly. Return 0 on the first call and
+ * larger values after that.
+ */
+ if (base_time)
+ return get_timer(base_time) * 1000;
+ base_time = get_timer(0);
+ return 0;
+}
+
+ulong timer_get_boot_us(void)
+ __attribute__((weak, alias("__timer_get_boot_us")));
BootpVendorProcess((uchar *)&bp->bp_vend[4], len);
NetSetTimeout(0, (thand_f *)0);
+ bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
debug("Got good BOOTP\n");
Bootp_t *bp;
int ext_len, pktlen, iplen;
+ bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
#if defined(CONFIG_CMD_DHCP)
dhcp_state = INIT;
#endif
BootpCopyNetParams(bp); /* Store net params from reply */
dhcp_state = BOUND;
printf ("DHCP client bound to address %pI4\n", &NetOurIP);
+ bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
+ "bootp_stop");
net_auto_load();
return;
int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
-extern int mv6436x_eth_initialize(bd_t *);
-extern int mv6446x_eth_initialize(bd_t *);
-
#ifdef CONFIG_API
extern void (*push_packet)(volatile void *, int);
struct eth_device *d;
static int index = 0;
- assert(strlen(dev->name) < NAMESIZE);
+ assert(strlen(dev->name) < sizeof(dev->name));
if (!eth_devices) {
eth_current = eth_devices = dev;
return 0;
}
+int eth_unregister(struct eth_device *dev)
+{
+ struct eth_device *cur;
+
+ /* No device */
+ if (!eth_devices)
+ return -1;
+
+ for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
+ cur = cur->next)
+ ;
+
+ /* Device not found */
+ if (cur->next != dev)
+ return -1;
+
+ cur->next = dev->next;
+
+ if (eth_devices == dev)
+ eth_devices = dev->next == eth_devices ? NULL : dev->next;
+
+ if (eth_current == dev) {
+ eth_current = eth_devices;
+ eth_current_changed();
+ }
+
+ return 0;
+}
+
int eth_initialize(bd_t *bis)
{
int num_devices = 0;
eth_devices = NULL;
eth_current = NULL;
- show_boot_progress (64);
+ bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_init();
#endif
} else
printf("Net Initialization Skipped\n");
-#if defined(CONFIG_DB64360) || defined(CONFIG_CPCI750)
- mv6436x_eth_initialize(bis);
-#endif
-#if defined(CONFIG_DB64460) || defined(CONFIG_P3Mx)
- mv6446x_eth_initialize(bis);
-#endif
if (!eth_devices) {
puts ("No ethernet found.\n");
- show_boot_progress (-64);
+ bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
} else {
struct eth_device *dev = eth_devices;
char *ethprime = getenv ("ethprime");
- show_boot_progress (65);
+ bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
do {
if (dev->index)
puts (", ");
NetArpWaitTxPacketSize = 0;
}
+ bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
eth_halt();
eth_set_current();
if (eth_init(bd) < 0) {
SPLIB-$(CONFIG_HAS_POST) = drivers/libpostdrivers.o
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d lib_$(ARCH) ]; then echo \
"lib_$(ARCH)/libpost$(ARCH).o"; fi)
-SPLIB-$(CONFIG_SYS_POST_FPU) += $(shell if [ -d lib_$(ARCH)/fpu ]; then echo \
+SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d lib_$(ARCH)/fpu ]; then echo \
"lib_$(ARCH)/fpu/libpost$(ARCH)fpu.o"; fi)
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d cpu/$(CPU) ]; then echo \
"cpu/$(CPU)/libpost$(CPU).o"; fi)
post_log("PASSED\n");
else {
post_log("FAILED\n");
- show_boot_progress(-31);
+ bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
}
}
}
} else {
if ((*test->test)(flags) != 0) {
post_log("FAILED\n");
- show_boot_progress(-32);
+ bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
show_post_progress(i, POST_AFTER, POST_FAILED);
if (test_flags & POST_CRITICAL)
gd->flags |= GD_FLG_POSTFAIL;
*/
unsigned long post_time_ms(unsigned long base)
{
-#if defined(CONFIG_PPC) || defined(CONFIG_BLACKFIN) || \
- (defined(CONFIG_ARM) && !defined(CONFIG_KIRKWOOD))
+#if defined(CONFIG_PPC) || defined(CONFIG_BLACKFIN) || defined(CONFIG_ARM)
return (unsigned long)lldiv(get_ticks(), get_tbclk() / CONFIG_SYS_HZ)
- base;
#else
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-spl.lds
endif
+ifeq ($(wildcard $(LDSCRIPT)),)
+ LDSCRIPT := $(TOPDIR)/arch/$(ARCH)/cpu/u-boot.lds
+endif
ifeq ($(wildcard $(LDSCRIPT)),)
$(error could not find linker script)
endif
LDPPFLAGS += \
-include $(TOPDIR)/include/u-boot/u-boot.lds.h \
-include $(OBJTREE)/include/config.h \
+ -DCPUDIR=$(CPUDIR) \
$(shell $(LD) --version | \
sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
--- /dev/null
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <joern@lazybastard.org>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+# s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
+# Mips port by Juan Quintela <quintela@mandrakesoft.com>
+# IA64 port via Andreas Dilger
+# Arm port by Holger Schurig
+# sh64 port by Paul Mundt
+# Random bits by Matt Mackall <mpm@selenic.com>
+# M68k port by Geert Uytterhoeven and Andreas Schwab
+# AVR32 port by Haavard Skinnemoen (Atmel)
+# PARISC port by Kyle McMartin <kyle@parisc-linux.org>
+# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
+#
+# Usage:
+# objdump -d vmlinux | scripts/checkstack.pl [arch]
+#
+# TODO : Port to all architectures (one regex per arch)
+
+use strict;
+
+# check for arch
+#
+# $re is used for two matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the size of the stack growth
+#
+# $dre is similar, but for dynamic stack redutions:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the dynamic amount of the stack growth
+#
+# use anything else and feel the pain ;)
+my (@stack, $re, $dre, $x, $xs);
+{
+ my $arch = shift;
+ if ($arch eq "") {
+ $arch = `uname -m`;
+ chomp($arch);
+ }
+
+ $x = "[0-9a-f]"; # hex character
+ $xs = "[0-9a-f ]"; # hex character or space
+ if ($arch eq 'arm') {
+ #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
+ $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'avr32') {
+ #8000008a: 20 1d sub sp,4
+ #80000ca8: fa cd 05 b0 sub sp,sp,1456
+ $re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
+ } elsif ($arch =~ /^i[3456]86$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
+ $dre = qr/^.*[as][du][db] (%.*),\%esp$/o;
+ } elsif ($arch eq 'x86_64') {
+ # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp
+ $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%rsp$/o;
+ $dre = qr/^.*[as][du][db] (\%.*),\%rsp$/o;
+ } elsif ($arch eq 'ia64') {
+ #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12
+ $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
+ } elsif ($arch eq 'm68k') {
+ # 2b6c: 4e56 fb70 linkw %fp,#-1168
+ # 1df770: defc ffe4 addaw #-28,%sp
+ $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
+ } elsif ($arch eq 'mips64') {
+ #8800402c: 67bdfff0 daddiu sp,sp,-16
+ $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'mips') {
+ #88003254: 27bdffe0 addiu sp,sp,-32
+ $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
+ $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
+ } elsif ($arch eq 'ppc') {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
+ } elsif ($arch eq 'ppc64') {
+ #XXX
+ $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o;
+ } elsif ($arch eq 'powerpc') {
+ $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
+ } elsif ($arch =~ /^s390x?$/) {
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ # or
+ # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15)
+ $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
+ (?:\(\%r15\))?$/ox;
+ } elsif ($arch =~ /^sh64$/) {
+ #XXX: we only check for the immediate case presently,
+ # though we will want to check for the movi/sub
+ # pair for larger users. -- PFM.
+ #a00048e0: d4fc40f0 addi.l r15,-240,r15
+ $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
+ } elsif ($arch =~ /^blackfin$/) {
+ # 0: 00 e8 38 01 LINK 0x4e0;
+ $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o;
+ } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
+ # f0019d10: 9d e3 bf 90 save %sp, -112, %sp
+ $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
+ } else {
+ print("wrong or unknown architecture \"$arch\"\n");
+ exit
+ }
+}
+
+#
+# main()
+#
+my $funcre = qr/^$x* <(.*)>:$/;
+my ($func, $file, $lastslash);
+
+while (my $line = <STDIN>) {
+ if ($line =~ m/$funcre/) {
+ $func = $1;
+ }
+ elsif ($line =~ m/(.*):\s*file format/) {
+ $file = $1;
+ $file =~ s/\.ko//;
+ $lastslash = rindex($file, "/");
+ if ($lastslash != -1) {
+ $file = substr($file, $lastslash + 1);
+ }
+ }
+ elsif ($line =~ m/$re/) {
+ my $size = $1;
+ $size = hex($size) if ($size =~ /^0x/);
+
+ if ($size > 0xf0000000) {
+ $size = - $size;
+ $size += 0x80000000;
+ $size += 0x80000000;
+ }
+ next if ($size > 0x10000000);
+
+ next if $line !~ m/^($xs*)/;
+ my $addr = $1;
+ $addr =~ s/ /0/g;
+ $addr = "0x$addr";
+
+ my $intro = "$addr $func [$file]:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ next if ($size < 100);
+ push @stack, "$intro$size\n";
+ }
+ elsif (defined $dre && $line =~ m/$dre/) {
+ my $size = "Dynamic ($1)";
+
+ next if $line !~ m/^($xs*)/;
+ my $addr = $1;
+ $addr =~ s/ /0/g;
+ $addr = "0x$addr";
+
+ my $intro = "$addr $func [$file]:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ push @stack, "$intro$size\n";
+ }
+}
+
+# Sort output by size (last field)
+print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
uint32_t base_offset;
- /* Set default offset */
- imxhdr->flash_offset = FLASH_OFFSET_STANDARD;
+ /* Exit if there is no BOOT_FROM field specifying the flash_offset */
+ if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+ fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
+ params->imagename);
+ exit(EXIT_FAILURE);
+ }
/* Set magic number */
fhdr_v1->app_code_barker = APP_CODE_BARKER;
imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
- /* Set default offset */
- imxhdr->flash_offset = FLASH_OFFSET_STANDARD;
+ /* Exit if there is no BOOT_FROM field specifying the flash_offset */
+ if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+ fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
+ params->imagename);
+ exit(EXIT_FAILURE);
+ }
/* Set magic number */
fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
* set up function ptr group to V1 by default.
*/
imximage_version = IMXIMAGE_V1;
+ /* Be able to detect if the cfg file has no BOOT_FROM tag */
+ imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
set_hdr_func(imxhdr);
/* Parse dcd configuration file */
#define HEADER_OFFSET 0x400
#define CMD_DATA_STR "DATA"
+#define FLASH_OFFSET_UNDEFINED 0xFFFFFFFF
#define FLASH_OFFSET_STANDARD 0x400
#define FLASH_OFFSET_NAND FLASH_OFFSET_STANDARD
#define FLASH_OFFSET_SD FLASH_OFFSET_STANDARD
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
-#include <compiler.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mman.h>
+#include "compiler.h"
#include <u-boot/crc.h>
#include <version.h>
static void usage(const char *exec_name)
{
- fprintf(stderr, "%s [-h] [-r] [-b] [-p <byte>] "
- "-s <environment partition size> -o <output> <input file>\n"
+ fprintf(stderr, "%s [-h] [-r] [-b] [-p <byte>] -s <environment partition size> -o <output> <input file>\n"
"\n"
- "This tool takes a key=value input file (same as would a "
- "`printenv' show) and generates the corresponding environment "
- "image, ready to be flashed.\n"
+ "This tool takes a key=value input file (same as would a `printenv' show) and generates the corresponding environment image, ready to be flashed.\n"
"\n"
"\tThe input file is in format:\n"
"\t\tkey1=value1\n"
"\t\t...\n"
"\t-r : the environment has multiple copies in flash\n"
"\t-b : the target is big endian (default is little endian)\n"
- "\t-p <byte> : fill the image with <byte> bytes instead of "
- "0xff bytes\n"
+ "\t-p <byte> : fill the image with <byte> bytes instead of 0xff bytes\n"
"\t-V : print version information and exit\n"
"\n"
"If the input file is \"-\", data is read from standard input\n",
exec_name);
}
+long int xstrtol(const char *s)
+{
+ long int tmp;
+
+ errno = 0;
+ tmp = strtol(s, NULL, 0);
+ if (!errno)
+ return tmp;
+
+ if (errno == ERANGE)
+ fprintf(stderr, "Bad integer format: %s\n", s);
+ else
+ fprintf(stderr, "Error while parsing %s: %s\n", s,
+ strerror(errno));
+
+ exit(EXIT_FAILURE);
+}
+
int main(int argc, char **argv)
{
uint32_t crc, targetendian_crc;
while ((option = getopt(argc, argv, ":s:o:rbp:hV")) != -1) {
switch (option) {
case 's':
- datasize = strtol(optarg, NULL, 0);
+ datasize = xstrtol(optarg);
break;
case 'o':
bin_filename = strdup(optarg);
if (!bin_filename) {
- fprintf(stderr, "Can't strdup() the output "
- "filename\n");
+ fprintf(stderr, "Can't strdup() the output filename\n");
return EXIT_FAILURE;
}
break;
bigendian = 1;
break;
case 'p':
- padbyte = strtol(optarg, NULL, 0);
+ padbyte = xstrtol(optarg);
break;
case 'h':
usage(prg);
case ':':
fprintf(stderr, "Missing argument for option -%c\n",
optopt);
- usage(argv[0]);
+ usage(prg);
return EXIT_FAILURE;
default:
fprintf(stderr, "Wrong option -%c\n", optopt);
/* Check datasize and allocate the data */
if (datasize == 0) {
- fprintf(stderr,
- "Please specify the size of the environment "
- "partition.\n");
+ fprintf(stderr, "Please specify the size of the environment partition.\n");
usage(prg);
return EXIT_FAILURE;
}
dataptr = malloc(datasize * sizeof(*dataptr));
if (!dataptr) {
- fprintf(stderr, "Can't alloc dataptr.\n");
+ fprintf(stderr, "Can't alloc %d bytes for dataptr.\n",
+ datasize);
return EXIT_FAILURE;
}
/*
* envptr points to the beginning of the actual environment (after the
- * crc and possible `redundant' bit
+ * crc and possible `redundant' byte
*/
envsize = datasize - (CRC_SIZE + redundant);
envptr = dataptr + CRC_SIZE + redundant;
memset(envptr, padbyte, envsize);
/* Open the input file ... */
- if (optind >= argc) {
- fprintf(stderr, "Please specify an input filename\n");
- return EXIT_FAILURE;
- }
-
- txt_filename = argv[optind];
- if (strcmp(txt_filename, "-") == 0) {
+ if (optind >= argc || strcmp(argv[optind], "-") == 0) {
int readbytes = 0;
- int readlen = sizeof(*envptr) * 2048;
+ int readlen = sizeof(*envptr) * 4096;
txt_fd = STDIN_FILENO;
do {
filebuf = realloc(filebuf, readlen);
+ if (!filebuf) {
+ fprintf(stderr, "Can't realloc memory for the input file buffer\n");
+ return EXIT_FAILURE;
+ }
readbytes = read(txt_fd, filebuf + filesize, readlen);
+ if (errno) {
+ fprintf(stderr, "Error while reading stdin: %s\n",
+ strerror(errno));
+ return EXIT_FAILURE;
+ }
filesize += readbytes;
} while (readbytes == readlen);
} else {
+ txt_filename = argv[optind];
txt_fd = open(txt_filename, O_RDONLY);
if (txt_fd == -1) {
fprintf(stderr, "Can't open \"%s\": %s\n",
/* ... and check it */
ret = fstat(txt_fd, &txt_file_stat);
if (ret == -1) {
- fprintf(stderr, "Can't stat() on \"%s\": "
- "%s\n", txt_filename, strerror(errno));
+ fprintf(stderr, "Can't stat() on \"%s\": %s\n",
+ txt_filename, strerror(errno));
return EXIT_FAILURE;
}
filesize = txt_file_stat.st_size;
- /* Read the raw input file and transform it */
- filebuf = malloc(sizeof(*envptr) * filesize);
- ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
- if (ret != sizeof(*envptr) * filesize) {
- fprintf(stderr, "Can't read the whole input file\n");
- return EXIT_FAILURE;
+
+ filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
+ MAP_PRIVATE, txt_fd, 0);
+ if (filebuf == MAP_FAILED) {
+ fprintf(stderr, "mmap (%ld bytes) failed: %s\n",
+ sizeof(*envptr) * filesize,
+ strerror(errno));
+ fprintf(stderr, "Falling back to read()\n");
+
+ filebuf = malloc(sizeof(*envptr) * filesize);
+ ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
+ if (ret != sizeof(*envptr) * filesize) {
+ fprintf(stderr, "Can't read the whole input file (%ld bytes): %s\n",
+ sizeof(*envptr) * filesize,
+ strerror(errno));
+
+ return EXIT_FAILURE;
+ }
}
ret = close(txt_fd);
}
- /*
- * The right test to do is "=>" (not ">") because of the additional
- * ending \0. See below.
- */
- if (filesize >= envsize) {
- fprintf(stderr, "The input file is larger than the "
- "environment partition size\n");
+ /* The +1 is for the additionnal ending \0. See below. */
+ if (filesize + 1 > envsize) {
+ fprintf(stderr, "The input file is larger than the environment partition size\n");
return EXIT_FAILURE;
}
/* End of a variable */
envptr[ep++] = '\0';
}
- } else if (filebuf[fp] == '#') {
- if (fp != 0 && filebuf[fp-1] == '\n') {
- /* This line is a comment, let's skip it */
- while (fp < txt_file_stat.st_size && fp++ &&
- filebuf[fp] != '\n');
- } else {
- envptr[ep++] = filebuf[fp];
- }
} else {
envptr[ep++] = filebuf[fp];
}
* check the env size again to make sure we have room for two \0
*/
if (ep >= envsize) {
- fprintf(stderr, "The environment file is too large for "
- "the target environment storage\n");
+ fprintf(stderr, "The environment file is too large for the target environment storage\n");
return EXIT_FAILURE;
}
envptr[ep] = '\0';
crc = crc32(0, envptr, envsize);
targetendian_crc = bigendian ? cpu_to_be32(crc) : cpu_to_le32(crc);
- memcpy(dataptr, &targetendian_crc, sizeof(uint32_t));
+ memcpy(dataptr, &targetendian_crc, sizeof(targetendian_crc));
+ if (redundant)
+ dataptr[sizeof(targetendian_crc)] = 1;
- bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
- if (bin_fd == -1) {
- fprintf(stderr, "Can't open output file \"%s\": %s\n",
- bin_filename, strerror(errno));
- return EXIT_FAILURE;
+ if (!bin_filename || strcmp(bin_filename, "-") == 0) {
+ bin_fd = STDOUT_FILENO;
+ } else {
+ bin_fd = creat(bin_filename, S_IRUSR | S_IWUSR | S_IRGRP |
+ S_IWGRP);
+ if (bin_fd == -1) {
+ fprintf(stderr, "Can't open output file \"%s\": %s\n",
+ bin_filename, strerror(errno));
+ return EXIT_FAILURE;
+ }
}
if (write(bin_fd, dataptr, sizeof(*dataptr) * datasize) !=
void usage(void)
{
printf(
- "Usage: mx28image [ops] <type> <infile> <outfile>\n"
+ "Usage: mxsboot [ops] <type> <infile> <outfile>\n"
"Augment BootStream file with a proper header for i.MX28 boot\n"
"\n"
" <type> type of image:\n"