Project import
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..36932ae --- /dev/null +++ b/Makefile
@@ -0,0 +1,103 @@ +# +# Copyright (c) 2010 Nest Labs, Inc. +# All rights reserved. +# +# This document is the property of Nest Labs. It is considered +# confidential and proprietary information. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Nest Labs. +# +# Description: +# This file is the make file for X-Loader, an initial program +# loader (IPL) for embedded boards based on Texas Instruments +# OMAP processors. +# + +include pre.mak + +PackageRoot := . + +PackageName := x-loader + +PackageSeparator := + +PackageVersion := +PackageSourceDir := $(PackageName)$(PackageSeparator)$(PackageVersion) + +PackageBuildMakefile = $(call GenerateBuildPaths,include/config.mk) + +CleanPaths += $(PackageLicenseFile) + +SOURCEDIRS = $(PackageSourceDir) +$(PackageSourceDir)_RULE_TARGET = $(BuildDirectory)/configure + +all: $(PackageDefaultGoal) + +# Generate the package license contents. + +$(PackageSourceDir)/README: $(BuildDirectory)/source + +$(PackageLicenseFile): $(PackageSourceDir)/README + $(Echo) "Extracting \"$(call GenerateBuildRootEllipsedPath,$(@))\"" + $(Verbose)$(SED) -n -e '10,25p' < $< > $@ + +# Prepare the sources. + +$(BuildDirectory)/source: | $(PackageSourceDir) $(BuildDirectory) + $(Verbose)touch $@ + +# Patch the sources, if necessary. + +$(BuildDirectory)/patch: $(BuildDirectory)/source + $(Verbose)touch $@ + +# X-Loader has no way of explicitly setting CC, LD, OBJCOPY, et al and +# instead relies on the value of CROSS_COMPILE. Consequently, we have +# to ensure that 'ToolBinDir' is in 'PATH' so that the kernel build +# infrastructure can find $(CROSS_COMPILE)gcc, $(CROSS_COMPILE)ld, et al. + +$(BuildDirectory)/configure $(BuildDirectory)/build $(BuildDirectory)/stage: PATH := $(PATH):$(ToolBinDir) +$(BuildDirectory)/configure $(BuildDirectory)/build $(BuildDirectory)/stage: CROSS_COMPILE := $(CCACHE) $(CROSS_COMPILE) + +# Generate the package build makefile. + +# Configure the source for building. + +$(BuildDirectory)/configure: $(BuildDirectory)/source | $(PackageSourceDir) $(BuildDirectory) + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) O=$(CURDIR)/$(BuildDirectory) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + $(XLoaderProductionConfig) + $(Verbose)touch $@ + +# Build the source. + +$(BuildDirectory)/build: $(BuildDirectory)/configure + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) O=$(CURDIR)/$(BuildDirectory) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + all + $(Verbose)touch $@ + +# Stage the build to a temporary installation area. +# +# X-Loader does not support a notion of installing, so we have to +# cherry-pick the components we want from the build directory and +# copy/install them to the results directory. + +$(BuildDirectory)/stage: $(BuildDirectory)/build | $(ResultDirectory) + $(Verbose)cp -f $(wildcard $(call GenerateBuildPaths,x-load*)) $(ResultDirectory) + $(Verbose)cp -f $(call GenerateBuildPaths,System.map) $(ResultDirectory) + $(Verbose)touch $@ + +.PHONY: stage +stage: $(BuildDirectory)/stage + + +clean: + $(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory) + $(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory) + +include post.mak
diff --git a/x-loader.version b/x-loader.version new file mode 100644 index 0000000..dbf095b --- /dev/null +++ b/x-loader.version
@@ -0,0 +1 @@ +1.46_OMAPPSP_03.00.01.06
diff --git a/x-loader/.file-list b/x-loader/.file-list new file mode 100644 index 0000000..c1d5069 --- /dev/null +++ b/x-loader/.file-list
@@ -0,0 +1,111 @@ +.@@/main/x-load_tid_int_x.x/2 +./Makefile@@/main/x-load_tid_int_x.x/5 +./README@@/main/x-load_tid_int_x.x/3 +./arm_config.mk@@/main/x-load_tid_int_x.x/1 +./board@@/main/x-load_tid_int_x.x/4 +./board/omap1710h3@@/main/x-load_tid_int_x.x/1 +./board/omap1710h3/Makefile@@/main/x-load_tid_int_x.x/1 +./board/omap1710h3/config.mk@@/main/x-load_tid_int_x.x/1 +./board/omap1710h3/omap1710h3.c@@/main/x-load_tid_int_x.x/1 +./board/omap1710h3/platform.S@@/main/x-load_tid_int_x.x/1 +./board/omap1710h3/x-load.lds@@/main/x-load_tid_int_x.x/1 +./board/omap2420h4@@/main/x-load_tid_int_x.x/1 +./board/omap2420h4/Makefile@@/main/x-load_tid_int_x.x/1 +./board/omap2420h4/config.mk@@/main/x-load_tid_int_x.x/1 +./board/omap2420h4/omap2420h4.c@@/main/x-load_tid_int_x.x/3 +./board/omap2420h4/platform.S@@/main/x-load_tid_int_x.x/3 +./board/omap2420h4/x-load.lds@@/main/x-load_tid_int_x.x/1 +./board/omap2430sdp@@/main/x-load_tid_int_x.x/2 +./board/omap2430sdp/Makefile@@/main/x-load_tid_int_x.x/2 +./board/omap2430sdp/config.mk@@/main/x-load_tid_int_x.x/1 +./board/omap2430sdp/omap2430sdp.c@@/main/x-load_tid_int_x.x/7 +./board/omap2430sdp/platform.S@@/main/x-load_tid_int_x.x/2 +./board/omap2430sdp/x-load.lds@@/main/x-load_tid_int_x.x/1 +./board/omap3430sdp@@/main/x-load_tid_int_x.x/1 +./board/omap3430sdp/Makefile@@/main/x-load_tid_int_x.x/1 +./board/omap3430sdp/config.mk@@/main/x-load_tid_int_x.x/1 +./board/omap3430sdp/omap3430sdp.c@@/main/x-load_tid_int_x.x/2 +./board/omap3430sdp/platform.S@@/main/x-load_tid_int_x.x/2 +./board/omap3430sdp/x-load.lds@@/main/x-load_tid_int_x.x/1 +./config.mk@@/main/x-load_tid_int_x.x/2 +./cpu@@/main/x-load_tid_int_x.x/3 +./cpu/arm1136@@/main/x-load_tid_int_x.x/1 +./cpu/arm1136/Makefile@@/main/x-load_tid_int_x.x/1 +./cpu/arm1136/config.mk@@/main/x-load_tid_int_x.x/7 +./cpu/arm1136/cpu.c@@/main/x-load_tid_int_x.x/1 +./cpu/arm1136/start.S@@/main/x-load_tid_int_x.x/1 +./cpu/arm926ejs@@/main/x-load_tid_int_x.x/1 +./cpu/arm926ejs/Makefile@@/main/x-load_tid_int_x.x/1 +./cpu/arm926ejs/config.mk@@/main/x-load_tid_int_x.x/3 +./cpu/arm926ejs/cpu.c@@/main/x-load_tid_int_x.x/1 +./cpu/arm926ejs/start.S@@/main/x-load_tid_int_x.x/2 +./cpu/omap3@@/main/x-load_tid_int_x.x/1 +./cpu/omap3/Makefile@@/main/x-load_tid_int_x.x/1 +./cpu/omap3/config.mk@@/main/x-load_tid_int_x.x/1 +./cpu/omap3/cpu.c@@/main/x-load_tid_int_x.x/1 +./cpu/omap3/start.S@@/main/x-load_tid_int_x.x/1 +./drivers@@/main/x-load_tid_int_x.x/3 +./drivers/Makefile@@/main/x-load_tid_int_x.x/3 +./drivers/k9f5616.c@@/main/x-load_tid_int_x.x/2 +./drivers/k9k1216.c@@/main/x-load_tid_int_x.x/1 +./drivers/ns16550.c@@/main/x-load_tid_int_x.x/2 +./drivers/onenand.c@@/main/x-load_tid_int_x.x/1 +./drivers/onenand_regs.h@@/main/x-load_tid_int_x.x/1 +./drivers/serial.c@@/main/x-load_tid_int_x.x/1 +./include@@/main/x-load_tid_int_x.x/1 +./include/asm@@/main/x-load_tid_int_x.x/3 +./include/asm/arch-arm1136@@/main/x-load_tid_int_x.x/3 +./include/asm/arch-arm1136/bits.h@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-arm1136/clocks.h +./include/asm/arch-arm1136/clocks242x.h +./include/asm/arch-arm1136/clocks243x.h +./include/asm/arch-arm1136/mem.h +./include/asm/arch-arm1136/omap2420.h@@/main/x-load_tid_int_x.x/3 +./include/asm/arch-arm1136/omap2430.h@@/main/x-load_tid_int_x.x/2 +./include/asm/arch-arm1136/sizes.h@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-arm1136/sys_info.h@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-arm926ejs@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-arm926ejs/sizes.h@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-omap3@@/main/x-load_tid_int_x.x/1 +./include/asm/arch-omap3/bits.h +./include/asm/arch-omap3/clocks.h +./include/asm/arch-omap3/clocks343x.h +./include/asm/arch-omap3/cpu.h +./include/asm/arch-omap3/mem.h +./include/asm/arch-omap3/mux.h +./include/asm/arch-omap3/omap3430.h +./include/asm/arch-omap3/sizes.h +./include/asm/arch-omap3/sys_info.h +./include/asm/arch-omap3/sys_proto.h +./include/asm/atomic.h@@/main/x-load_tid_int_x.x/1 +./include/asm/posix_types.h@@/main/x-load_tid_int_x.x/1 +./include/asm/proc-armv@@/main/x-load_tid_int_x.x/1 +./include/asm/setup.h@@/main/x-load_tid_int_x.x/1 +./include/asm/sizes.h@@/main/x-load_tid_int_x.x/1 +./include/asm/string.h@@/main/x-load_tid_int_x.x/1 +./include/asm/types.h@@/main/x-load_tid_int_x.x/1 +./include/asm/x-load-arm.h@@/main/x-load_tid_int_x.x/1 +./include/common.h@@/main/x-load_tid_int_x.x/2 +./include/configs@@/main/x-load_tid_int_x.x/4 +./include/configs/omap1510.h@@/main/x-load_tid_int_x.x/1 +./include/configs/omap1710h3.h@@/main/x-load_tid_int_x.x/2 +./include/configs/omap2420h4.h@@/main/x-load_tid_int_x.x/4 +./include/configs/omap2430sdp.h@@/main/x-load_tid_int_x.x/6 +./include/configs/omap3430sdp.h@@/main/x-load_tid_int_x.x/1 +./include/linux@@/main/x-load_tid_int_x.x/1 +./include/linux/config.h@@/main/x-load_tid_int_x.x/1 +./include/linux/posix_types.h@@/main/x-load_tid_int_x.x/1 +./include/linux/stddef.h@@/main/x-load_tid_int_x.x/1 +./include/linux/types.h@@/main/x-load_tid_int_x.x/1 +./include/ns16550.h@@/main/x-load_tid_int_x.x/2 +./lib@@/main/x-load_tid_int_x.x/2 +./lib/Makefile@@/main/x-load_tid_int_x.x/2 +./lib/_udivsi3.S@@/main/x-load_tid_int_x.x/1 +./lib/_umodsi3.S@@/main/x-load_tid_int_x.x/1 +./lib/board.c@@/main/x-load_tid_int_x.x/8 +./lib/div0.c@@/main/x-load_tid_int_x.x/1 +./lib/ecc.c@@/main/x-load_tid_int_x.x/1 +./lib/printf.c@@/main/x-load_tid_int_x.x/1 +./mkconfig@@/main/x-load_tid_int_x.x/1 +./scripts@@/main/x-load_tid_int_x.x/1 +./scripts/mkoneboot.sh@@/main/x-load_tid_int_x.x/1
diff --git a/x-loader/Makefile b/x-loader/Makefile new file mode 100644 index 0000000..2c43dae --- /dev/null +++ b/x-loader/Makefile
@@ -0,0 +1,386 @@ +# +# (C) Copyright 2004-2006, Texas Instruments, <www.ti.com> +# Jian Zhang <jzhang@ti.com> +# +# (C) Copyright 2000-2010 +# 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 +# + +VERSION = 1 +PATCHLEVEL = 46 +SUBLEVEL = +EXTRAVERSION = +ifneq "$(SUBLEVEL)" "" +X_LOADER_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) +else +X_LOADER_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION) +endif +TIMESTAMP_FILE = $(obj)include/timestamp_autogenerated.h +VERSION_FILE = $(obj)include/version_autogenerated.h + +HOSTARCH := $(shell uname -m | \ + sed -e s/i.86/i386/ \ + -e s/sun4u/sparc64/ \ + -e s/arm.*/arm/ \ + -e s/sa110/arm/ \ + -e s/ppc64/powerpc/ \ + -e s/ppc/powerpc/ \ + -e s/macppc/powerpc/\ + -e s/sh.*/sh/) + +HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ + sed -e 's/\(cygwin\).*/cygwin/') + +# Set shell to bash if possible, otherwise fall back to sh +SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi; fi) + +export HOSTARCH HOSTOS SHELL + +# Deal with colliding definitions from tcsh etc. +VENDOR= + +######################################################################### +# Allow for silent builds +ifeq (,$(findstring s,$(MAKEFLAGS))) +XECHO = echo +else +XECHO = : +endif + +######################################################################### +# +# X-loader build supports producing a object files to the separate external +# directory. Two use cases are supported: +# +# 1) Add O= to the make command line +# 'make O=/tmp/build all' +# +# 2) Set environement variable BUILD_DIR to point to the desired location +# 'export BUILD_DIR=/tmp/build' +# 'make' +# +# The second approach can also be used with a MAKEALL script +# 'export BUILD_DIR=/tmp/build' +# './MAKEALL' +# +# Command line 'O=' setting overrides BUILD_DIR environent variable. +# +# When none of the above methods is used the local build is performed and +# the object files are placed in the source directory. +# + +ifdef O +ifeq ("$(origin O)", "command line") +BUILD_DIR := $(O) +endif +endif + +ifneq ($(BUILD_DIR),) +saved-output := $(BUILD_DIR) + +# Attempt to create a output directory. +$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}) + +# Verify if it was successful. +BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd) +$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist)) +endif # ifneq ($(BUILD_DIR),) + +OBJTREE := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR)) +SRCTREE := $(CURDIR) +TOPDIR := $(SRCTREE) +LNDIR := $(OBJTREE) +export TOPDIR SRCTREE OBJTREE + +MKCONFIG := $(SRCTREE)/mkconfig +export MKCONFIG + +ifneq ($(OBJTREE),$(SRCTREE)) +REMOTE_BUILD := 1 +export REMOTE_BUILD +endif + +# $(obj) and (src) are defined in config.mk but here in main Makefile +# we also need them before config.mk is included which is the case for +# some targets like unconfig, clean, clobber, distclean, etc. +ifneq ($(OBJTREE),$(SRCTREE)) +obj := $(OBJTREE)/ +src := $(SRCTREE)/ +else +obj := +src := +endif +export obj src + +######################################################################### + +# The "tools" are needed early, so put this first +# Don't include stuff already done in $(LIBS) +SUBDIRS = tools +.PHONY : $(SUBDIRS) + +ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk)) + +# Include autoconf.mk before config.mk so that the config options are available +# to all top level build files. We need the dummy all: target to prevent the +# dependency target in autoconf.mk.dep from being the default. +all: +sinclude $(obj)include/autoconf.mk.dep +sinclude $(obj)include/autoconf.mk + +# load ARCH, BOARD, and CPU configuration +include $(obj)include/config.mk +export ARCH CPU BOARD VENDOR SOC + +# set default to nothing for native builds +ifeq ($(HOSTARCH),$(ARCH)) +CROSS_COMPILE ?= +endif + +# load other configuration +include $(TOPDIR)/config.mk + +######################################################################### +# X-Load objects....order is important (i.e. start must be first) + +OBJS = $(CPUDIR)/start.o + +OBJS := $(addprefix $(obj),$(OBJS)) + +LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \ + "board/$(VENDOR)/common/lib$(VENDOR).a"; fi) +LIBS += $(CPUDIR)/lib$(CPU).a +LIBS += lib/lib$(ARCH).a +LIBS += common/libcommon.a +LIBS += fs/fat/libfat.a +LIBS += disk/libdisk.a +LIBS += drivers/mtd/nand/libnand.a +LIBS += drivers/mtd/onenand/libonenand.a +LIBS += drivers/rtc/librtc.a +LIBS += drivers/serial/libserial.a +LIBS += drivers/usb/libusb.a + +LIBS := $(addprefix $(obj),$(LIBS)) +.PHONY : $(LIBS) $(TIMESTAMP_FILE) $(VERSION_FILE) + +LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a +LIBBOARD := $(addprefix $(obj),$(LIBBOARD)) + +# Add GCC lib +PLATFORM_LIBGCC = -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc +PLATFORM_LIBS += $(PLATFORM_LIBGCC) +export PLATFORM_LIBS + +__OBJS := $(subst $(obj),,$(OBJS)) +__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD)) + +######################################################################### +######################################################################### + +# Always append ALL so that arch config.mk's can add custom ones +ALL += $(obj)x-load.srec $(obj)x-load.bin $(obj)x-load.bin.ift $(obj)System.map + +all: $(ALL) + +$(obj)x-load.hex: $(obj)x-load + $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ + +$(obj)x-load.srec: $(obj)x-load + $(OBJCOPY) -O srec $< $@ + +$(obj)x-load.bin: $(obj)x-load + $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ + +$(obj)x-load.bin.ift: $(obj)x-load.bin + $(obj)tools/signGP $< + +$(obj)x-load.dis: $(obj)x-load + $(OBJDUMP) -d $< > $@ + +GEN_XLOAD = \ + UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \ + sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ + cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ + --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ + -Map x-load.map -o x-load +$(obj)x-load: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)x-load.lds + $(GEN_XLOAD) + +$(OBJS): depend + $(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@)) + +$(LIBS): depend $(SUBDIRS) + $(MAKE) -C $(dir $(subst $(obj),,$@)) + +$(LIBBOARD): depend $(LIBS) + $(MAKE) -C $(dir $(subst $(obj),,$@)) + +$(SUBDIRS): depend + $(MAKE) -C $@ all + +$(LDSCRIPT): depend + $(MAKE) -C $(dir $@) $(notdir $@) + +$(obj)x-load.lds: $(LDSCRIPT) + $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ + +$(obj)oneboot: $(obj)x-load.bin + scripts/mkoneboot.sh +$(VERSION_FILE): + @( printf '#define X_LOADER_VERSION "Texas Instruments X-Loader %s%s"\n' "$(X_LOADER_VERSION)" \ + '$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ) > $@.tmp + @cmp -s $@ $@.tmp && rm -f $@.tmp || mv -f $@.tmp $@ + +$(TIMESTAMP_FILE): + @LC_ALL=C date +'#define X_LOADER_DATE "%b %d %C%y"' > $@ + @LC_ALL=C date +'#define X_LOADER_TIME "%T"' >> $@ + +# Explicitly make _depend in subdirs containing multiple targets to prevent +# parallel sub-makes creating .depend files simultaneously. +depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) + for dir in $(SUBDIRS) $(CPUDIR) $(dir $(LDSCRIPT)) ; do \ + $(MAKE) -C $$dir _depend ; done + +TAG_SUBDIRS = $(SUBDIRS) +TAG_SUBDIRS += $(dir $(__LIBS)) +TAG_SUBDIRS += include + +tags ctags: + ctags -w -o $(obj)ctags `find $(TAG_SUBDIRS) \ + -name '*.[chS]' -print` + +etags: + etags -a -o $(obj)etags `find $(TAG_SUBDIRS) \ + -name '*.[chS]' -print` +cscope: + find $(TAG_SUBDIRS) -name '*.[chS]' -print > cscope.files + cscope -b -q -k + +SYSTEM_MAP = \ + $(NM) $1 | \ + grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + LC_ALL=C sort +$(obj)System.map: $(obj)x-load + @$(call SYSTEM_MAP,$<) > $(obj)System.map + + + +######################################################################### +else # !config.mk +all $(obj)x-load.hex $(obj)x-load.srec $(obj)x-load.bin \ +$(obj)x-load.dis $(obj)x-load \ +$(obj)oneboot \ +$(filter-out tools,$(SUBDIRS)) $(TIMESTAMP_FILE) $(VERSION_FILE) \ +depend dep tags ctags etags cscope $(obj)System.map: + @echo "System not configured - see README" >&2 + @ exit 1 + +tools: + $(MAKE) -C tools +tools-all: + $(MAKE) -C tools HOST_TOOLS_ALL=y +endif # config.mk + +######################################################################### + +unconfig: + @rm -f $(obj)include/config.h $(obj)include/config.mk + +%_config:: unconfig + @$(MKCONFIG) -A $(@:_config=) + +# +# Functions to generate common board directory names +# +lcname = $(shell echo $(1) | sed -e 's/\(.*\)_config/\L\1/') +ucname = $(shell echo $(1) | sed -e 's/\(.*\)_config/\U\1/') + +#======================================================================== +# ARM +#======================================================================== +######################################################################### +## OMAP1 (ARM92xT) Systems +######################################################################### + +omap1710h3_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm926ejs omap1710h3 + +######################################################################### +## OMAP2 (ARM1136) Systems +######################################################################### + +omap2420h4_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4 + +omap2430sdp_config : unconfig + @$(MKCONFIG) $(@:_config=) arm arm1136 omap2430sdp + +######################################################################### +## OMAP3 (ARM-CortexA8) Systems +######################################################################### +omap3430sdp_config : unconfig + @$(MKCONFIG) $(@:_config=) arm omap3 omap3430sdp + +omap3430labrador_config : unconfig + @$(MKCONFIG) $(@:_config=) arm omap3 omap3430labrador + +omap3evm_config : unconfig + @$(MKCONFIG) $(@:_config=) arm omap3 omap3evm + +am3517evm_config : unconfig + @$(MKCONFIG) $(@:_config=) arm omap3 am3517evm + +######################################################################### +######################################################################### +clean: + @rm -f $(obj)tools/signGP + @rm -f $(TIMESTAMP_FILE) $(VERSION_FILE) + @find $(OBJTREE) -type f \ + \( -name 'core' -o -name '*.bak' -o -name '*~' \ + -o -name '*.o' -o -name '*.a' -o -name '*.exe' \) -print \ + | xargs rm -f + +clobber: clean + @find $(OBJTREE) -type f \( -name .depend \ + -o -name '*.srec' -o -name '*.bin' -o -name '*.bin.ift' \) \ + -print0 \ + | xargs -0 rm -f + @rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \ + $(obj)cscope.* $(obj)*.*~ + @rm -f $(obj)x-load $(obj)x-load.map $(obj)x-load.hex $(ALL) + @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm + +ifeq ($(OBJTREE),$(SRCTREE)) +mrproper \ +distclean: clobber unconfig +else +mrproper \ +distclean: clobber unconfig + rm -rf $(obj)* +endif + +backup: + F=`basename $(TOPDIR)` ; cd .. ; \ + gtar --force-local -zcvf `LC_ALL=C date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F + +#########################################################################
diff --git a/x-loader/README b/x-loader/README new file mode 100644 index 0000000..ae2662a --- /dev/null +++ b/x-loader/README
@@ -0,0 +1,152 @@ +# +# (C) Copyright 2004-2006 Texas Instruments +# +# Some cut/paste from U-Boot README +# (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 +# + +Summary: +======== + +This directory contains the source code for X-Loader, an initial program +loader for Embedded boards based on OMAP processors. X-Loader can be +signed by Texas Instruments IFT and installed to Nand flash to achieve +Nand booting. + + +Status: +======= + +The support for Texas Instruments H3 board (OMAP1710) has been implemented +and tested. (May 2004) +The support for Texas Instruments H4 board (OMAP2420) has been implemented +and tested. (Nov 2004) +The support for Texas Instruments 2430SDP board (OMAP2430) has been implemented +and tested. (Jul 2006) +The support for Texas Instruments 3430SDP board (OMAP3430) has been implemented +and tested. (Dec 2006) + + +Support for other OMAP boards can be added. + + +Directory Hierarchy: +==================== + +- board Board dependent files +- cpu CPU specific files +- drivers Commonly used device drivers +- lib Libraries + +- cpu/arm926ejs Files specific to ARM 926 CPUs +- cpu/arm1136 Files specific to ARM 1136 CPUs +- cpu/omap3 Files specific to ARM CortexA8 CPU + + +- board/omap1710h3 + Files specific to OMAP 1710 H3 boards +- board/omap2420h4 + Files specific to OMAP 2420 H4 boards +- board/omap2430sdp + Files specific to OMAP 2430 2430sdp boards +- board/omap3430sdp + Files specific to OMAP 3420sdp boards + + +Software Configuration: +======================= + +Configuration is usually done using C preprocessor defines. Configuration +depends on the combination of board and CPU type; all such information is +kept in a configuration file "include/configs/<board_name>.h". + +Example: For a H3 module, all configuration settings are in +"include/configs/omap1710h3.h". + +For all supported boards there are ready-to-use default +configurations available; just type "make <board_name>_config". + +Example: For a H3 module type: + + cd x-load + make omap1710h3_config + +After a board has been configured, type "make" to build it supposing the +needed cross tools are in your path. + + +Image Format: +============= + +X-Loader expects OS boot loader (e.g. U-Boot) in Nand flash using +JFFS2 style ECC. + + +Prepare Booting Nand Flash: +=========================== + +After you have built x-load.bin for your board, you need to do the +followings to get it into Nand flash: + +1. Use Texas Instruments IFT to sign x-load.bin. This results in a +signed image called x-load.bin.ift. +2. Use Texas Instruments FlashPrep to generate a .out file using +FlashWriterNand and specifying 0 as nand target address. +3. Use Texas instrumnets Code Composer Studio to run the .out file +which flashes x-load.bin.ift to Nand flash. + +Next you need to get your OS boot loader to Nand at the address your +X-Loader expects. For the H3 example, you can use U-Boot to flash U-Boot. +You can't use FlashWriterNand because it uses ROM code ECC style. + + +More Information +================ + +OMAP1710 NAND Booting Design Document has more information. + +Implemenation notes: +==================== +H3, H4 support NAND flash booting +2430sdp & 3430sdp support OneNAND booting + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file
diff --git a/x-loader/arm_config.mk b/x-loader/arm_config.mk new file mode 100644 index 0000000..73d9625 --- /dev/null +++ b/x-loader/arm_config.mk
@@ -0,0 +1,24 @@ +# +# (C) Copyright 2000-2002 +# 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 +# + +PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
diff --git a/x-loader/board/am3517evm/Makefile b/x-loader/board/am3517evm/Makefile new file mode 100644 index 0000000..4ac2924 --- /dev/null +++ b/x-loader/board/am3517evm/Makefile
@@ -0,0 +1,49 @@ +# +# (C) Copyright 2009 +# Texas Instruments, <www.ti.com> +# Manikandan Pillai<mani.pillai@ti.com> +# This file is copied from board/omap3evm/Makefile +# +# 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).a + +OBJS := am3517evm.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/am3517evm/am3517evm.c b/x-loader/board/am3517evm/am3517evm.c new file mode 100644 index 0000000..5e44be9 --- /dev/null +++ b/x-loader/board/am3517evm/am3517evm.c
@@ -0,0 +1,908 @@ +/* + * (C) Copyright 2009 + * Texas Instruments, <www.ti.com> + * Manikandan Pillai<mani.pillai@ti.com> + * This file is copied from board/omap3evm/omap3evm.c + * + * 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 <part.h> +#include <fat.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +/* Used to index into DPLL parameter tables */ +struct dpll_param { + unsigned int m; + unsigned int n; + unsigned int fsel; + unsigned int m2; +}; + +typedef struct dpll_param dpll_param; + +#define MAX_SIL_INDEX 3 + +/* Definitions for EMIF4 configuration values */ +#define EMIF4_TIM1_T_RP 0x3 +#define EMIF4_TIM1_T_RCD 0x3 +#define EMIF4_TIM1_T_WR 0x3 +#define EMIF4_TIM1_T_RAS 0x8 +#define EMIF4_TIM1_T_RC 0xA +#define EMIF4_TIM1_T_RRD 0x2 +#define EMIF4_TIM1_T_WTR 0x2 + +#define EMIF4_TIM2_T_XP 0x2 +#define EMIF4_TIM2_T_ODT 0x0 +#define EMIF4_TIM2_T_XSNR 0x1C +#define EMIF4_TIM2_T_XSRD 0xC8 +#define EMIF4_TIM2_T_RTP 0x1 +#define EMIF4_TIM2_T_CKE 0x2 + +#define EMIF4_TIM3_T_TDQSCKMAX 0x0 +#define EMIF4_TIM3_T_RFC 0x25 +#define EMIF4_TIM3_T_RAS_MAX 0x7 + +#define EMIF4_PWR_IDLE 0x2 +#define EMIF4_PWR_DPD_EN 0x0 +#define EMIF4_PWR_PM_EN 0x0 +#define EMIF4_PWR_PM_TIM 0x0 + +#define EMIF4_INITREF_DIS 0x0 +#define EMIF4_PASR 0x0 +#define EMIF4_REFRESH_RATE 0x50F + +/* + * SDRAM Config register + */ +#define EMIF4_CFG_SDRAM_TYP 0x2 +#define EMIF4_CFG_IBANK_POS 0x0 +#define EMIF4_CFG_DDR_TERM 0x0 +#define EMIF4_CFG_DDR2_DDQS 0x1 +#define EMIF4_CFG_DYN_ODT 0x0 +#define EMIF4_CFG_DDR_DIS_DLL 0x0 +#define EMIF4_CFG_SDR_DRV 0x0 +#define EMIF4_CFG_CWL 0x0 +#define EMIF4_CFG_NARROW_MD 0x0 +#define EMIF4_CFG_CL 0x5 +#define EMIF4_CFG_ROWSIZE 0x0 +#define EMIF4_CFG_IBANK 0x3 +#define EMIF4_CFG_EBANK 0x0 +#define EMIF4_CFG_PGSIZE 0x2 + +/* + * EMIF4 PHY Control 1 register configuration + */ +#define EMIF4_DDR1_RD_LAT 0x6 +#define EMIF4_DDR1_PWRDN_DIS 0x0 +#define EMIF4_DDR1_STRBEN_EXT 0x0 +#define EMIF4_DDR1_DLL_MODE 0x0 +#define EMIF4_DDR1_VTP_DYN 0x0 +#define EMIF4_DDR1_LB_CK_SEL 0x0 + +/* + * EMIF4 PHY Control 2 register configuration + */ +#define EMIF4_DDR2_TX_DATA_ALIGN 0x0 +#define EMIF4_DDR2_RX_DLL_BYPASS 0x0 + +/* Following functions are exported from lowlevel_init.S */ +extern dpll_param *get_mpu_dpll_param(void); +#if 0 +extern dpll_param *get_iva_dpll_param(void); +#endif +extern dpll_param *get_core_dpll_param(void); +extern dpll_param *get_per_dpll_param(void); + +extern int mmc_init(int verbose); +extern block_dev_desc_t *mmc_get_dev(int dev); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +/* TODO: Move it to common place so that should be used + * for all OMAP series of devices + */ +u32 is_cpu_family(void) +{ + u32 cpuid = 0, cpu_family = 0; + u16 hawkeye; + + cpuid = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (cpuid >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + case HAWKEYE_AM35XX: + default: + cpu_family = CPU_AM35XX; + break; + } + return cpu_family; +} +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); + return(mode >>= 8); +} + +/************************************************ + * get_sysboot_value(void) - return SYS_BOOT[4:0] + ************************************************/ +u32 get_sysboot_value(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (SYSBOOT_MASK); + return mode; +} +/************************************************************* + * Routine: get_mem_type(void) - returns the kind of memory connected + * to GPMC that we are trying to boot form. Uses SYS BOOT settings. + *************************************************************/ +u32 get_mem_type(void) +{ + u32 mem_type = get_sysboot_value(); + switch (mem_type){ + + case 1: + case 12: + case 15: + case 21: + case 27: return GPMC_NAND; + + + + case 13: + return MMC_NAND; + + default: return GPMC_NAND; + } +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid=0; + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + if((cpuid & 0xf) == 0x0) + return CPU_3430_ES1; + else + return CPU_3430_ES2; + +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +/********************************************************************* + * config_emif4_ddr() - Init/Configure DDR on AM3517 EVM board. + *********************************************************************/ +void config_emif4_ddr(void) +{ + unsigned int regval; + + /* Set the DDR PHY parameters in PHY ctrl registers */ + regval = (EMIF4_DDR1_RD_LAT | (EMIF4_DDR1_PWRDN_DIS << 6) | + (EMIF4_DDR1_STRBEN_EXT << 7) | (EMIF4_DDR1_DLL_MODE << 12) | + (EMIF4_DDR1_VTP_DYN << 15) | (EMIF4_DDR1_LB_CK_SEL << 23)); + __raw_writel(regval, EMIF4_DDR_PHYCTL1); + __raw_writel(regval, EMIF4_DDR_PHYCTL1_SHDW); + + regval = (EMIF4_DDR2_TX_DATA_ALIGN | (EMIF4_DDR2_RX_DLL_BYPASS << 1)); + __raw_writel(regval, EMIF4_DDR_PHYCTL2); + + /* Reset the DDR PHY and wait till completed */ + sr32(EMIF4_IODFT_TLGC, 10, 1, 1); + /*Wait till that bit clears*/ + while ((__raw_readl(EMIF4_IODFT_TLGC) & BIT10) == 0x1); + /*Re-verify the DDR PHY status*/ + while ((__raw_readl(EMIF4_SDRAM_STS) & BIT2) == 0x0); + + sr32(EMIF4_IODFT_TLGC, 0, 1, 1); + /* Set SDR timing registers */ + regval = (EMIF4_TIM1_T_WTR | (EMIF4_TIM1_T_RRD << 3) | + (EMIF4_TIM1_T_RC << 6) | (EMIF4_TIM1_T_RAS << 12) | + (EMIF4_TIM1_T_WR << 17) | (EMIF4_TIM1_T_RCD << 21) | + (EMIF4_TIM1_T_RP << 25)); + __raw_writel(regval, EMIF4_SDRAM_TIM1); + __raw_writel(regval, EMIF4_SDRAM_TIM1_SHDW); + + regval = (EMIF4_TIM2_T_CKE | (EMIF4_TIM2_T_RTP << 3) | + (EMIF4_TIM2_T_XSRD << 6) | (EMIF4_TIM2_T_XSNR << 16) | + (EMIF4_TIM2_T_ODT << 25) | (EMIF4_TIM2_T_XP << 28)); + __raw_writel(regval, EMIF4_SDRAM_TIM2); + __raw_writel(regval, EMIF4_SDRAM_TIM2_SHDW); + + regval = (EMIF4_TIM3_T_RAS_MAX | (EMIF4_TIM3_T_RFC << 4) | + (EMIF4_TIM3_T_TDQSCKMAX << 13)); + __raw_writel(regval, EMIF4_SDRAM_TIM3); + __raw_writel(regval, EMIF4_SDRAM_TIM3_SHDW); + + /* Set the PWR control register */ + regval = (EMIF4_PWR_PM_TIM | (EMIF4_PWR_PM_EN << 8) | + (EMIF4_PWR_DPD_EN << 10) | (EMIF4_PWR_IDLE << 30)); + __raw_writel(regval, EMIF4_PWR_MGT_CTRL); + __raw_writel(regval, EMIF4_PWR_MGT_CTRL_SHDW); + + /* Set the DDR refresh rate control register */ + regval = (EMIF4_REFRESH_RATE | (EMIF4_PASR << 24) | + (EMIF4_INITREF_DIS << 31)); + __raw_writel(regval, EMIF4_SDRAM_RFCR); + __raw_writel(regval, EMIF4_SDRAM_RFCR_SHDW); + + /* set the SDRAM configuration register */ + regval = (EMIF4_CFG_PGSIZE | (EMIF4_CFG_EBANK << 3) | + (EMIF4_CFG_IBANK << 4) | (EMIF4_CFG_ROWSIZE << 7) | + (EMIF4_CFG_CL << 10) | (EMIF4_CFG_NARROW_MD << 14) | + (EMIF4_CFG_CWL << 16) | (EMIF4_CFG_SDR_DRV << 18) | + (EMIF4_CFG_DDR_DIS_DLL << 20) | (EMIF4_CFG_DYN_ODT << 21) | + (EMIF4_CFG_DDR2_DDQS << 23) | (EMIF4_CFG_DDR_TERM << 24) | + (EMIF4_CFG_IBANK_POS << 27) | (EMIF4_CFG_SDRAM_TYP << 29)); + __raw_writel(regval, EMIF4_SDRAM_CFG); +} + +/************************************************************* + * get_sys_clk_speed - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *************************************************************/ +u32 get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + /* If SYS_CLK is being divided by 2, remove for now */ + val = (val & (~BIT7)) | BIT6; + __raw_writel(val, PRM_CLKSRC_CTRL); + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/****************************************************************************** + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on + * -- input oscillator clock frequency. + * + *****************************************************************************/ +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) +{ + if(osc_clk == S38_4M) + *sys_clkin_sel= 4; + else if(osc_clk == S26M) + *sys_clkin_sel = 3; + else if(osc_clk == S19_2M) + *sys_clkin_sel = 2; + else if(osc_clk == S13M) + *sys_clkin_sel = 1; + else if(osc_clk == S12M) + *sys_clkin_sel = 0; +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * -- called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + u32 osc_clk=0, sys_clkin_sel; + dpll_param *dpll_param_p; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + osc_clk = get_osc_clk_speed(); + get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + + sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ + + /* If the input clock is greater than 19.2M always divide/2 */ + if(sys_clkin_sel > 2) { + sr32(PRM_CLKSRC_CTRL, 6, 2, 2);/* input clock divider */ + clk_index = sys_clkin_sel/2; + } else { + sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ + clk_index = sys_clkin_sel; + } + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + sil_index = get_cpu_rev() - 1; + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + /* Getting the base address of Core DPLL param table*/ + dpll_param_p = (dpll_param *)get_core_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + 2*clk_index + sil_index; + /* CORE DPLL */ + /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ + sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to PER DPLL param table*/ + dpll_param_p = (dpll_param *)get_per_dpll_param(); + /* Moving it to the right sysclk base */ + dpll_param_p = dpll_param_p + clk_index; + /* PER DPLL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ + sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m); /* set m */ + sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n); /* set n */ + sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel);/* FREQSEL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to MPU DPLL param table*/ + dpll_param_p = (dpll_param *)get_mpu_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + 2*clk_index + sil_index; + /* MPU DPLL (unlocked already) */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +void secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +void try_unlock_memory(void) +{ + int mode; + + /* if GP device unlock device SRAM for general use */ + /* secure code breaks for Secure/Emulation device - HS/E/T*/ + mode = get_device_type(); + if (mode == GP_DEVICE) { + secure_unlock(); + } + return; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +void s_init(void) +{ + watchdog_init(); +#ifdef CONFIG_3430_AS_3410 + /* setup the scalability control register for + * 3430 to work in 3410 mode + */ + __raw_writel(0x5ABF,CONTROL_SCALABLE_OMAP_OCP); +#endif + try_unlock_memory(); + set_muxconf_regs(); + delay(100); + prcm_init(); + per_clocks_enable(); + + /* enable the DDRPHY clk */ + sr32((OMAP34XX_CTRL_BASE + 0x588), 15, 15, 0x1); + /* enable the EMIF4 clk */ + sr32((OMAP34XX_CTRL_BASE + 0x588), 14, 14, 0x1); + /* Enable the peripheral clocks */ + sr32((OMAP34XX_CTRL_BASE + 0x59C), 0, 4, 0xF); + sr32((OMAP34XX_CTRL_BASE + 0x59C), 8, 10, 0x7); + + /* bring cpgmac out of reset */ + sr32((OMAP34XX_CTRL_BASE + 0x598), 1, 1, 0x1); + + /* Configure the EMIF4 for our DDR */ + config_emif4_ddr(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); + + /* Enable UART2 clocks */ + sr32(CM_FCLKEN1_CORE, 14, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 14, 1, 0x1); + + /* Enable UART2 clocks */ + sr32(CM_FCLKEN_PER, 11, 1, 0x1); + sr32(CM_ICLKEN_PER, 11, 1, 0x1); +#endif + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); + + /* Enable MMC2 clocks */ + sr32(CM_FCLKEN1_CORE, 25, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 25, 1, 0x1); + + delay(1000); +} + +/* Set MUX for UART, GPMC, SDRC, GPIO */ + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ +#define MUX_DEFAULT()\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ + MUX_VAL(CP(sdrc_cke0), (M0)) /*SDRC_CKE0*/\ + MUX_VAL(CP(sdrc_cke1), (M0)) /*SDRC_CKE1*/\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /*GPMC_A1*/\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /*GPMC_A2*/\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /*GPMC_A3*/\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /*GPMC_A4*/\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /*GPMC_A5*/\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /*GPMC_A6*/\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /*GPMC_A7*/\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /*GPMC_A8*/\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /*GPMC_A9*/\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /*GPMC_A10*/\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /*GPMC_D0*/\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /*GPMC_D1*/\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /*GPMC_D2*/\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /*GPMC_D3*/\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /*GPMC_D4*/\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /*GPMC_D5*/\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /*GPMC_D6*/\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /*GPMC_D7*/\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /*GPMC_D8*/\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /*GPMC_D9*/\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /*GPMC_D10*/\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /*GPMC_D11*/\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /*GPMC_D12*/\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /*GPMC_D13*/\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /*GPMC_D14*/\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /*GPMC_D15*/\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /*GPMC_NCS0*/\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_NCS1*/\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_NCS2*/\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_NCS3*/\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /*GPMC_NCS4*/\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /*GPMC_NCS5*/\ + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTU | EN | M0)) /*GPMC_NCS6*/\ + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /*GPMC_NCS7*/\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /*GPMC_CLK*/\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_NADV_ALE*/\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_NOE*/\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_NWE*/\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /*GPMC_NBE0_CLE*/\ + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)) /*GPIO_61*/\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /*GPMC_NWP*/\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ + MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M4)) /*GPIO_64*/\ + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M4)) /*GPIO_65*/\ + MUX_VAL(CP(DSS_DATA18), (IEN | PTD | DIS | M4)) /*GPIO_88*/\ + MUX_VAL(CP(DSS_DATA19), (IEN | PTD | DIS | M4)) /*GPIO_89*/\ + MUX_VAL(CP(DSS_DATA20), (IEN | PTD | DIS | M4)) /*GPIO_90*/\ + MUX_VAL(CP(DSS_DATA21), (IEN | PTD | DIS | M4)) /*GPIO_91*/\ + MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ + MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ + MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ + MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ + MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ + /*Expansion card */\ + MUX_VAL(CP(MMC1_CLK), (IEN | PTU | EN | M0)) /*MMC1_CLK*/\ + MUX_VAL(CP(MMC1_CMD), (IEN | PTU | DIS | M0)) /*MMC1_CMD*/\ + MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | DIS | M0)) /*MMC1_DAT0*/\ + MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | DIS | M0)) /*MMC1_DAT1*/\ + MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | DIS | M0)) /*MMC1_DAT2*/\ + MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | DIS | M0)) /*MMC1_DAT3*/\ + MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | DIS | M0)) /*MMC1_DAT4*/\ + MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | DIS | M0)) /*MMC1_DAT5*/\ + MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | DIS | M0)) /*MMC1_DAT6*/\ + MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | DIS | M0)) /*MMC1_DAT7*/\ + MUX_VAL(CP(McBSP1_DX), (IEN | PTD | DIS | M4)) /*GPIO_158*/\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /*GPIO_8 */\ + MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M4)) /*GPIO_186*/\ + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ + MUX_VAL(CP(ETK_CLK), (IEN | PTD | DIS | M4)) /*GPIO_12*/\ + MUX_VAL(CP(ETK_CTL), (IEN | PTD | DIS | M4)) /*GPIO_13*/\ + MUX_VAL(CP(ETK_D0 ), (IEN | PTD | DIS | M4)) /*GPIO_14*/\ + MUX_VAL(CP(ETK_D1 ), (IEN | PTD | DIS | M4)) /*GPIO_15*/\ + MUX_VAL(CP(ETK_D2 ), (IEN | PTD | DIS | M4)) /*GPIO_16*/\ + MUX_VAL(CP(ETK_D10), (IEN | PTD | DIS | M4)) /*GPIO_24*/\ + MUX_VAL(CP(ETK_D11), (IEN | PTD | DIS | M4)) /*GPIO_25*/\ + MUX_VAL(CP(ETK_D12), (IEN | PTD | DIS | M4)) /*GPIO_26*/\ + MUX_VAL(CP(ETK_D13), (IEN | PTD | DIS | M4)) /*GPIO_27*/\ + MUX_VAL(CP(ETK_D14), (IEN | PTD | DIS | M4)) /*GPIO_28*/\ + MUX_VAL(CP(ETK_D15), (IEN | PTD | DIS | M4)) /*GPIO_29*/ + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware. Many pins need + * to be moved from protect to primary mode. + *********************************************************/ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} + +/********************************************************** + * Routine: nand+_init + * Description: Set up nand for nand and jffs2 commands + *********************************************************/ + +int nand_init(void) +{ + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ + + /* Set the GPMC Vals . For NAND boot on 3430SDP, NAND is mapped at CS0 + * , NOR at CS1 and MPDB at CS3. And oneNAND boot, we map oneNAND at CS0. + * We configure only GPMC CS0 with required values. Configiring other devices + * at other CS in done in u-boot anyway. So we don't have to bother doing it here. + */ + __raw_writel(0 , GPMC_CONFIG7 + GPMC_CONFIG_CS0); + delay(1000); + + if ((get_mem_type() == GPMC_NAND) || (get_mem_type() == MMC_NAND)){ + __raw_writel( M_NAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((NAND_BASE_ADR>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); + + if (nand_chip()){ +#ifdef CFG_PRINTF + printf("Unsupported Chip!\n"); +#endif + return 1; + } + + } + + if ((get_mem_type() == GPMC_ONENAND) || (get_mem_type() == MMC_ONENAND)){ + __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((ONENAND_BASE>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); + + if (onenand_chip()){ +#ifdef CFG_PRINTF + printf("OneNAND Unsupported !\n"); +#endif + return 1; + } + } + return 0; +} + + +typedef int (mmc_boot_addr) (void); +int mmc_boot(unsigned char *buf) +{ + + long size = 0; +#ifdef CFG_CMD_FAT + block_dev_desc_t *dev_desc = NULL; + unsigned char ret = 0; + + printf("Starting X-loader on MMC \n"); + + ret = mmc_init(1); + if(ret == 0){ + printf("\n MMC init failed \n"); + return 0; + } + + dev_desc = mmc_get_dev(0); + fat_register_device(dev_desc, 1); + size = file_fat_read("u-boot.bin", buf, 0); + if (size == -1) { + return 0; + } + printf("\n%ld Bytes Read from MMC \n", size); + + printf("Starting OS Bootloader from MMC...\n"); +#endif + return size; +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{ while (0) {};}
diff --git a/x-loader/board/am3517evm/config.mk b/x-loader/board/am3517evm/config.mk new file mode 100644 index 0000000..0a212a4 --- /dev/null +++ b/x-loader/board/am3517evm/config.mk
@@ -0,0 +1,19 @@ +# (C) Copyright 2009 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40200800
diff --git a/x-loader/board/am3517evm/platform.S b/x-loader/board/am3517evm/platform.S new file mode 100644 index 0000000..c98f6e7 --- /dev/null +++ b/x-loader/board/am3517evm/platform.S
@@ -0,0 +1,436 @@ +/* + * Board specific setup info + * + * (C) Copyright 2009 + * Texas Instruments, <www.ti.com> + * Manikandan Pillai <mani.pillai@ti.com> + * This file is copied from board/omap3evm/platform.S + * + * 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 <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL + +#endif + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr +
diff --git a/x-loader/board/am3517evm/x-load.lds b/x-loader/board/am3517evm/x-load.lds new file mode 100644 index 0000000..d2e0ce5 --- /dev/null +++ b/x-loader/board/am3517evm/x-load.lds
@@ -0,0 +1,52 @@ +/* + * (C) Copyright 2009 + * Manikandan Pillai<mani.pillai@ti.com> + * This file is copied from board/omap3evm/x-load.lds + * + * 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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/nest/diamond-usb-loader/Makefile b/x-loader/board/nest/diamond-usb-loader/Makefile new file mode 100644 index 0000000..7eb6795 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/Makefile
@@ -0,0 +1,62 @@ +# +# Copyright (c) 2010-2011 Nest Labs, Inc. +# All rights reserved. +# +# Description: +# This file is the make file for portions of X-Loader specific +# to the Nest Learning Thermostat board. +# + +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +COBJS := diamond.o mux.o prcm.o +SOBJS := platform.o + +CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(SOBJS) $(OBJS) + $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/nest/diamond-usb-loader/config.mk b/x-loader/board/nest/diamond-usb-loader/config.mk new file mode 100644 index 0000000..b14e459 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/config.mk
@@ -0,0 +1,22 @@ + + +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40200000 +STACK_BASE = 0x4020FCB0
diff --git a/x-loader/board/nest/diamond-usb-loader/diamond.c b/x-loader/board/nest/diamond-usb-loader/diamond.c new file mode 100644 index 0000000..d457795 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/diamond.c
@@ -0,0 +1,1047 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703ACUS, focusing + * primarily on GPIO, RAM and flash initialization. + * + * This is inherited from the OMAP3 EVM equivalent file. + * + * Initialization function order is roughly: + * + * 1) s_init + * 2) board_init + * 3) misc_init_r + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +#include "platform.h" + +#define MAX_DIAMOND_BOOT_DEVICES (3) + + +void +udelay(unsigned long usecs) { + delay(usecs); +} + +static inline u32 +get_cpu_id(void) +{ + u32 cpuid = 0; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + + return (cpuid); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 +get_cpu_rev(void) +{ + const u32 cpuid = get_cpu_id(); + + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + if ((cpuid & 0xf) == 0x0) { + return (CPU_3430_ES1); + + } else { + return (CPU_3430_ES2); + + } + +} + +u32 +is_cpu_family(void) +{ + const u32 cpuid = get_cpu_id(); + u32 cpu_family = 0, omap34xx_id = 0; + u16 hawkeye; + + if ((cpuid & 0xf) == 0x0) { + cpu_family = CPU_OMAP34XX; + + } else { + omap34xx_id = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (omap34xx_id >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + + case HAWKEYE_AM35XX: + cpu_family = CPU_AM35XX; + break; + + case HAWKEYE_OMAP36XX: + cpu_family = CPU_OMAP36XX; + break; + + case HAWKEYE_OMAP34XX: + default: + cpu_family = CPU_OMAP34XX; + break; + + } + } + + return (cpu_family); +} +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 +cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/* + * void sr32() + * + * Description: + * This routine clears and sets a value in a bit extent for a + * 32-bit value at the specified address. + * + * Input(s): + * addr - The address at which to clear and set the specified + * specified 32-bit value. + * start_bit - The first bit of the 32-bit data to clear and set. + * num_bits - The range of bits of the 32-bit data to clear and set. + * value - The value to set. + * + * Output(s): + * addr - The address with the specified bit extent cleared and + * set to the specified value. + * + * Returns: + * N/A + * + */ +void +sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + + msk = (1 << num_bits); + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/* + * u32 wait_on_value() + * + * Description: + * This routine reads the register at the specified address and + * busy waits until the specified match value is read or until the + * bounded number of loops have been reached. + * + * Input(s): + * read_bit_mask - The bit mask to apply after reading the register. + * match_value - The value to match on after reading and masking. + * read_addr - The register address to read. + * bound - The maximum number of times to read before giving + * up. + * + * Output(s): + * N/A + * + * Returns: + * True (1) if the match_value was reached; otherwise, false (0). + * + */ +u32 +wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +static void +secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +static void +try_unlock_memory(void) +{ + const int type = get_device_type(); + + /* + * If the processor is a GP device, unlock the device SRAM for + * general use. + */ + + if (type == CONTROL_STATUS_DEVICETYPE_GP) { + secure_unlock(); + } + + return; +} + +#if defined(CFG_SDRAM_DEBUG) +static void +omap3_sdrc_register_dump(void) +{ + printf("\n SDRC Register Dump:\n"); + + DUMP_REGL(SDRC_REVISION); + DUMP_REGL(SDRC_SYSCONFIG); + DUMP_REGL(SDRC_SYSSTATUS); + DUMP_REGL(SDRC_CS_CFG); + DUMP_REGL(SDRC_SHARING); + DUMP_REGL(SDRC_ERR_ADDR); + DUMP_REGL(SDRC_ERR_TYPE); + DUMP_REGL(SDRC_DLLA_CTRL); + DUMP_REGL(SDRC_DLLA_STATUS); + DUMP_REGL(SDRC_POWER_REG); + DUMP_REGL(SDRC_MCFG_0); + DUMP_REGL(SDRC_MR_0); + DUMP_REGL(SDRC_EMR2_0); + DUMP_REGL(SDRC_ACTIM_CTRLA_0); + DUMP_REGL(SDRC_ACTIM_CTRLB_0); + DUMP_REGL(SDRC_RFR_CTRL_0); + DUMP_REGL(SDRC_MANUAL_0); + DUMP_REGL(SDRC_MCFG_1); + DUMP_REGL(SDRC_MR_1); + DUMP_REGL(SDRC_EMR2_1); + DUMP_REGL(SDRC_ACTIM_CTRLA_1); + DUMP_REGL(SDRC_ACTIM_CTRLB_1); + DUMP_REGL(SDRC_RFR_CTRL_1); + DUMP_REGL(SDRC_MANUAL_1); +} +#else +# define omap3_sdrc_register_dump() do { } while (0) +#endif /* defined(CFG_SDRAM_DEBUG) */ + +#if defined(CFG_GPMC_DEBUG) +static void +omap3_gpmc_register_dump(void) +{ + printf("\n GPMC Register Dump:\n"); + + DUMP_REGL(GPMC_REVISION); + DUMP_REGL(GPMC_SYSCONFIG); + DUMP_REGL(GPMC_SYSSTATUS); + DUMP_REGL(GPMC_IRQSTATUS); + DUMP_REGL(GPMC_IRQENABLE); + DUMP_REGL(GPMC_TIMEOUT_CONTROL); + DUMP_REGL(GPMC_ERR_ADDRESS); + DUMP_REGL(GPMC_ERR_TYPE ); + DUMP_REGL(GPMC_CONFIG ); + DUMP_REGL(GPMC_STATUS ); + + DUMP_REGL(GPMC_CONFIG1_0); + DUMP_REGL(GPMC_CONFIG2_0); + DUMP_REGL(GPMC_CONFIG3_0); + DUMP_REGL(GPMC_CONFIG4_0); + DUMP_REGL(GPMC_CONFIG5_0); + DUMP_REGL(GPMC_CONFIG6_0); + DUMP_REGL(GPMC_CONFIG7_0); + + DUMP_REGL(GPMC_CONFIG1_1); + DUMP_REGL(GPMC_CONFIG2_1); + DUMP_REGL(GPMC_CONFIG3_1); + DUMP_REGL(GPMC_CONFIG4_1); + DUMP_REGL(GPMC_CONFIG5_1); + DUMP_REGL(GPMC_CONFIG6_1); + DUMP_REGL(GPMC_CONFIG7_1); + + DUMP_REGL(GPMC_CONFIG1_2); + DUMP_REGL(GPMC_CONFIG2_2); + DUMP_REGL(GPMC_CONFIG3_2); + DUMP_REGL(GPMC_CONFIG5_2); + DUMP_REGL(GPMC_CONFIG4_2); + DUMP_REGL(GPMC_CONFIG6_2); + DUMP_REGL(GPMC_CONFIG7_2); + + DUMP_REGL(GPMC_CONFIG1_3); + DUMP_REGL(GPMC_CONFIG2_3); + DUMP_REGL(GPMC_CONFIG3_3); + DUMP_REGL(GPMC_CONFIG4_3); + DUMP_REGL(GPMC_CONFIG5_3); + DUMP_REGL(GPMC_CONFIG6_3); + DUMP_REGL(GPMC_CONFIG7_3); + + DUMP_REGL(GPMC_CONFIG1_4); + DUMP_REGL(GPMC_CONFIG2_4); + DUMP_REGL(GPMC_CONFIG3_4); + DUMP_REGL(GPMC_CONFIG4_4); + DUMP_REGL(GPMC_CONFIG5_4); + DUMP_REGL(GPMC_CONFIG6_4); + DUMP_REGL(GPMC_CONFIG7_4); + + DUMP_REGL(GPMC_CONFIG1_5); + DUMP_REGL(GPMC_CONFIG2_5); + DUMP_REGL(GPMC_CONFIG3_5); + DUMP_REGL(GPMC_CONFIG4_5); + DUMP_REGL(GPMC_CONFIG5_5); + DUMP_REGL(GPMC_CONFIG6_5); + DUMP_REGL(GPMC_CONFIG7_5); + + DUMP_REGL(GPMC_CONFIG1_6); + DUMP_REGL(GPMC_CONFIG2_6); + DUMP_REGL(GPMC_CONFIG3_6); + DUMP_REGL(GPMC_CONFIG4_6); + DUMP_REGL(GPMC_CONFIG5_6); + DUMP_REGL(GPMC_CONFIG6_6); + DUMP_REGL(GPMC_CONFIG7_6); + + DUMP_REGL(GPMC_CONFIG1_7); + DUMP_REGL(GPMC_CONFIG2_7); + DUMP_REGL(GPMC_CONFIG3_7); + DUMP_REGL(GPMC_CONFIG4_7); + DUMP_REGL(GPMC_CONFIG5_7); + DUMP_REGL(GPMC_CONFIG6_7); + DUMP_REGL(GPMC_CONFIG7_7); + +#if 0 + DUMP_REGL(GPMC_NAND_COMMAND_0); + DUMP_REGL(GPMC_NAND_COMMAND_1); + DUMP_REGL(GPMC_NAND_COMMAND_2); + DUMP_REGL(GPMC_NAND_COMMAND_3); + DUMP_REGL(GPMC_NAND_COMMAND_4); + DUMP_REGL(GPMC_NAND_COMMAND_5); + DUMP_REGL(GPMC_NAND_COMMAND_6); + DUMP_REGL(GPMC_NAND_COMMAND_7); + + DUMP_REGL(GPMC_NAND_ADDRESS_0); + DUMP_REGL(GPMC_NAND_ADDRESS_1); + DUMP_REGL(GPMC_NAND_ADDRESS_2); + DUMP_REGL(GPMC_NAND_ADDRESS_3); + DUMP_REGL(GPMC_NAND_ADDRESS_4); + DUMP_REGL(GPMC_NAND_ADDRESS_5); + DUMP_REGL(GPMC_NAND_ADDRESS_6); + DUMP_REGL(GPMC_NAND_ADDRESS_7); + + DUMP_REGL(GPMC_NAND_DATA_0); + DUMP_REGL(GPMC_NAND_DATA_1); + DUMP_REGL(GPMC_NAND_DATA_2); + DUMP_REGL(GPMC_NAND_DATA_3); + DUMP_REGL(GPMC_NAND_DATA_4); + DUMP_REGL(GPMC_NAND_DATA_5); + DUMP_REGL(GPMC_NAND_DATA_6); + DUMP_REGL(GPMC_NAND_DATA_7); + + DUMP_REGL(GPMC_PREFETCH_CONFIG1); + DUMP_REGL(GPMC_PREFETCH_CONFIG2); + DUMP_REGL(GPMC_PREFETCH_CONTROL); + DUMP_REGL(GPMC_PREFETCH_STATUS); + + DUMP_REGL(GPMC_ECC_CONFIG); + DUMP_REGL(GPMC_ECC_CONTROL); + DUMP_REGL(GPMC_ECC_SIZE_CONFIG); + + DUMP_REGL(GPMC_ECC1_RESULT); + DUMP_REGL(GPMC_ECC2_RESULT); + DUMP_REGL(GPMC_ECC3_RESULT); + DUMP_REGL(GPMC_ECC4_RESULT); + DUMP_REGL(GPMC_ECC5_RESULT); + DUMP_REGL(GPMC_ECC6_RESULT); + DUMP_REGL(GPMC_ECC7_RESULT); + DUMP_REGL(GPMC_ECC8_RESULT); + DUMP_REGL(GPMC_ECC9_RESULT); + + DUMP_REGL(GPMC_BCH_RESULT0_0); + DUMP_REGL(GPMC_BCH_RESULT0_1); + DUMP_REGL(GPMC_BCH_RESULT0_2); + DUMP_REGL(GPMC_BCH_RESULT0_3); + DUMP_REGL(GPMC_BCH_RESULT0_4); + DUMP_REGL(GPMC_BCH_RESULT0_5); + DUMP_REGL(GPMC_BCH_RESULT0_6); + DUMP_REGL(GPMC_BCH_RESULT0_7); + + DUMP_REGL(GPMC_BCH_RESULT1_0); + DUMP_REGL(GPMC_BCH_RESULT1_1); + DUMP_REGL(GPMC_BCH_RESULT1_2); + DUMP_REGL(GPMC_BCH_RESULT1_3); + DUMP_REGL(GPMC_BCH_RESULT1_4); + DUMP_REGL(GPMC_BCH_RESULT1_5); + DUMP_REGL(GPMC_BCH_RESULT1_6); + DUMP_REGL(GPMC_BCH_RESULT1_7); + + DUMP_REGL(GPMC_BCH_RESULT2_0); + DUMP_REGL(GPMC_BCH_RESULT2_1); + DUMP_REGL(GPMC_BCH_RESULT2_2); + DUMP_REGL(GPMC_BCH_RESULT2_3); + DUMP_REGL(GPMC_BCH_RESULT2_4); + DUMP_REGL(GPMC_BCH_RESULT2_5); + DUMP_REGL(GPMC_BCH_RESULT2_6); + DUMP_REGL(GPMC_BCH_RESULT2_7); + + DUMP_REGL(GPMC_BCH_RESULT3_0); + DUMP_REGL(GPMC_BCH_RESULT3_1); + DUMP_REGL(GPMC_BCH_RESULT3_2); + DUMP_REGL(GPMC_BCH_RESULT3_3); + DUMP_REGL(GPMC_BCH_RESULT3_4); + DUMP_REGL(GPMC_BCH_RESULT3_5); + DUMP_REGL(GPMC_BCH_RESULT3_6); + DUMP_REGL(GPMC_BCH_RESULT3_7); + + DUMP_REGL(GPMC_BCH_SWDATA); +#endif +} +#else +# define omap3_gpmc_register_dump() do { } while (0) +#endif /* defined(CFG_NAND_DEBUG) */ + +#if defined(CFG_PRCM_DEBUG) +static void +omap3_prcm_register_dump(void) +{ + printf("\n PRCM Register Dump:\n"); + + DUMP_REGL(PRCM_PRM_CCR_CLKSEL); + DUMP_REGL(PRCM_PRM_GR_CLKSRC_CTRL); + DUMP_REGL(CM_CLKSEL1_PLL); + DUMP_REGL(CM_CLKSEL2_PLL); + DUMP_REGL(CM_CLKSEL3_PLL); + DUMP_REGL(CM_CLKEN_PLL); + DUMP_REGL(CM_CLKSEL1_PLL_MPU); + DUMP_REGL(CM_CLKSEL2_PLL_MPU); + DUMP_REGL(CM_CLKEN_PLL_MPU); + DUMP_REGL(CM_CLKSEL1_PLL_IVA2); + DUMP_REGL(CM_CLKSEL2_PLL_IVA2); + DUMP_REGL(CM_CLKEN_PLL_IVA2); + DUMP_REGL(CM_CLKSEL_CAM); + DUMP_REGL(CM_CLKSEL_CORE); + DUMP_REGL(CM_CLKSEL_DSS); + DUMP_REGL(CM_CLKSEL1_EMU); +} +#else +#define omap3_prcm_register_dump() do { } while (0) +#endif /* CFG_PRCM_DEBUG */ + +/* + * void config_diamond_sdram() + * + * Description: + * This routine initializes the processor's SDRAM Controller (SDRC) + * as appropriate for the Samsung K4X51163PI-FCG6 32 Mb x 16 b (64 + * MiB) DDR SDRAM on the Nest Learning Thermostat board. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +config_diamond_sdram(void) +{ + u32 value, actim_ctrla, actim_ctrlb; + + /* + * Step 1: Reset the SDRC controller and then wait for the reset + * event to clear. + */ + + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_SET, SDRC_SYSCONFIG); + wait_on_value(SDRC_SYSSTATUS_RESETDONE, + SDRC_SYSSTATUS_RESETDONE, + SDRC_STATUS, + 12000000); + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_CLEAR, SDRC_SYSCONFIG); + + /* + * Step 2: Setup the position and geometry of the SDRAM device on + * the controller's bus. + */ + + value = + (SDRC_SHARING_LOCK_OFF | + SDRC_SHARING_CS1MUXCFG_ENCODE(SDRC_SHARING_CS1MUXCFG_16_BIT_16_0) | + SDRC_SHARING_CS0MUXCFG_ENCODE(SDRC_SHARING_CS0MUXCFG_16_BIT_16_0) | + SDRC_SHARING_SDRCTRISTATE_OFF); + __raw_writel(value, SDRC_SHARING); + + /* + * Step 3: Setup the memory configuration, including RAS width, + * CAS width, address multiplexing, size, bank mapping, bus width, + * power mode, DDR type and memory type. + */ + + value = + (SDRC_MCFG_LOCKSTATUS_RW | + SDRC_MCFG_RASWIDTH_ENCODE(SDRC_MCFG_RASWIDTH_14_BITS) | + SDRC_MCFG_CASWIDTH_ENCODE(SDRC_MCFG_CASWIDTH_10_BITS) | + SDRC_MCFG_ADDRMUXLEGACY_FLEXIBLE | + SDRC_MCFG_RAMSIZE_ENCODE(CFG_SDRAM_SIZE_MB) | + SDRC_MCFG_BANKALLOCATION_ENCODE(SDRC_MCFG_BANKALLOCATION_R_B_C)| + SDRC_MCFG_B32NOT16_OFF | + SDRC_MCFG_DEEPPD_SUPPORTED | + SDRC_MCFG_DDRTYPE_ENCODE(SDRC_MCFG_DDRTYPE_MOBILE_DDR) | + SDRC_MCFG_RAMTYPE_ENCODE(SDRC_MCFG_RAMTYPE_DDR)); + __raw_writel(value, SDRC_MCFG_0); + + /* + * Step 4: Establish the AC fine tuning timing characteristics. + */ + + actim_ctrla + = (SDRC_ACTIM_CTRLA_TRFC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRFC) | + SDRC_ACTIM_CTRLA_TRC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRC) | + SDRC_ACTIM_CTRLA_TRAS_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRAS) | + SDRC_ACTIM_CTRLA_TRP_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRP) | + SDRC_ACTIM_CTRLA_TRCD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRCD) | + SDRC_ACTIM_CTRLA_TRRD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRRD) | + SDRC_ACTIM_CTRLA_TDPL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDPL) | + SDRC_ACTIM_CTRLA_TDAL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDAL)); + + actim_ctrlb + = (SDRC_ACTIM_CTRLB_TWTR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TWTR) | + SDRC_ACTIM_CTRLB_TCKE_ENCODE(CFG_SDRC_ACTIM_CTRLB_TCKE) | + SDRC_ACTIM_CTRLB_TXP_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXP) | + SDRC_ACTIM_CTRLB_TXSR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXSR)); + + __raw_writel(actim_ctrla, SDRC_ACTIM_CTRLA_0); + __raw_writel(actim_ctrlb, SDRC_ACTIM_CTRLB_0); + + /* + * Step 5: Establish the memory autorefresh control + */ + + value = + (SDRC_RFR_CTRL_ARCV_ENCODE(1244) | + SDRC_RFR_CTRL_ARE_ENCODE(SDRC_RFR_CTRL_ARE_1_ARCV)); + __raw_writel(value, SDRC_RFR_CTRL_0); + + value = + (SDRC_POWER_REG_WAKEUP_DELAYED | + SDRC_POWER_REG_AUTOCOUNT_ENCODE(0) | + SDRC_POWER_REG_SRFR_ON_RST_ENABLE | + SDRC_POWER_REG_SRFR_ON_IDLE_DISABLE | + SDRC_POWER_REG_CLKCTRL_ENCODE(SDRC_POWER_REG_CLKCTRL_NONE) | + SDRC_POWER_REG_PAGEPOLICY_HPHB); + __raw_writel(value, SDRC_POWER_REG); + + /* + * Step 6: Establish the JEDEC-defined mode and DLL parameters. + */ + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + delay(5000); + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_PRECHARGE_ALL), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + value = + (SDRC_MR_ZERO_1 | + SDRC_MR_WBST_ENABLE | + SDRC_MR_ZERO_0 | + SDRC_MR_CASL_ENCODE(SDRC_MR_CASL_3) | + SDRC_MR_SIL_SERIAL | + SDRC_MR_BL_ENCODE(SDRC_MR_BL_4)); + __raw_writel(value, SDRC_MR_0); + + value = + (SDRC_DLLA_CTRL_FIXED_DELAY_ENCODE(0) | + SDRC_DLLA_CTRL_INIT_LAT_ENCODE(0) | + SDRC_DLLA_CTRL_MODE_ON_IDLE_ENCODE(SDRC_DLLA_CTRL_MODE_ON_IDLE_PWD) | + SDRC_DLLA_CTRL_DLL_ENABLE | + SDRC_DLLA_CTRL_LOCK_TRACKINGDELAY); + __raw_writel(value, SDRC_DLLA_CTRL); + + /* + * Delay for a "reasonably long" period of time to allow the + * requested changes to take effect. + */ + + delay(0x20000); +} + +/* + * void s_init() + * + * Description: + * This routine performs very early system initialization of chip + * pin multiplexing and clocks and is called when ONLY an + * SRAM-based stack is available (i.e. no SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +s_init(void) +{ + watchdog_init(); + try_unlock_memory(); + set_muxconf_regs(); + + delay(100); + + prcm_init(); + per_clocks_enable(); + config_diamond_sdram(); +} + +/* + * int board_init() + * + * Description: + * This routine performs any early, board-specific initialization + * following core CPU initialization but prior to serial and NAND + * initialization. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +board_init(void) +{ + return (0); +} + +/* + * u32 get_device_type() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register DEVICETYPE field, indicating whether the + * device is of TST, EMU, HS or GP type. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register DEVICETYPE field. + * + */ +u32 +get_device_type(void) +{ + const int value = __raw_readl(CONTROL_STATUS); + + return (CONTROL_STATUS_DEVICETYPE_DECODE(value)); +} + +/* + * u32 get_sysboot_value() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register SYSBOOT order subfield, indicating the + * order of memory interfaces from which the processor will attempt + * to boot itself. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register SYSBOOT order subfield. + * + */ +u32 +get_sysboot_value(void) +{ +#if 0 + const u32 value = __raw_readl(CONTROL_STATUS); + const u32 peripheral_type = CONTROL_STATUS_SYSBOOT_TYPE_PERIPHERAL; + + /* + * This routine and callers of it are implicitly expecting the + * MEMORY interface (SYSBOOT[5] == 0) not the PERHIPHERAL + * interface (SYSBOOT[5] == 1) boot order, so check that is + * actually the case. + */ + + if (CONTROL_STATUS_SYSBOOT_TYPE_DECODE(value) == peripheral_type) { + hang(); + } + + return (CONTROL_STATUS_SYSBOOT_ORDER_DECODE(value)); +#else + return __raw_readl(CONTROL_STATUS) & 0x3f; +#endif +} + +/* + * int get_boot_device_list(const u32** device_list) + * + * Description: + * This routine returns a constant list indicating the preferred + * device boot list. + * It gets called from start_armboot in board.c + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The preferred first processor memory boot interface. + * + */ + +int +get_boot_devices_list(const u32** devices_list) +{ + static u32 list[MAX_DIAMOND_BOOT_DEVICES]; + const u32 mem_order = get_sysboot_value(); + + // set defaults + int number_of_devices = 0; + *devices_list = &list[0]; + + switch (mem_order) { + case 15: + list[0] = GPMC_NAND; + list[1] = USB_PERIPHERAL; + list[2] = MMC_NAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 47: + list[0] = USB_PERIPHERAL; + list[1] = MMC_NAND; + list[2] = GPMC_NAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + default: + break; + } + return number_of_devices; +} + +/* + * int misc_init_r() + * + * Description: + * This routine performs any miscellaneous, board-specific + * initialization following CPU, early board, serial and NAND + * initialization but prior to loading the secondary program loader + * to RAM. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +misc_init_r(void) +{ + return (0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void +wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void +watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +/* + * void foobar() + * + * Description: + * This routine... + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + +#ifdef CONFIG_MMC + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); +#endif + delay(1000); +} + +static int +gpmc_config_0(void) +{ +#if defined(CFG_GPMC_CONFIG1_0) + /* + * First, disable the interface and wait. + */ + __raw_writel(GPMC_CONFIG7_CSVALID_DISABLED, GPMC_CONFIG7_0); + + delay(1000); + + /* + * Next, program the configuration parameters. + */ + __raw_writel(CFG_GPMC_CONFIG1_0, GPMC_CONFIG1_0); + __raw_writel(CFG_GPMC_CONFIG2_0, GPMC_CONFIG2_0); + __raw_writel(CFG_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(CFG_GPMC_CONFIG4_0, GPMC_CONFIG4_0); + __raw_writel(CFG_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __raw_writel(CFG_GPMC_CONFIG6_0, GPMC_CONFIG6_0); + + /* + * Finally, enable the GPMC mapping and spin for the parameters to + * become active. + */ + __raw_writel((CFG_GPMC_CONFIG7_0 | GPMC_CONFIG7_CSVALID_ENABLED), + GPMC_CONFIG7_0); + + delay(2000); + + if (nand_chip()){ + return (1); + } +#endif /* defined(CFG_GPMC_CONFIG1_0) */ + + return (0); +} + +/* + * int nand_init() + * + * Description: + * This routine initializes the General Purpose Memory Controller + * (GPMC) such that on-board NAND devices may be accessed for + * second-stage boot. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if NAND was successfully initialized; otherwise, 1. + * + */ +int +nand_init(void) +{ + int status = 1; + + /* + * Establish GPMC global settings. + */ + + __raw_writel(GPMC_SYSCONFIG_IDLEMODE_SMART, GPMC_SYSCONFIG); + + __raw_writel(GPMC_IRQENABLE_ALL_DISABLE, GPMC_IRQENABLE); + + __raw_writel(GPMC_TIMEOUTENABLE_OFF, GPMC_TIMEOUT_CONTROL); + + if (gpmc_config_0()) { + puts("Unsupported NAND device @ GPMC0!\n"); + goto done; + } + + status = 0; + + done: + /* Dump GPMC and SDRC registers if so configured. */ + + omap3_sdrc_register_dump(); + omap3_gpmc_register_dump(); + omap3_prcm_register_dump(); + + return (status); +} + +/* + * void board_hang() + * + * Description: + * This routine performs any board-specific actions when the system + * hangs by executing hang(). At present, there is nothing to do; + * however, we might later drive the piezo or a LED. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +board_hang (void) +{ + return; +}
diff --git a/x-loader/board/nest/diamond-usb-loader/mux.c b/x-loader/board/nest/diamond-usb-loader/mux.c new file mode 100644 index 0000000..42f92f9 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/mux.c
@@ -0,0 +1,314 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily I/O pad multiplexer configuration. + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> + +#include "platform.h" + +/* + * void set_muxconf_regs() + * + * Description: + * This routines sets the I/O pad multiplexers for UART, GPMC, SDRC, + * GPIO. + * + * The commented string gives the final mux configuration for that pin + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + */ +void +set_muxconf_regs(void) +{ + /* + * The bit fields for these settings are as follows: + * + * I{EN,DIS} - Input Enable/Disable + * PT[DU] - Pull-down, -up + * DIS,EN - Pull-down, -up disabled/enabled + * M[01234567] - Configuration mode 0-7 + */ + + /* + * SDRAM Controller (SDRC) + * + * Most of the SDRC signals are used to drive the Samsung + * K4X51163PI-FCG6 512 Mb x 16-bit (64 MiB) DDR SDRAM. Because we + * interface in 16-bit rather than 32-bit mode, we place the + * unused pins in safe mode (Mode 7). + */ + + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)); // SDRC_D0 + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)); // SDRC_D1 + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)); // SDRC_D2 + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)); // SDRC_D3 + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)); // SDRC_D4 + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)); // SDRC_D5 + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)); // SDRC_D6 + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)); // SDRC_D7 + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)); // SDRC_D8 + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)); // SDRC_D9 + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)); // SDRC_D10 + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)); // SDRC_D11 + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)); // SDRC_D12 + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)); // SDRC_D13 + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)); // SDRC_D14 + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)); // SDRC_D15 + + // Because we interface SDRAM in 16-bit mode, place + // SDRC_DATA[31:16] in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_D16), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D17), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D18), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D19), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D20), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D21), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D22), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D23), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D24), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D25), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D26), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D27), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D28), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D29), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D30), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D31), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)); // SDRC_CLK + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)); // SDRC_DQS0 + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)); // SDRC_DQS1 + + // Place unused DQ pins in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_DQS2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_DQS3), (IDIS | PTD | DIS | M7)); // Unused + + /* + * General Purpose Memory Controller (GPMC) + * + */ + + MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)); // GPMC_A1 + MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)); // GPMC_A2 + MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)); // GPMC_A3 + MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)); // GPMC_A4 + MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)); // GPMC_A5 + MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)); // GPMC_A6 + MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)); // GPMC_A7 + + // Place the unused GPMC_A8 pin in safe mode (Mode 7). + + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_A9 to GPIO_42 used as a push-pull, active low input + // from the USB PHY for USB suspend notification. + + MUX_VAL(CP(GPMC_A9), (IEN | PTU | DIS | M4)); // GPIO_42 + +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign GPMC_A10 to GPIO_43 used as push-pull, active low output + // LCD_nENBUFFER for the 1.8V to 3.3V LCD buffer enable. + + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M4)); // GPIO_43 +#else + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + + MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)); // GPMC_D0 + MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)); // GPMC_D1 + MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)); // GPMC_D2 + MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)); // GPMC_D3 + MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)); // GPMC_D4 + MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)); // GPMC_D5 + MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)); // GPMC_D6 + MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)); // GPMC_D7 + MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)); // GPMC_D8 + MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)); // GPMC_D9 + MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)); // GPMC_D10 + MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)); // GPMC_D11 + MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)); // GPMC_D12 + MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)); // GPMC_D13 + MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)); // GPMC_D14 + MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)); // GPMC_D15 + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)); // GPMC_nCS0 + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)); // GPMC_nCS1 + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)); // GPMC_nCS2 +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign to GPMC_NCS3 for Samsung K9F4G08U0C 512 MiB SLC NAND + // Flash + + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)); // GPMC_nCS3 +#else + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTD | DIS | M7)); // Unused +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign to GPMC_NCS5 for SMSC LAN9220 10/100 Mbit Ethernet MAC + // and PHY + + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)); // GPMC_nCS5 +#else + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + + // Assign GPMC_NCS6 to GPT11_PWM_EVT used as a push-pull pulse width + // modulated (PWM) signal for the piezo. + + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTD | DIS | M3)); // GPT11_PWM_EVT + + // Assign GPMC_NCS7 to GPIO_58 used as a push-pull output + // PIEZO_NENABLE to the TI SN74LVC2G240 Dual Buffer/Driver With + // 3-State Outputs inputs. + + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTD | DIS | M4)); // GPIO_58 + + MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)); // GPMC_CLK + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); // GPMC_nADV_ALE + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); // GPMC_nOE + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); // GPMC_nWE + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)); // GPMC_nBE0_CLE + + // Assign GPMC_NBE1 to GPIO_61 used as a push-pull output to the + // ZigBee active-low reset. + + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)); // GPIO_61 + + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)); // GPMC_nWP + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)); // GPMC_WAIT0 + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)); // GPMC_WAIT1 + MUX_VAL(CP(GPMC_WAIT2), (IDIS | PTD | DIS | M7)); // Unavailable + + // Assign GPMC_WAIT3 to GPIO_65 used as an active-high, push-pull + // backplate detect input. + + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTD | DIS | M4)); // GPIO_65 + + /* + * Display Subsystem (DSS) + * + * All DSS signals are used in their normal, default mode (Mode 0) + * to drive the Samsung LMS350DF0[13] LCD display panel. + */ + + MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)); // DSS_PCLK + MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)); // DSS_HSYNC + MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)); // DSS_VSYNC + MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)); // DSS_ACBIAS + MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)); // DSS_DATA0 + MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)); // DSS_DATA1 + MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)); // DSS_DATA2 + MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)); // DSS_DATA3 + MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)); // DSS_DATA4 + MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)); // DSS_DATA5 + MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)); // DSS_DATA6 + MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)); // DSS_DATA7 + MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)); // DSS_DATA8 + MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)); // DSS_DATA9 + MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)); // DSS_DATA10 + MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)); // DSS_DATA11 + MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)); // DSS_DATA12 + MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)); // DSS_DATA13 + MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)); // DSS_DATA14 + MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)); // DSS_DATA15 + MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)); // DSS_DATA16 + MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)); // DSS_DATA17 + MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)); // DSS_DATA18 + MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)); // DSS_DATA19 + MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)); // DSS_DATA20 + MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)); // DSS_DATA21 + MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)); // DSS_DATA22 + MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)); // DSS_DATA23 + + MUX_VAL(CP(CAM_WEN), (IDIS | PTD | DIS | M7)); // Unused + + /* + * Universal Asynchronous Receiver / Transmitter (UART) + * + */ + + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); // UART1_TX + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)); // UART1_RTS + MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)); // UART1_CTS + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)); // UART1_RX + /* + * Control and Debug + * + */ + + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)); // SYS_32K + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M0)); // SYS_BOOT0 + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M0)); // SYS_BOOT1 + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M0)); // SYS_BOOT2 + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M0)); // SYS_BOOT3 + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M0)); // SYS_BOOT4 + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M0)); // SYS_BOOT5 + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M0)); // SYS_BOOT6 + MUX_VAL(CP(SYS_CLKOUT1), (IDIS | PTU | EN | M0)); // SYS_CLKOUT1 + MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)); // JTAG_nTRST + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)); // JTAG_TCK + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)); // JTAG_TMS + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)); // JTAG_TDI + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)); // JTAG_EMU0 + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)); // JTAG_EMU1 + MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D0_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D1_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D2_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D3_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D4_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D5_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D6_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D7_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D8_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D9_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D12_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D13_ES2), (IDIS | PTD | DIS | M7)); // Unused + + // Assign ETK_D1[45] as MM2_RXRCV and MM2_TXSE0 USB FS/LS Host + // (Mode 5) + + MUX_VAL(CP(ETK_D14_ES2), (IEN | PTD | DIS | M5)); // MM2_RXRCV + MUX_VAL(CP(ETK_D15_ES2), (IEN | PTD | DIS | M5)); // MM2_TXSE0 +}
diff --git a/x-loader/board/nest/diamond-usb-loader/platform.S b/x-loader/board/nest/diamond-usb-loader/platform.S new file mode 100644 index 0000000..0549d27 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/platform.S
@@ -0,0 +1,557 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific setup for the Nest Learning + * Thermostat board. + * + * It inherits entirely from the equivalent TI OMAP3 EVM + * file. + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG1_0) +flash_cfg3_addr: + .word (GPMC_CONFIG3_0) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG4_0) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG5_0) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL +#endif /* !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) */ + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* + * Tables for 36x/37x devices + * + * (Populated for 13MHz only) + */ +mpu_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_MPU_DPLL_300MHZ) +.word 150, 5, 0, 1 // 12 MHz +.word 300, 12, 0, 1 // 13 MHz +.word 125, 7, 0, 1 // 19.2 MHz +.word 150, 12, 0, 1 // 26 MHz +.word 125, 15, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_MPU_DPLL_600MHZ) +.word 300, 5, 0, 1 // 12 MHz +.word 600, 12, 0, 1 // 13 MHz +.word 125, 3, 0, 1 // 19.2 MHz +.word 300, 12, 0, 1 // 26 MHz +.word 125, 7, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "MPU DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_MPU_DPLL_600MHZ) */ + +iva_36x_dpll_param: +// M N FS M2 +.word 10, 0, 0, 1 // 12 MHz +.word 10, 0, 0, 1 // 13 MHz +.word 10, 0, 0, 1 // 19.2 MHz +.word 10, 0, 0, 1 // 26 MHz +.word 10, 0, 0, 1 // 38.4 MHz +.word 10, 0, 0, 1 // 16.8 MHz + +core_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_CORE_DPLL_200MHZ) +.word 100, 5, 0, 1 // 12 MHz +.word 200, 12, 0, 1 // 13 MHz +.word 375, 35, 0, 1 // 19.2 MHz +.word 100, 12, 0, 1 // 26 MHz +.word 375, 71, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_332MHZ) +.word 166, 5, 0, 1 // 12 MHz +.word 332, 12, 0, 1 // 13 MHz +.word 415, 23, 0, 1 // 19.2 MHz +.word 166, 12, 0, 1 // 26 MHz +.word 415, 47, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_400MHZ) +.word 200, 5, 0, 1 // 12 MHz +.word 400, 12, 0, 1 // 13 MHz +.word 375, 17, 0, 1 // 19.2 MHz +.word 200, 12, 0, 1 // 26 MHz +.word 375, 35, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "Core DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_CORE_DPLL_400MHZ) */ + +/* + * For the peripheral (PER) (aka DPLL4) clock settings, there are only + * effectively two clock choices, 96 MHz or 192 MHz. However, the only + * time 192 MHz is apt to be used in an application is if both SGX and + * TV output are used. + * + * For any given system clock, the dividers are configured thus (per + * Section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" of the OMAP3 TRM): + * + * PER[clkout] = (SYS[clkout] * M) / (N + 1) + * + * M2[clkout]: PER[clkout] / M2 used by UART, MMC, I2C, etc. + * M3[clkout]: PER[clkout] / M3 used by TV out. + * M4[clkout]: PER[clkout] / M4 used by DSS. + * M5[clkout]: PER[clkout] / M5 used by camera. + * M6[clkout]: PER[clkout] / M6 used by emulation. + * + * So, for a 19.2 MHz system clock and the scalar entries below: + * + * PER[clkout] = (19.2 * 540) / (11 + 1) = 864 + * + * M2[clkout]: 864 / 9 = 96 MHz + * M3[clkout]: 864 / 16 = 54 MHz + * M4[clkout]: 864 / 5 = 172.8 MHz + * M5[clkout]: 864 / 4 = 216 MHz + * M6[clkout]: 864 / 3 = 288 MHz + */ +per_36x_dpll_param: +// SYS_CLK M N M2 M3 M4 M5 M6 m2DIV +.word 12000, 432, 5, 9, 16, 9, 4, 3, 1 // 12 MHz +.word 13000, 864, 12, 9, 16, 9, 4, 3, 1 // 13 MHz +.word 19200, 540, 11, 9, 16, 9, 4, 3, 1 // 19.2 MHz +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 // 26 MHz +.word 38400, 270, 11, 9, 16, 9, 4, 3, 1 // 38.4 MHz +.word 16800, 360, 6, 9, 16, 9, 4, 3, 1 // 16.8 MHz + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: + adr r0, mpu_36x_dpll_param + mov pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: + adr r0, iva_36x_dpll_param + mov pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: + adr r0, core_36x_dpll_param + mov pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: + adr r0, per_36x_dpll_param + mov pc, lr
diff --git a/x-loader/board/nest/diamond-usb-loader/platform.h b/x-loader/board/nest/diamond-usb-loader/platform.h new file mode 100644 index 0000000..c836e5a --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/platform.h
@@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines data structures and function prototypes for + * accessing Digital Phased Lock Loop (DPLL) parameters and + * settings. + * + */ + +#ifndef _NEST_DIAMOND_PLATFORM_H_ +#define _NEST_DIAMOND_PLATFORM_H_ + +#include <asm/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Type Definitions + */ + +/* Used to index into DPLL parameter tables */ + +struct dpll_param { + u32 m; + u32 n; + u32 fsel; + u32 m2; +}; + +struct dpll_per_36x_param { + u32 sys_clk; + u32 m; + u32 n; + u32 m2; + u32 m3; + u32 m4; + u32 m5; + u32 m6; + u32 m2div; +}; + +typedef struct dpll_param dpll_param; + +/* + * Inline Functions + */ +static inline void +delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + + +/* + * Function Prototypes + * + * The following functions are exported from platform.S. + */ + +extern dpll_param * get_mpu_dpll_param(void); +extern dpll_param * get_iva_dpll_param(void); +extern dpll_param * get_core_dpll_param(void); +extern dpll_param * get_per_dpll_param(void); + +extern dpll_param * get_36x_mpu_dpll_param(void); +extern dpll_param * get_36x_iva_dpll_param(void); +extern dpll_param * get_36x_core_dpll_param(void); +extern dpll_param * get_36x_per_dpll_param(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NEST_DIAMOND_PLATFORM_H_ */
diff --git a/x-loader/board/nest/diamond-usb-loader/prcm.c b/x-loader/board/nest/diamond-usb-loader/prcm.c new file mode 100644 index 0000000..5625ad7 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/prcm.c
@@ -0,0 +1,565 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily clock set-up for the processor's Power, Reset and + * Clock Manager (PRCM) + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +#include "platform.h" + +/* + * u32 get_osc_clk_speed() + * + * Description: + * This routine determines the reference oscillator speed based on + * a known 32 kHz clock and general purpose timer. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The reference oscillator clock speed. + * + */ +static u32 +get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & BIT7) + cdiv = 2; + else if (val & BIT6) + cdiv = 1; + else + /* + * Should never reach here! + * TBD: Add a WARN()/BUG() + * For now, assume divider as 1. + */ + cdiv = 1; + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/* + * void get_sys_clkin_sel() + * + * Description: + * This routine sets the value for the PRCM PRM system clock + * frequency selector, which should be written to PRM_CLKSEL. + * + * Input(s): + * hertz - The speed, in MHz, that the system clock is believed + * to be running at. + * sys_clkin_sel - A pointer to storage for the index used to access the + * digital PLL settings. + * + * Output(s): + * sys_clkin_sel - A pointer to the index for the digital PLL settings + * appropriate for the specified system clock rate. + * + * Returns: + * N/A + * + */ +static void +get_sys_clkin_sel(u32 hertz, u32 *sys_clkin_sel) +{ + switch (hertz) { + + case S38_4M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_38_4_MHZ; + break; + + case S26M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_26_0_MHZ; + break; + + case S19_2M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ; + break; + + case S16_8M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_16_8_MHZ; + break; + + case S13M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_13_0_MHZ; + break; + + case S12M: + default: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_12_0_MHZ; + break; + + } +} + +/* + * OMAP34x/35x specific functions + */ +static void +dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_34X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + ptr = (dpll_param *)get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + sr32(CM_CLKSEL2_PLL, 8, 11, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + sr32(CM_CLKEN_PLL, 20, 4, ptr->fsel); + + /* LOCK MODE (EN_PERIPH_DPLL) : CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, ptr->fsel); +} + +static void +iva_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, ptr->fsel); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ +static void +dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_36x_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr += clk_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_36X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct dpll_per_36x_param *ptr; + + ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + sr32(CM_CLKSEL1_EMU, 24, 6, ptr->m6); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + sr32(CM_CLKSEL_CAM, 0, 6, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + sr32(CM_CLKSEL_DSS, 0, 6, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + sr32(CM_CLKSEL_DSS, 8, 6, ptr->m3); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + sr32(CM_CLKSEL2_PLL, 8, 12, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + sr32(CM_CLKSEL_CORE, 12, 2, ptr->m2div); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_36x_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* LOCK MODE (EN_MPU_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); +} + +static void +iva_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * void prcm_init() + * + * Description: + * This routine initializes clocks in a board-specific manner for + * the processor's Power, Reset and Clock Manager (PRCM) and is + * called only when an SRAM-based stack is available (i.e. no + * SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +prcm_init(void) +{ + u32 sys_clk_rate = 0, sys_clkin_sel, sys_clk_div; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + sys_clk_rate = get_osc_clk_speed(); + get_sys_clkin_sel(sys_clk_rate, &sys_clkin_sel); + + /* Set the PRM_CLKSEL_SYS_CLKIN_SEL value in the processor. */ + + sr32(PRCM_PRM_CCR_CLKSEL, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_START, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS, + sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide by two. + * + * On OMAP3630, DDR data corruption has been observed on OFF mode + * exit if the sys clock was lower than 26M. As a work around, + * OMAP3630 is operated at 26M sys clock and this internal division + * is not performed. + */ + + if((is_cpu_family() != CPU_OMAP36XX) && + (sys_clkin_sel > PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ)) { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_2; + clk_index = sys_clkin_sel / 2; + + } else { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_1; + clk_index = sys_clkin_sel / 1; + + } + + sr32(PRCM_PRM_GR_CLKSRC_CTRL, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_START, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS, + sys_clk_div); + + if (is_cpu_family() == CPU_OMAP36XX) { + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + + } else { + sil_index = get_cpu_rev() - 1; + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + iva_init_34xx(sil_index, clk_index); + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +}
diff --git a/x-loader/board/nest/diamond-usb-loader/x-load.lds b/x-loader/board/nest/diamond-usb-loader/x-load.lds new file mode 100644 index 0000000..e0603a2 --- /dev/null +++ b/x-loader/board/nest/diamond-usb-loader/x-load.lds
@@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2010-2011 Nest Labs, Inc. + * All rights reserved. + * + * Description: + * This file is the X-Loader linker scatter file for the Nest + * Learning Thermostat board. + * + */ + +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/nest/diamond/Makefile b/x-loader/board/nest/diamond/Makefile new file mode 100644 index 0000000..7eb6795 --- /dev/null +++ b/x-loader/board/nest/diamond/Makefile
@@ -0,0 +1,62 @@ +# +# Copyright (c) 2010-2011 Nest Labs, Inc. +# All rights reserved. +# +# Description: +# This file is the make file for portions of X-Loader specific +# to the Nest Learning Thermostat board. +# + +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +COBJS := diamond.o mux.o prcm.o +SOBJS := platform.o + +CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(SOBJS) $(OBJS) + $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/nest/diamond/config.mk b/x-loader/board/nest/diamond/config.mk new file mode 100644 index 0000000..881380c --- /dev/null +++ b/x-loader/board/nest/diamond/config.mk
@@ -0,0 +1,21 @@ + + +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40200800
diff --git a/x-loader/board/nest/diamond/diamond.c b/x-loader/board/nest/diamond/diamond.c new file mode 100644 index 0000000..1806f67 --- /dev/null +++ b/x-loader/board/nest/diamond/diamond.c
@@ -0,0 +1,1075 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703ACUS, focusing + * primarily on GPIO, RAM and flash initialization. + * + * This is inherited from the OMAP3 EVM equivalent file. + * + * Initialization function order is roughly: + * + * 1) s_init + * 2) board_init + * 3) misc_init_r + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +#include "platform.h" + +#define MAX_DIAMOND_BOOT_DEVICES (1) + + +void +udelay(unsigned long usecs) { + delay(usecs); +} + +static inline u32 +get_cpu_id(void) +{ + u32 cpuid = 0; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + + return (cpuid); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 +get_cpu_rev(void) +{ + const u32 cpuid = get_cpu_id(); + + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + if ((cpuid & 0xf) == 0x0) { + return (CPU_3430_ES1); + + } else { + return (CPU_3430_ES2); + + } + +} + +u32 +is_cpu_family(void) +{ + const u32 cpuid = get_cpu_id(); + u32 cpu_family = 0, omap34xx_id = 0; + u16 hawkeye; + + if ((cpuid & 0xf) == 0x0) { + cpu_family = CPU_OMAP34XX; + + } else { + omap34xx_id = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (omap34xx_id >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + + case HAWKEYE_AM35XX: + cpu_family = CPU_AM35XX; + break; + + case HAWKEYE_OMAP36XX: + cpu_family = CPU_OMAP36XX; + break; + + case HAWKEYE_OMAP34XX: + default: + cpu_family = CPU_OMAP34XX; + break; + + } + } + + return (cpu_family); +} +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 +cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/* + * void sr32() + * + * Description: + * This routine clears and sets a value in a bit extent for a + * 32-bit value at the specified address. + * + * Input(s): + * addr - The address at which to clear and set the specified + * specified 32-bit value. + * start_bit - The first bit of the 32-bit data to clear and set. + * num_bits - The range of bits of the 32-bit data to clear and set. + * value - The value to set. + * + * Output(s): + * addr - The address with the specified bit extent cleared and + * set to the specified value. + * + * Returns: + * N/A + * + */ +void +sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + + msk = (1 << num_bits); + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/* + * u32 wait_on_value() + * + * Description: + * This routine reads the register at the specified address and + * busy waits until the specified match value is read or until the + * bounded number of loops have been reached. + * + * Input(s): + * read_bit_mask - The bit mask to apply after reading the register. + * match_value - The value to match on after reading and masking. + * read_addr - The register address to read. + * bound - The maximum number of times to read before giving + * up. + * + * Output(s): + * N/A + * + * Returns: + * True (1) if the match_value was reached; otherwise, false (0). + * + */ +u32 +wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +static void +secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +static void +try_unlock_memory(void) +{ + const int type = get_device_type(); + + /* + * If the processor is a GP device, unlock the device SRAM for + * general use. + */ + + if (type == CONTROL_STATUS_DEVICETYPE_GP) { + secure_unlock(); + } + + return; +} + +#if defined(CFG_SDRAM_DEBUG) +static void +omap3_sdrc_register_dump(void) +{ + printf("\n SDRC Register Dump:\n"); + + DUMP_REGL(SDRC_REVISION); + DUMP_REGL(SDRC_SYSCONFIG); + DUMP_REGL(SDRC_SYSSTATUS); + DUMP_REGL(SDRC_CS_CFG); + DUMP_REGL(SDRC_SHARING); + DUMP_REGL(SDRC_ERR_ADDR); + DUMP_REGL(SDRC_ERR_TYPE); + DUMP_REGL(SDRC_DLLA_CTRL); + DUMP_REGL(SDRC_DLLA_STATUS); + DUMP_REGL(SDRC_POWER_REG); + DUMP_REGL(SDRC_MCFG_0); + DUMP_REGL(SDRC_MR_0); + DUMP_REGL(SDRC_EMR2_0); + DUMP_REGL(SDRC_ACTIM_CTRLA_0); + DUMP_REGL(SDRC_ACTIM_CTRLB_0); + DUMP_REGL(SDRC_RFR_CTRL_0); + DUMP_REGL(SDRC_MANUAL_0); + DUMP_REGL(SDRC_MCFG_1); + DUMP_REGL(SDRC_MR_1); + DUMP_REGL(SDRC_EMR2_1); + DUMP_REGL(SDRC_ACTIM_CTRLA_1); + DUMP_REGL(SDRC_ACTIM_CTRLB_1); + DUMP_REGL(SDRC_RFR_CTRL_1); + DUMP_REGL(SDRC_MANUAL_1); +} +#else +# define omap3_sdrc_register_dump() do { } while (0) +#endif /* defined(CFG_SDRAM_DEBUG) */ + +#if defined(CFG_GPMC_DEBUG) +static void +omap3_gpmc_register_dump(void) +{ + printf("\n GPMC Register Dump:\n"); + + DUMP_REGL(GPMC_REVISION); + DUMP_REGL(GPMC_SYSCONFIG); + DUMP_REGL(GPMC_SYSSTATUS); + DUMP_REGL(GPMC_IRQSTATUS); + DUMP_REGL(GPMC_IRQENABLE); + DUMP_REGL(GPMC_TIMEOUT_CONTROL); + DUMP_REGL(GPMC_ERR_ADDRESS); + DUMP_REGL(GPMC_ERR_TYPE ); + DUMP_REGL(GPMC_CONFIG ); + DUMP_REGL(GPMC_STATUS ); + + DUMP_REGL(GPMC_CONFIG1_0); + DUMP_REGL(GPMC_CONFIG2_0); + DUMP_REGL(GPMC_CONFIG3_0); + DUMP_REGL(GPMC_CONFIG4_0); + DUMP_REGL(GPMC_CONFIG5_0); + DUMP_REGL(GPMC_CONFIG6_0); + DUMP_REGL(GPMC_CONFIG7_0); + + DUMP_REGL(GPMC_CONFIG1_1); + DUMP_REGL(GPMC_CONFIG2_1); + DUMP_REGL(GPMC_CONFIG3_1); + DUMP_REGL(GPMC_CONFIG4_1); + DUMP_REGL(GPMC_CONFIG5_1); + DUMP_REGL(GPMC_CONFIG6_1); + DUMP_REGL(GPMC_CONFIG7_1); + + DUMP_REGL(GPMC_CONFIG1_2); + DUMP_REGL(GPMC_CONFIG2_2); + DUMP_REGL(GPMC_CONFIG3_2); + DUMP_REGL(GPMC_CONFIG5_2); + DUMP_REGL(GPMC_CONFIG4_2); + DUMP_REGL(GPMC_CONFIG6_2); + DUMP_REGL(GPMC_CONFIG7_2); + + DUMP_REGL(GPMC_CONFIG1_3); + DUMP_REGL(GPMC_CONFIG2_3); + DUMP_REGL(GPMC_CONFIG3_3); + DUMP_REGL(GPMC_CONFIG4_3); + DUMP_REGL(GPMC_CONFIG5_3); + DUMP_REGL(GPMC_CONFIG6_3); + DUMP_REGL(GPMC_CONFIG7_3); + + DUMP_REGL(GPMC_CONFIG1_4); + DUMP_REGL(GPMC_CONFIG2_4); + DUMP_REGL(GPMC_CONFIG3_4); + DUMP_REGL(GPMC_CONFIG4_4); + DUMP_REGL(GPMC_CONFIG5_4); + DUMP_REGL(GPMC_CONFIG6_4); + DUMP_REGL(GPMC_CONFIG7_4); + + DUMP_REGL(GPMC_CONFIG1_5); + DUMP_REGL(GPMC_CONFIG2_5); + DUMP_REGL(GPMC_CONFIG3_5); + DUMP_REGL(GPMC_CONFIG4_5); + DUMP_REGL(GPMC_CONFIG5_5); + DUMP_REGL(GPMC_CONFIG6_5); + DUMP_REGL(GPMC_CONFIG7_5); + + DUMP_REGL(GPMC_CONFIG1_6); + DUMP_REGL(GPMC_CONFIG2_6); + DUMP_REGL(GPMC_CONFIG3_6); + DUMP_REGL(GPMC_CONFIG4_6); + DUMP_REGL(GPMC_CONFIG5_6); + DUMP_REGL(GPMC_CONFIG6_6); + DUMP_REGL(GPMC_CONFIG7_6); + + DUMP_REGL(GPMC_CONFIG1_7); + DUMP_REGL(GPMC_CONFIG2_7); + DUMP_REGL(GPMC_CONFIG3_7); + DUMP_REGL(GPMC_CONFIG4_7); + DUMP_REGL(GPMC_CONFIG5_7); + DUMP_REGL(GPMC_CONFIG6_7); + DUMP_REGL(GPMC_CONFIG7_7); + +#if 0 + DUMP_REGL(GPMC_NAND_COMMAND_0); + DUMP_REGL(GPMC_NAND_COMMAND_1); + DUMP_REGL(GPMC_NAND_COMMAND_2); + DUMP_REGL(GPMC_NAND_COMMAND_3); + DUMP_REGL(GPMC_NAND_COMMAND_4); + DUMP_REGL(GPMC_NAND_COMMAND_5); + DUMP_REGL(GPMC_NAND_COMMAND_6); + DUMP_REGL(GPMC_NAND_COMMAND_7); + + DUMP_REGL(GPMC_NAND_ADDRESS_0); + DUMP_REGL(GPMC_NAND_ADDRESS_1); + DUMP_REGL(GPMC_NAND_ADDRESS_2); + DUMP_REGL(GPMC_NAND_ADDRESS_3); + DUMP_REGL(GPMC_NAND_ADDRESS_4); + DUMP_REGL(GPMC_NAND_ADDRESS_5); + DUMP_REGL(GPMC_NAND_ADDRESS_6); + DUMP_REGL(GPMC_NAND_ADDRESS_7); + + DUMP_REGL(GPMC_NAND_DATA_0); + DUMP_REGL(GPMC_NAND_DATA_1); + DUMP_REGL(GPMC_NAND_DATA_2); + DUMP_REGL(GPMC_NAND_DATA_3); + DUMP_REGL(GPMC_NAND_DATA_4); + DUMP_REGL(GPMC_NAND_DATA_5); + DUMP_REGL(GPMC_NAND_DATA_6); + DUMP_REGL(GPMC_NAND_DATA_7); + + DUMP_REGL(GPMC_PREFETCH_CONFIG1); + DUMP_REGL(GPMC_PREFETCH_CONFIG2); + DUMP_REGL(GPMC_PREFETCH_CONTROL); + DUMP_REGL(GPMC_PREFETCH_STATUS); + + DUMP_REGL(GPMC_ECC_CONFIG); + DUMP_REGL(GPMC_ECC_CONTROL); + DUMP_REGL(GPMC_ECC_SIZE_CONFIG); + + DUMP_REGL(GPMC_ECC1_RESULT); + DUMP_REGL(GPMC_ECC2_RESULT); + DUMP_REGL(GPMC_ECC3_RESULT); + DUMP_REGL(GPMC_ECC4_RESULT); + DUMP_REGL(GPMC_ECC5_RESULT); + DUMP_REGL(GPMC_ECC6_RESULT); + DUMP_REGL(GPMC_ECC7_RESULT); + DUMP_REGL(GPMC_ECC8_RESULT); + DUMP_REGL(GPMC_ECC9_RESULT); + + DUMP_REGL(GPMC_BCH_RESULT0_0); + DUMP_REGL(GPMC_BCH_RESULT0_1); + DUMP_REGL(GPMC_BCH_RESULT0_2); + DUMP_REGL(GPMC_BCH_RESULT0_3); + DUMP_REGL(GPMC_BCH_RESULT0_4); + DUMP_REGL(GPMC_BCH_RESULT0_5); + DUMP_REGL(GPMC_BCH_RESULT0_6); + DUMP_REGL(GPMC_BCH_RESULT0_7); + + DUMP_REGL(GPMC_BCH_RESULT1_0); + DUMP_REGL(GPMC_BCH_RESULT1_1); + DUMP_REGL(GPMC_BCH_RESULT1_2); + DUMP_REGL(GPMC_BCH_RESULT1_3); + DUMP_REGL(GPMC_BCH_RESULT1_4); + DUMP_REGL(GPMC_BCH_RESULT1_5); + DUMP_REGL(GPMC_BCH_RESULT1_6); + DUMP_REGL(GPMC_BCH_RESULT1_7); + + DUMP_REGL(GPMC_BCH_RESULT2_0); + DUMP_REGL(GPMC_BCH_RESULT2_1); + DUMP_REGL(GPMC_BCH_RESULT2_2); + DUMP_REGL(GPMC_BCH_RESULT2_3); + DUMP_REGL(GPMC_BCH_RESULT2_4); + DUMP_REGL(GPMC_BCH_RESULT2_5); + DUMP_REGL(GPMC_BCH_RESULT2_6); + DUMP_REGL(GPMC_BCH_RESULT2_7); + + DUMP_REGL(GPMC_BCH_RESULT3_0); + DUMP_REGL(GPMC_BCH_RESULT3_1); + DUMP_REGL(GPMC_BCH_RESULT3_2); + DUMP_REGL(GPMC_BCH_RESULT3_3); + DUMP_REGL(GPMC_BCH_RESULT3_4); + DUMP_REGL(GPMC_BCH_RESULT3_5); + DUMP_REGL(GPMC_BCH_RESULT3_6); + DUMP_REGL(GPMC_BCH_RESULT3_7); + + DUMP_REGL(GPMC_BCH_SWDATA); +#endif +} +#else +# define omap3_gpmc_register_dump() do { } while (0) +#endif /* defined(CFG_NAND_DEBUG) */ + +#if defined(CFG_PRCM_DEBUG) +static void +omap3_prcm_register_dump(void) +{ + printf("\n PRCM Register Dump:\n"); + + DUMP_REGL(PRCM_PRM_CCR_CLKSEL); + DUMP_REGL(PRCM_PRM_GR_CLKSRC_CTRL); + DUMP_REGL(CM_CLKSEL1_PLL); + DUMP_REGL(CM_CLKSEL2_PLL); + DUMP_REGL(CM_CLKSEL3_PLL); + DUMP_REGL(CM_CLKEN_PLL); + DUMP_REGL(CM_CLKSEL1_PLL_MPU); + DUMP_REGL(CM_CLKSEL2_PLL_MPU); + DUMP_REGL(CM_CLKEN_PLL_MPU); + DUMP_REGL(CM_CLKSEL1_PLL_IVA2); + DUMP_REGL(CM_CLKSEL2_PLL_IVA2); + DUMP_REGL(CM_CLKEN_PLL_IVA2); + DUMP_REGL(CM_CLKSEL_CAM); + DUMP_REGL(CM_CLKSEL_CORE); + DUMP_REGL(CM_CLKSEL_DSS); + DUMP_REGL(CM_CLKSEL1_EMU); +} +#else +#define omap3_prcm_register_dump() do { } while (0) +#endif /* CFG_PRCM_DEBUG */ + +/* + * void config_diamond_sdram() + * + * Description: + * This routine initializes the processor's SDRAM Controller (SDRC) + * as appropriate for the Samsung K4X51163PI-FCG6 32 Mb x 16 b (64 + * MiB) DDR SDRAM on the Nest Learning Thermostat board. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +config_diamond_sdram(void) +{ + u32 value, actim_ctrla, actim_ctrlb; + + /* + * Step 1: Reset the SDRC controller and then wait for the reset + * event to clear. + */ + + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_SET, SDRC_SYSCONFIG); + wait_on_value(SDRC_SYSSTATUS_RESETDONE, + SDRC_SYSSTATUS_RESETDONE, + SDRC_STATUS, + 12000000); + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_CLEAR, SDRC_SYSCONFIG); + + /* + * Step 2: Setup the position and geometry of the SDRAM device on + * the controller's bus. + */ + + value = + (SDRC_SHARING_LOCK_OFF | + SDRC_SHARING_CS1MUXCFG_ENCODE(SDRC_SHARING_CS1MUXCFG_16_BIT_16_0) | + SDRC_SHARING_CS0MUXCFG_ENCODE(SDRC_SHARING_CS0MUXCFG_16_BIT_16_0) | + SDRC_SHARING_SDRCTRISTATE_OFF); + __raw_writel(value, SDRC_SHARING); + + /* + * Step 3: Setup the memory configuration, including RAS width, + * CAS width, address multiplexing, size, bank mapping, bus width, + * power mode, DDR type and memory type. + */ + + value = + (SDRC_MCFG_LOCKSTATUS_RW | + SDRC_MCFG_RASWIDTH_ENCODE(SDRC_MCFG_RASWIDTH_14_BITS) | + SDRC_MCFG_CASWIDTH_ENCODE(SDRC_MCFG_CASWIDTH_10_BITS) | + SDRC_MCFG_ADDRMUXLEGACY_FLEXIBLE | + SDRC_MCFG_RAMSIZE_ENCODE(CFG_SDRAM_SIZE_MB) | + SDRC_MCFG_BANKALLOCATION_ENCODE(SDRC_MCFG_BANKALLOCATION_R_B_C)| + SDRC_MCFG_B32NOT16_OFF | + SDRC_MCFG_DEEPPD_SUPPORTED | + SDRC_MCFG_DDRTYPE_ENCODE(SDRC_MCFG_DDRTYPE_MOBILE_DDR) | + SDRC_MCFG_RAMTYPE_ENCODE(SDRC_MCFG_RAMTYPE_DDR)); + __raw_writel(value, SDRC_MCFG_0); + + /* + * Step 4: Establish the AC fine tuning timing characteristics. + */ + + actim_ctrla + = (SDRC_ACTIM_CTRLA_TRFC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRFC) | + SDRC_ACTIM_CTRLA_TRC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRC) | + SDRC_ACTIM_CTRLA_TRAS_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRAS) | + SDRC_ACTIM_CTRLA_TRP_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRP) | + SDRC_ACTIM_CTRLA_TRCD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRCD) | + SDRC_ACTIM_CTRLA_TRRD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRRD) | + SDRC_ACTIM_CTRLA_TDPL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDPL) | + SDRC_ACTIM_CTRLA_TDAL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDAL)); + + actim_ctrlb + = (SDRC_ACTIM_CTRLB_TWTR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TWTR) | + SDRC_ACTIM_CTRLB_TCKE_ENCODE(CFG_SDRC_ACTIM_CTRLB_TCKE) | + SDRC_ACTIM_CTRLB_TXP_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXP) | + SDRC_ACTIM_CTRLB_TXSR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXSR)); + + __raw_writel(actim_ctrla, SDRC_ACTIM_CTRLA_0); + __raw_writel(actim_ctrlb, SDRC_ACTIM_CTRLB_0); + + /* + * Step 5: Establish the memory autorefresh control + */ + + value = + (SDRC_RFR_CTRL_ARCV_ENCODE(1244) | + SDRC_RFR_CTRL_ARE_ENCODE(SDRC_RFR_CTRL_ARE_1_ARCV)); + __raw_writel(value, SDRC_RFR_CTRL_0); + + value = + (SDRC_POWER_REG_WAKEUP_DELAYED | + SDRC_POWER_REG_AUTOCOUNT_ENCODE(0) | + SDRC_POWER_REG_SRFR_ON_RST_ENABLE | + SDRC_POWER_REG_SRFR_ON_IDLE_DISABLE | + SDRC_POWER_REG_CLKCTRL_ENCODE(SDRC_POWER_REG_CLKCTRL_NONE) | + SDRC_POWER_REG_PAGEPOLICY_HPHB); + __raw_writel(value, SDRC_POWER_REG); + + /* + * Step 6: Establish the JEDEC-defined mode and DLL parameters. + */ + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + delay(5000); + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_PRECHARGE_ALL), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + value = + (SDRC_MR_ZERO_1 | + SDRC_MR_WBST_ENABLE | + SDRC_MR_ZERO_0 | + SDRC_MR_CASL_ENCODE(SDRC_MR_CASL_3) | + SDRC_MR_SIL_SERIAL | + SDRC_MR_BL_ENCODE(SDRC_MR_BL_4)); + __raw_writel(value, SDRC_MR_0); + + value = + (SDRC_DLLA_CTRL_FIXED_DELAY_ENCODE(0) | + SDRC_DLLA_CTRL_INIT_LAT_ENCODE(0) | + SDRC_DLLA_CTRL_MODE_ON_IDLE_ENCODE(SDRC_DLLA_CTRL_MODE_ON_IDLE_PWD) | + SDRC_DLLA_CTRL_DLL_ENABLE | + SDRC_DLLA_CTRL_LOCK_TRACKINGDELAY); + __raw_writel(value, SDRC_DLLA_CTRL); + + /* + * Delay for a "reasonably long" period of time to allow the + * requested changes to take effect. + */ + + delay(0x20000); +} + +/* + * void s_init() + * + * Description: + * This routine performs very early system initialization of chip + * pin multiplexing and clocks and is called when ONLY an + * SRAM-based stack is available (i.e. no SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +s_init(void) +{ + watchdog_init(); + try_unlock_memory(); + set_muxconf_regs(); + + delay(100); + + prcm_init(); + per_clocks_enable(); + config_diamond_sdram(); +} + +/* + * int board_init() + * + * Description: + * This routine performs any early, board-specific initialization + * following core CPU initialization but prior to serial and NAND + * initialization. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +board_init(void) +{ + return (0); +} + +/* + * u32 get_device_type() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register DEVICETYPE field, indicating whether the + * device is of TST, EMU, HS or GP type. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register DEVICETYPE field. + * + */ +u32 +get_device_type(void) +{ + const int value = __raw_readl(CONTROL_STATUS); + + return (CONTROL_STATUS_DEVICETYPE_DECODE(value)); +} + +/* + * u32 get_sysboot_value() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register SYSBOOT order subfield, indicating the + * order of memory interfaces from which the processor will attempt + * to boot itself. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register SYSBOOT order subfield. + * + */ +u32 +get_sysboot_value(void) +{ + const u32 value = __raw_readl(CONTROL_STATUS); + const u32 peripheral_type = CONTROL_STATUS_SYSBOOT_TYPE_PERIPHERAL; + + /* + * This routine and callers of it are implicitly expecting the + * MEMORY interface (SYSBOOT[5] == 0) not the PERHIPHERAL + * interface (SYSBOOT[5] == 1) boot order, so check that is + * actually the case. + */ + + if (CONTROL_STATUS_SYSBOOT_TYPE_DECODE(value) == peripheral_type) { + hang(); + } + + return (CONTROL_STATUS_SYSBOOT_ORDER_DECODE(value)); +} + +/* + * int get_boot_device_list(const u32** device_list) + * + * Description: + * This routine returns a constant list indicating the preferred + * device boot list. + * It gets called from start_armboot in board.c + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The preferred first processor memory boot interface. + * + */ + +int +get_boot_devices_list(const u32** devices_list) +{ + static u32 list[MAX_DIAMOND_BOOT_DEVICES]; + const u32 mem_order = get_sysboot_value(); + + // set defaults + int number_of_devices = 0; + *devices_list = &list[0]; + + switch (mem_order) { + + case 0: + case 2: + case 4: + case 16: + case 22: + list[0] = GPMC_ONENAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 1: + case 12: + case 15: + case 21: + case 27: + list[0] = GPMC_NAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 3: + case 6: + list[0] = MMC_ONENAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 8: + case 11: + case 14: + case 20: + case 26: + list[0] = GPMC_MDOC; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 17: + case 18: + case 24: + list[0] = MMC_NAND; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + case 7: + case 10: + case 13: + case 19: + case 25: + + default: + list[0] = GPMC_NOR; + number_of_devices = MAX_DIAMOND_BOOT_DEVICES; + break; + } + return number_of_devices; +} + +/* + * int misc_init_r() + * + * Description: + * This routine performs any miscellaneous, board-specific + * initialization following CPU, early board, serial and NAND + * initialization but prior to loading the secondary program loader + * to RAM. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +misc_init_r(void) +{ + return (0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void +wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void +watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +/* + * void foobar() + * + * Description: + * This routine... + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + +#ifdef CONFIG_MMC + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); +#endif + delay(1000); +} + +static int +gpmc_config_0(void) +{ +#if defined(CFG_GPMC_CONFIG1_0) + /* + * First, disable the interface and wait. + */ + __raw_writel(GPMC_CONFIG7_CSVALID_DISABLED, GPMC_CONFIG7_0); + + delay(1000); + + /* + * Next, program the configuration parameters. + */ + __raw_writel(CFG_GPMC_CONFIG1_0, GPMC_CONFIG1_0); + __raw_writel(CFG_GPMC_CONFIG2_0, GPMC_CONFIG2_0); + __raw_writel(CFG_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(CFG_GPMC_CONFIG4_0, GPMC_CONFIG4_0); + __raw_writel(CFG_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __raw_writel(CFG_GPMC_CONFIG6_0, GPMC_CONFIG6_0); + + /* + * Finally, enable the GPMC mapping and spin for the parameters to + * become active. + */ + __raw_writel((CFG_GPMC_CONFIG7_0 | GPMC_CONFIG7_CSVALID_ENABLED), + GPMC_CONFIG7_0); + + delay(2000); + + if (nand_chip()){ + return (1); + } +#endif /* defined(CFG_GPMC_CONFIG1_0) */ + + return (0); +} + +/* + * int nand_init() + * + * Description: + * This routine initializes the General Purpose Memory Controller + * (GPMC) such that on-board NAND devices may be accessed for + * second-stage boot. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if NAND was successfully initialized; otherwise, 1. + * + */ +int +nand_init(void) +{ + int status = 1; + + /* + * Establish GPMC global settings. + */ + + __raw_writel(GPMC_SYSCONFIG_IDLEMODE_SMART, GPMC_SYSCONFIG); + + __raw_writel(GPMC_IRQENABLE_ALL_DISABLE, GPMC_IRQENABLE); + + __raw_writel(GPMC_TIMEOUTENABLE_OFF, GPMC_TIMEOUT_CONTROL); + + if (gpmc_config_0()) { + puts("Unsupported NAND device @ GPMC0!\n"); + goto done; + } + + status = 0; + + done: + /* Dump GPMC and SDRC registers if so configured. */ + + omap3_sdrc_register_dump(); + omap3_gpmc_register_dump(); + omap3_prcm_register_dump(); + + return (status); +} + +/* + * void board_hang() + * + * Description: + * This routine performs any board-specific actions when the system + * hangs by executing hang(). At present, there is nothing to do; + * however, we might later drive the piezo or a LED. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +board_hang (void) +{ + return; +}
diff --git a/x-loader/board/nest/diamond/mux.c b/x-loader/board/nest/diamond/mux.c new file mode 100644 index 0000000..42f92f9 --- /dev/null +++ b/x-loader/board/nest/diamond/mux.c
@@ -0,0 +1,314 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily I/O pad multiplexer configuration. + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> + +#include "platform.h" + +/* + * void set_muxconf_regs() + * + * Description: + * This routines sets the I/O pad multiplexers for UART, GPMC, SDRC, + * GPIO. + * + * The commented string gives the final mux configuration for that pin + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + */ +void +set_muxconf_regs(void) +{ + /* + * The bit fields for these settings are as follows: + * + * I{EN,DIS} - Input Enable/Disable + * PT[DU] - Pull-down, -up + * DIS,EN - Pull-down, -up disabled/enabled + * M[01234567] - Configuration mode 0-7 + */ + + /* + * SDRAM Controller (SDRC) + * + * Most of the SDRC signals are used to drive the Samsung + * K4X51163PI-FCG6 512 Mb x 16-bit (64 MiB) DDR SDRAM. Because we + * interface in 16-bit rather than 32-bit mode, we place the + * unused pins in safe mode (Mode 7). + */ + + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)); // SDRC_D0 + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)); // SDRC_D1 + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)); // SDRC_D2 + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)); // SDRC_D3 + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)); // SDRC_D4 + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)); // SDRC_D5 + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)); // SDRC_D6 + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)); // SDRC_D7 + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)); // SDRC_D8 + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)); // SDRC_D9 + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)); // SDRC_D10 + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)); // SDRC_D11 + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)); // SDRC_D12 + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)); // SDRC_D13 + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)); // SDRC_D14 + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)); // SDRC_D15 + + // Because we interface SDRAM in 16-bit mode, place + // SDRC_DATA[31:16] in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_D16), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D17), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D18), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D19), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D20), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D21), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D22), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D23), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D24), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D25), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D26), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D27), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D28), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D29), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D30), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D31), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)); // SDRC_CLK + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)); // SDRC_DQS0 + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)); // SDRC_DQS1 + + // Place unused DQ pins in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_DQS2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_DQS3), (IDIS | PTD | DIS | M7)); // Unused + + /* + * General Purpose Memory Controller (GPMC) + * + */ + + MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)); // GPMC_A1 + MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)); // GPMC_A2 + MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)); // GPMC_A3 + MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)); // GPMC_A4 + MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)); // GPMC_A5 + MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)); // GPMC_A6 + MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)); // GPMC_A7 + + // Place the unused GPMC_A8 pin in safe mode (Mode 7). + + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_A9 to GPIO_42 used as a push-pull, active low input + // from the USB PHY for USB suspend notification. + + MUX_VAL(CP(GPMC_A9), (IEN | PTU | DIS | M4)); // GPIO_42 + +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign GPMC_A10 to GPIO_43 used as push-pull, active low output + // LCD_nENBUFFER for the 1.8V to 3.3V LCD buffer enable. + + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M4)); // GPIO_43 +#else + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + + MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)); // GPMC_D0 + MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)); // GPMC_D1 + MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)); // GPMC_D2 + MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)); // GPMC_D3 + MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)); // GPMC_D4 + MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)); // GPMC_D5 + MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)); // GPMC_D6 + MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)); // GPMC_D7 + MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)); // GPMC_D8 + MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)); // GPMC_D9 + MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)); // GPMC_D10 + MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)); // GPMC_D11 + MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)); // GPMC_D12 + MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)); // GPMC_D13 + MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)); // GPMC_D14 + MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)); // GPMC_D15 + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)); // GPMC_nCS0 + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)); // GPMC_nCS1 + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)); // GPMC_nCS2 +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign to GPMC_NCS3 for Samsung K9F4G08U0C 512 MiB SLC NAND + // Flash + + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)); // GPMC_nCS3 +#else + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTD | DIS | M7)); // Unused +#if defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) + // Assign to GPMC_NCS5 for SMSC LAN9220 10/100 Mbit Ethernet MAC + // and PHY + + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)); // GPMC_nCS5 +#else + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M7)); // Unused +#endif /* defined(CONFIG_DIAMOND_BOARD_DEVELOPMENT) */ + + // Assign GPMC_NCS6 to GPT11_PWM_EVT used as a push-pull pulse width + // modulated (PWM) signal for the piezo. + + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTD | DIS | M3)); // GPT11_PWM_EVT + + // Assign GPMC_NCS7 to GPIO_58 used as a push-pull output + // PIEZO_NENABLE to the TI SN74LVC2G240 Dual Buffer/Driver With + // 3-State Outputs inputs. + + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTD | DIS | M4)); // GPIO_58 + + MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)); // GPMC_CLK + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); // GPMC_nADV_ALE + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); // GPMC_nOE + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); // GPMC_nWE + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)); // GPMC_nBE0_CLE + + // Assign GPMC_NBE1 to GPIO_61 used as a push-pull output to the + // ZigBee active-low reset. + + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)); // GPIO_61 + + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)); // GPMC_nWP + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)); // GPMC_WAIT0 + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)); // GPMC_WAIT1 + MUX_VAL(CP(GPMC_WAIT2), (IDIS | PTD | DIS | M7)); // Unavailable + + // Assign GPMC_WAIT3 to GPIO_65 used as an active-high, push-pull + // backplate detect input. + + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTD | DIS | M4)); // GPIO_65 + + /* + * Display Subsystem (DSS) + * + * All DSS signals are used in their normal, default mode (Mode 0) + * to drive the Samsung LMS350DF0[13] LCD display panel. + */ + + MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)); // DSS_PCLK + MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)); // DSS_HSYNC + MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)); // DSS_VSYNC + MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)); // DSS_ACBIAS + MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)); // DSS_DATA0 + MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)); // DSS_DATA1 + MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)); // DSS_DATA2 + MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)); // DSS_DATA3 + MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)); // DSS_DATA4 + MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)); // DSS_DATA5 + MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)); // DSS_DATA6 + MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)); // DSS_DATA7 + MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)); // DSS_DATA8 + MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)); // DSS_DATA9 + MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)); // DSS_DATA10 + MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)); // DSS_DATA11 + MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)); // DSS_DATA12 + MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)); // DSS_DATA13 + MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)); // DSS_DATA14 + MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)); // DSS_DATA15 + MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)); // DSS_DATA16 + MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)); // DSS_DATA17 + MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)); // DSS_DATA18 + MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)); // DSS_DATA19 + MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)); // DSS_DATA20 + MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)); // DSS_DATA21 + MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)); // DSS_DATA22 + MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)); // DSS_DATA23 + + MUX_VAL(CP(CAM_WEN), (IDIS | PTD | DIS | M7)); // Unused + + /* + * Universal Asynchronous Receiver / Transmitter (UART) + * + */ + + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); // UART1_TX + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)); // UART1_RTS + MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)); // UART1_CTS + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)); // UART1_RX + /* + * Control and Debug + * + */ + + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)); // SYS_32K + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M0)); // SYS_BOOT0 + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M0)); // SYS_BOOT1 + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M0)); // SYS_BOOT2 + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M0)); // SYS_BOOT3 + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M0)); // SYS_BOOT4 + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M0)); // SYS_BOOT5 + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M0)); // SYS_BOOT6 + MUX_VAL(CP(SYS_CLKOUT1), (IDIS | PTU | EN | M0)); // SYS_CLKOUT1 + MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)); // JTAG_nTRST + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)); // JTAG_TCK + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)); // JTAG_TMS + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)); // JTAG_TDI + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)); // JTAG_EMU0 + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)); // JTAG_EMU1 + MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D0_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D1_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D2_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D3_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D4_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D5_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D6_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D7_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D8_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D9_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D12_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D13_ES2), (IDIS | PTD | DIS | M7)); // Unused + + // Assign ETK_D1[45] as MM2_RXRCV and MM2_TXSE0 USB FS/LS Host + // (Mode 5) + + MUX_VAL(CP(ETK_D14_ES2), (IEN | PTD | DIS | M5)); // MM2_RXRCV + MUX_VAL(CP(ETK_D15_ES2), (IEN | PTD | DIS | M5)); // MM2_TXSE0 +}
diff --git a/x-loader/board/nest/diamond/platform.S b/x-loader/board/nest/diamond/platform.S new file mode 100644 index 0000000..0549d27 --- /dev/null +++ b/x-loader/board/nest/diamond/platform.S
@@ -0,0 +1,557 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific setup for the Nest Learning + * Thermostat board. + * + * It inherits entirely from the equivalent TI OMAP3 EVM + * file. + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG1_0) +flash_cfg3_addr: + .word (GPMC_CONFIG3_0) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG4_0) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG5_0) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL +#endif /* !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) */ + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* + * Tables for 36x/37x devices + * + * (Populated for 13MHz only) + */ +mpu_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_MPU_DPLL_300MHZ) +.word 150, 5, 0, 1 // 12 MHz +.word 300, 12, 0, 1 // 13 MHz +.word 125, 7, 0, 1 // 19.2 MHz +.word 150, 12, 0, 1 // 26 MHz +.word 125, 15, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_MPU_DPLL_600MHZ) +.word 300, 5, 0, 1 // 12 MHz +.word 600, 12, 0, 1 // 13 MHz +.word 125, 3, 0, 1 // 19.2 MHz +.word 300, 12, 0, 1 // 26 MHz +.word 125, 7, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "MPU DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_MPU_DPLL_600MHZ) */ + +iva_36x_dpll_param: +// M N FS M2 +.word 10, 0, 0, 1 // 12 MHz +.word 10, 0, 0, 1 // 13 MHz +.word 10, 0, 0, 1 // 19.2 MHz +.word 10, 0, 0, 1 // 26 MHz +.word 10, 0, 0, 1 // 38.4 MHz +.word 10, 0, 0, 1 // 16.8 MHz + +core_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_CORE_DPLL_200MHZ) +.word 100, 5, 0, 1 // 12 MHz +.word 200, 12, 0, 1 // 13 MHz +.word 375, 35, 0, 1 // 19.2 MHz +.word 100, 12, 0, 1 // 26 MHz +.word 375, 71, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_332MHZ) +.word 166, 5, 0, 1 // 12 MHz +.word 332, 12, 0, 1 // 13 MHz +.word 415, 23, 0, 1 // 19.2 MHz +.word 166, 12, 0, 1 // 26 MHz +.word 415, 47, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_400MHZ) +.word 200, 5, 0, 1 // 12 MHz +.word 400, 12, 0, 1 // 13 MHz +.word 375, 17, 0, 1 // 19.2 MHz +.word 200, 12, 0, 1 // 26 MHz +.word 375, 35, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "Core DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_CORE_DPLL_400MHZ) */ + +/* + * For the peripheral (PER) (aka DPLL4) clock settings, there are only + * effectively two clock choices, 96 MHz or 192 MHz. However, the only + * time 192 MHz is apt to be used in an application is if both SGX and + * TV output are used. + * + * For any given system clock, the dividers are configured thus (per + * Section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" of the OMAP3 TRM): + * + * PER[clkout] = (SYS[clkout] * M) / (N + 1) + * + * M2[clkout]: PER[clkout] / M2 used by UART, MMC, I2C, etc. + * M3[clkout]: PER[clkout] / M3 used by TV out. + * M4[clkout]: PER[clkout] / M4 used by DSS. + * M5[clkout]: PER[clkout] / M5 used by camera. + * M6[clkout]: PER[clkout] / M6 used by emulation. + * + * So, for a 19.2 MHz system clock and the scalar entries below: + * + * PER[clkout] = (19.2 * 540) / (11 + 1) = 864 + * + * M2[clkout]: 864 / 9 = 96 MHz + * M3[clkout]: 864 / 16 = 54 MHz + * M4[clkout]: 864 / 5 = 172.8 MHz + * M5[clkout]: 864 / 4 = 216 MHz + * M6[clkout]: 864 / 3 = 288 MHz + */ +per_36x_dpll_param: +// SYS_CLK M N M2 M3 M4 M5 M6 m2DIV +.word 12000, 432, 5, 9, 16, 9, 4, 3, 1 // 12 MHz +.word 13000, 864, 12, 9, 16, 9, 4, 3, 1 // 13 MHz +.word 19200, 540, 11, 9, 16, 9, 4, 3, 1 // 19.2 MHz +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 // 26 MHz +.word 38400, 270, 11, 9, 16, 9, 4, 3, 1 // 38.4 MHz +.word 16800, 360, 6, 9, 16, 9, 4, 3, 1 // 16.8 MHz + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: + adr r0, mpu_36x_dpll_param + mov pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: + adr r0, iva_36x_dpll_param + mov pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: + adr r0, core_36x_dpll_param + mov pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: + adr r0, per_36x_dpll_param + mov pc, lr
diff --git a/x-loader/board/nest/diamond/platform.h b/x-loader/board/nest/diamond/platform.h new file mode 100644 index 0000000..c836e5a --- /dev/null +++ b/x-loader/board/nest/diamond/platform.h
@@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines data structures and function prototypes for + * accessing Digital Phased Lock Loop (DPLL) parameters and + * settings. + * + */ + +#ifndef _NEST_DIAMOND_PLATFORM_H_ +#define _NEST_DIAMOND_PLATFORM_H_ + +#include <asm/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Type Definitions + */ + +/* Used to index into DPLL parameter tables */ + +struct dpll_param { + u32 m; + u32 n; + u32 fsel; + u32 m2; +}; + +struct dpll_per_36x_param { + u32 sys_clk; + u32 m; + u32 n; + u32 m2; + u32 m3; + u32 m4; + u32 m5; + u32 m6; + u32 m2div; +}; + +typedef struct dpll_param dpll_param; + +/* + * Inline Functions + */ +static inline void +delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + + +/* + * Function Prototypes + * + * The following functions are exported from platform.S. + */ + +extern dpll_param * get_mpu_dpll_param(void); +extern dpll_param * get_iva_dpll_param(void); +extern dpll_param * get_core_dpll_param(void); +extern dpll_param * get_per_dpll_param(void); + +extern dpll_param * get_36x_mpu_dpll_param(void); +extern dpll_param * get_36x_iva_dpll_param(void); +extern dpll_param * get_36x_core_dpll_param(void); +extern dpll_param * get_36x_per_dpll_param(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NEST_DIAMOND_PLATFORM_H_ */
diff --git a/x-loader/board/nest/diamond/prcm.c b/x-loader/board/nest/diamond/prcm.c new file mode 100644 index 0000000..5625ad7 --- /dev/null +++ b/x-loader/board/nest/diamond/prcm.c
@@ -0,0 +1,565 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily clock set-up for the processor's Power, Reset and + * Clock Manager (PRCM) + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +#include "platform.h" + +/* + * u32 get_osc_clk_speed() + * + * Description: + * This routine determines the reference oscillator speed based on + * a known 32 kHz clock and general purpose timer. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The reference oscillator clock speed. + * + */ +static u32 +get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & BIT7) + cdiv = 2; + else if (val & BIT6) + cdiv = 1; + else + /* + * Should never reach here! + * TBD: Add a WARN()/BUG() + * For now, assume divider as 1. + */ + cdiv = 1; + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/* + * void get_sys_clkin_sel() + * + * Description: + * This routine sets the value for the PRCM PRM system clock + * frequency selector, which should be written to PRM_CLKSEL. + * + * Input(s): + * hertz - The speed, in MHz, that the system clock is believed + * to be running at. + * sys_clkin_sel - A pointer to storage for the index used to access the + * digital PLL settings. + * + * Output(s): + * sys_clkin_sel - A pointer to the index for the digital PLL settings + * appropriate for the specified system clock rate. + * + * Returns: + * N/A + * + */ +static void +get_sys_clkin_sel(u32 hertz, u32 *sys_clkin_sel) +{ + switch (hertz) { + + case S38_4M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_38_4_MHZ; + break; + + case S26M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_26_0_MHZ; + break; + + case S19_2M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ; + break; + + case S16_8M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_16_8_MHZ; + break; + + case S13M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_13_0_MHZ; + break; + + case S12M: + default: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_12_0_MHZ; + break; + + } +} + +/* + * OMAP34x/35x specific functions + */ +static void +dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_34X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + ptr = (dpll_param *)get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + sr32(CM_CLKSEL2_PLL, 8, 11, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + sr32(CM_CLKEN_PLL, 20, 4, ptr->fsel); + + /* LOCK MODE (EN_PERIPH_DPLL) : CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, ptr->fsel); +} + +static void +iva_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, ptr->fsel); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ +static void +dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_36x_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr += clk_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_36X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct dpll_per_36x_param *ptr; + + ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + sr32(CM_CLKSEL1_EMU, 24, 6, ptr->m6); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + sr32(CM_CLKSEL_CAM, 0, 6, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + sr32(CM_CLKSEL_DSS, 0, 6, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + sr32(CM_CLKSEL_DSS, 8, 6, ptr->m3); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + sr32(CM_CLKSEL2_PLL, 8, 12, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + sr32(CM_CLKSEL_CORE, 12, 2, ptr->m2div); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_36x_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* LOCK MODE (EN_MPU_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); +} + +static void +iva_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * void prcm_init() + * + * Description: + * This routine initializes clocks in a board-specific manner for + * the processor's Power, Reset and Clock Manager (PRCM) and is + * called only when an SRAM-based stack is available (i.e. no + * SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +prcm_init(void) +{ + u32 sys_clk_rate = 0, sys_clkin_sel, sys_clk_div; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + sys_clk_rate = get_osc_clk_speed(); + get_sys_clkin_sel(sys_clk_rate, &sys_clkin_sel); + + /* Set the PRM_CLKSEL_SYS_CLKIN_SEL value in the processor. */ + + sr32(PRCM_PRM_CCR_CLKSEL, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_START, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS, + sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide by two. + * + * On OMAP3630, DDR data corruption has been observed on OFF mode + * exit if the sys clock was lower than 26M. As a work around, + * OMAP3630 is operated at 26M sys clock and this internal division + * is not performed. + */ + + if((is_cpu_family() != CPU_OMAP36XX) && + (sys_clkin_sel > PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ)) { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_2; + clk_index = sys_clkin_sel / 2; + + } else { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_1; + clk_index = sys_clkin_sel / 1; + + } + + sr32(PRCM_PRM_GR_CLKSRC_CTRL, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_START, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS, + sys_clk_div); + + if (is_cpu_family() == CPU_OMAP36XX) { + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + + } else { + sil_index = get_cpu_rev() - 1; + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + iva_init_34xx(sil_index, clk_index); + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +}
diff --git a/x-loader/board/nest/diamond/x-load.lds b/x-loader/board/nest/diamond/x-load.lds new file mode 100644 index 0000000..e0603a2 --- /dev/null +++ b/x-loader/board/nest/diamond/x-load.lds
@@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2010-2011 Nest Labs, Inc. + * All rights reserved. + * + * Description: + * This file is the X-Loader linker scatter file for the Nest + * Learning Thermostat board. + * + */ + +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/nest/j49-usb-loader/Makefile b/x-loader/board/nest/j49-usb-loader/Makefile new file mode 100644 index 0000000..ece4a90 --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/Makefile
@@ -0,0 +1,62 @@ +# +# Copyright (c) 2010-2011 Nest Labs, Inc. +# All rights reserved. +# +# Description: +# This file is the make file for portions of X-Loader specific +# to the Nest Learning Thermostat board. +# + +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +COBJS := j49.o mux.o prcm.o +SOBJS := platform.o + +CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(SOBJS) $(OBJS) + $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/nest/j49-usb-loader/config.mk b/x-loader/board/nest/j49-usb-loader/config.mk new file mode 100644 index 0000000..f5d960c --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/config.mk
@@ -0,0 +1,21 @@ + + +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also + +TEXT_BASE = 0x40200000 +STACK_BASE = 0x4020FCB0
diff --git a/x-loader/board/nest/j49-usb-loader/j49.c b/x-loader/board/nest/j49-usb-loader/j49.c new file mode 100644 index 0000000..9609bbc --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/j49.c
@@ -0,0 +1,1046 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703ACUS, focusing + * primarily on GPIO, RAM and flash initialization. + * + * This is inherited from the OMAP3 EVM equivalent file. + * + * Initialization function order is roughly: + * + * 1) s_init + * 2) board_init + * 3) misc_init_r + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +#include "platform.h" + +#define MAX_J49_BOOT_DEVICES (3) + +void +udelay(unsigned long usecs) { + delay(usecs); +} + +static inline u32 +get_cpu_id(void) +{ + u32 cpuid = 0; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + + return (cpuid); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 +get_cpu_rev(void) +{ + const u32 cpuid = get_cpu_id(); + + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + if ((cpuid & 0xf) == 0x0) { + return (CPU_3430_ES1); + + } else { + return (CPU_3430_ES2); + + } + +} + +u32 +is_cpu_family(void) +{ + const u32 cpuid = get_cpu_id(); + u32 cpu_family = 0, omap34xx_id = 0; + u16 hawkeye; + + if ((cpuid & 0xf) == 0x0) { + cpu_family = CPU_OMAP34XX; + + } else { + omap34xx_id = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (omap34xx_id >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + + case HAWKEYE_AM35XX: + cpu_family = CPU_AM35XX; + break; + + case HAWKEYE_OMAP36XX: + cpu_family = CPU_OMAP36XX; + break; + + case HAWKEYE_OMAP34XX: + default: + cpu_family = CPU_OMAP34XX; + break; + + } + } + + return (cpu_family); +} +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 +cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/* + * void sr32() + * + * Description: + * This routine clears and sets a value in a bit extent for a + * 32-bit value at the specified address. + * + * Input(s): + * addr - The address at which to clear and set the specified + * specified 32-bit value. + * start_bit - The first bit of the 32-bit data to clear and set. + * num_bits - The range of bits of the 32-bit data to clear and set. + * value - The value to set. + * + * Output(s): + * addr - The address with the specified bit extent cleared and + * set to the specified value. + * + * Returns: + * N/A + * + */ +void +sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + + msk = (1 << num_bits); + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/* + * u32 wait_on_value() + * + * Description: + * This routine reads the register at the specified address and + * busy waits until the specified match value is read or until the + * bounded number of loops have been reached. + * + * Input(s): + * read_bit_mask - The bit mask to apply after reading the register. + * match_value - The value to match on after reading and masking. + * read_addr - The register address to read. + * bound - The maximum number of times to read before giving + * up. + * + * Output(s): + * N/A + * + * Returns: + * True (1) if the match_value was reached; otherwise, false (0). + * + */ +u32 +wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +static void +secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +static void +try_unlock_memory(void) +{ + const int type = get_device_type(); + + /* + * If the processor is a GP device, unlock the device SRAM for + * general use. + */ + + if (type == CONTROL_STATUS_DEVICETYPE_GP) { + secure_unlock(); + } + + return; +} + +#if defined(CFG_SDRAM_DEBUG) +static void +omap3_sdrc_register_dump(void) +{ + printf("\n SDRC Register Dump:\n"); + + DUMP_REGL(SDRC_REVISION); + DUMP_REGL(SDRC_SYSCONFIG); + DUMP_REGL(SDRC_SYSSTATUS); + DUMP_REGL(SDRC_CS_CFG); + DUMP_REGL(SDRC_SHARING); + DUMP_REGL(SDRC_ERR_ADDR); + DUMP_REGL(SDRC_ERR_TYPE); + DUMP_REGL(SDRC_DLLA_CTRL); + DUMP_REGL(SDRC_DLLA_STATUS); + DUMP_REGL(SDRC_POWER_REG); + DUMP_REGL(SDRC_MCFG_0); + DUMP_REGL(SDRC_MR_0); + DUMP_REGL(SDRC_EMR2_0); + DUMP_REGL(SDRC_ACTIM_CTRLA_0); + DUMP_REGL(SDRC_ACTIM_CTRLB_0); + DUMP_REGL(SDRC_RFR_CTRL_0); + DUMP_REGL(SDRC_MANUAL_0); + DUMP_REGL(SDRC_MCFG_1); + DUMP_REGL(SDRC_MR_1); + DUMP_REGL(SDRC_EMR2_1); + DUMP_REGL(SDRC_ACTIM_CTRLA_1); + DUMP_REGL(SDRC_ACTIM_CTRLB_1); + DUMP_REGL(SDRC_RFR_CTRL_1); + DUMP_REGL(SDRC_MANUAL_1); +} +#else +# define omap3_sdrc_register_dump() do { } while (0) +#endif /* defined(CFG_SDRAM_DEBUG) */ + +#if defined(CFG_GPMC_DEBUG) +static void +omap3_gpmc_register_dump(void) +{ + printf("\n GPMC Register Dump:\n"); + + DUMP_REGL(GPMC_REVISION); + DUMP_REGL(GPMC_SYSCONFIG); + DUMP_REGL(GPMC_SYSSTATUS); + DUMP_REGL(GPMC_IRQSTATUS); + DUMP_REGL(GPMC_IRQENABLE); + DUMP_REGL(GPMC_TIMEOUT_CONTROL); + DUMP_REGL(GPMC_ERR_ADDRESS); + DUMP_REGL(GPMC_ERR_TYPE ); + DUMP_REGL(GPMC_CONFIG ); + DUMP_REGL(GPMC_STATUS ); + + DUMP_REGL(GPMC_CONFIG1_0); + DUMP_REGL(GPMC_CONFIG2_0); + DUMP_REGL(GPMC_CONFIG3_0); + DUMP_REGL(GPMC_CONFIG4_0); + DUMP_REGL(GPMC_CONFIG5_0); + DUMP_REGL(GPMC_CONFIG6_0); + DUMP_REGL(GPMC_CONFIG7_0); + + DUMP_REGL(GPMC_CONFIG1_1); + DUMP_REGL(GPMC_CONFIG2_1); + DUMP_REGL(GPMC_CONFIG3_1); + DUMP_REGL(GPMC_CONFIG4_1); + DUMP_REGL(GPMC_CONFIG5_1); + DUMP_REGL(GPMC_CONFIG6_1); + DUMP_REGL(GPMC_CONFIG7_1); + + DUMP_REGL(GPMC_CONFIG1_2); + DUMP_REGL(GPMC_CONFIG2_2); + DUMP_REGL(GPMC_CONFIG3_2); + DUMP_REGL(GPMC_CONFIG5_2); + DUMP_REGL(GPMC_CONFIG4_2); + DUMP_REGL(GPMC_CONFIG6_2); + DUMP_REGL(GPMC_CONFIG7_2); + + DUMP_REGL(GPMC_CONFIG1_3); + DUMP_REGL(GPMC_CONFIG2_3); + DUMP_REGL(GPMC_CONFIG3_3); + DUMP_REGL(GPMC_CONFIG4_3); + DUMP_REGL(GPMC_CONFIG5_3); + DUMP_REGL(GPMC_CONFIG6_3); + DUMP_REGL(GPMC_CONFIG7_3); + + DUMP_REGL(GPMC_CONFIG1_4); + DUMP_REGL(GPMC_CONFIG2_4); + DUMP_REGL(GPMC_CONFIG3_4); + DUMP_REGL(GPMC_CONFIG4_4); + DUMP_REGL(GPMC_CONFIG5_4); + DUMP_REGL(GPMC_CONFIG6_4); + DUMP_REGL(GPMC_CONFIG7_4); + + DUMP_REGL(GPMC_CONFIG1_5); + DUMP_REGL(GPMC_CONFIG2_5); + DUMP_REGL(GPMC_CONFIG3_5); + DUMP_REGL(GPMC_CONFIG4_5); + DUMP_REGL(GPMC_CONFIG5_5); + DUMP_REGL(GPMC_CONFIG6_5); + DUMP_REGL(GPMC_CONFIG7_5); + + DUMP_REGL(GPMC_CONFIG1_6); + DUMP_REGL(GPMC_CONFIG2_6); + DUMP_REGL(GPMC_CONFIG3_6); + DUMP_REGL(GPMC_CONFIG4_6); + DUMP_REGL(GPMC_CONFIG5_6); + DUMP_REGL(GPMC_CONFIG6_6); + DUMP_REGL(GPMC_CONFIG7_6); + + DUMP_REGL(GPMC_CONFIG1_7); + DUMP_REGL(GPMC_CONFIG2_7); + DUMP_REGL(GPMC_CONFIG3_7); + DUMP_REGL(GPMC_CONFIG4_7); + DUMP_REGL(GPMC_CONFIG5_7); + DUMP_REGL(GPMC_CONFIG6_7); + DUMP_REGL(GPMC_CONFIG7_7); + +#if 0 + DUMP_REGL(GPMC_NAND_COMMAND_0); + DUMP_REGL(GPMC_NAND_COMMAND_1); + DUMP_REGL(GPMC_NAND_COMMAND_2); + DUMP_REGL(GPMC_NAND_COMMAND_3); + DUMP_REGL(GPMC_NAND_COMMAND_4); + DUMP_REGL(GPMC_NAND_COMMAND_5); + DUMP_REGL(GPMC_NAND_COMMAND_6); + DUMP_REGL(GPMC_NAND_COMMAND_7); + + DUMP_REGL(GPMC_NAND_ADDRESS_0); + DUMP_REGL(GPMC_NAND_ADDRESS_1); + DUMP_REGL(GPMC_NAND_ADDRESS_2); + DUMP_REGL(GPMC_NAND_ADDRESS_3); + DUMP_REGL(GPMC_NAND_ADDRESS_4); + DUMP_REGL(GPMC_NAND_ADDRESS_5); + DUMP_REGL(GPMC_NAND_ADDRESS_6); + DUMP_REGL(GPMC_NAND_ADDRESS_7); + + DUMP_REGL(GPMC_NAND_DATA_0); + DUMP_REGL(GPMC_NAND_DATA_1); + DUMP_REGL(GPMC_NAND_DATA_2); + DUMP_REGL(GPMC_NAND_DATA_3); + DUMP_REGL(GPMC_NAND_DATA_4); + DUMP_REGL(GPMC_NAND_DATA_5); + DUMP_REGL(GPMC_NAND_DATA_6); + DUMP_REGL(GPMC_NAND_DATA_7); + + DUMP_REGL(GPMC_PREFETCH_CONFIG1); + DUMP_REGL(GPMC_PREFETCH_CONFIG2); + DUMP_REGL(GPMC_PREFETCH_CONTROL); + DUMP_REGL(GPMC_PREFETCH_STATUS); + + DUMP_REGL(GPMC_ECC_CONFIG); + DUMP_REGL(GPMC_ECC_CONTROL); + DUMP_REGL(GPMC_ECC_SIZE_CONFIG); + + DUMP_REGL(GPMC_ECC1_RESULT); + DUMP_REGL(GPMC_ECC2_RESULT); + DUMP_REGL(GPMC_ECC3_RESULT); + DUMP_REGL(GPMC_ECC4_RESULT); + DUMP_REGL(GPMC_ECC5_RESULT); + DUMP_REGL(GPMC_ECC6_RESULT); + DUMP_REGL(GPMC_ECC7_RESULT); + DUMP_REGL(GPMC_ECC8_RESULT); + DUMP_REGL(GPMC_ECC9_RESULT); + + DUMP_REGL(GPMC_BCH_RESULT0_0); + DUMP_REGL(GPMC_BCH_RESULT0_1); + DUMP_REGL(GPMC_BCH_RESULT0_2); + DUMP_REGL(GPMC_BCH_RESULT0_3); + DUMP_REGL(GPMC_BCH_RESULT0_4); + DUMP_REGL(GPMC_BCH_RESULT0_5); + DUMP_REGL(GPMC_BCH_RESULT0_6); + DUMP_REGL(GPMC_BCH_RESULT0_7); + + DUMP_REGL(GPMC_BCH_RESULT1_0); + DUMP_REGL(GPMC_BCH_RESULT1_1); + DUMP_REGL(GPMC_BCH_RESULT1_2); + DUMP_REGL(GPMC_BCH_RESULT1_3); + DUMP_REGL(GPMC_BCH_RESULT1_4); + DUMP_REGL(GPMC_BCH_RESULT1_5); + DUMP_REGL(GPMC_BCH_RESULT1_6); + DUMP_REGL(GPMC_BCH_RESULT1_7); + + DUMP_REGL(GPMC_BCH_RESULT2_0); + DUMP_REGL(GPMC_BCH_RESULT2_1); + DUMP_REGL(GPMC_BCH_RESULT2_2); + DUMP_REGL(GPMC_BCH_RESULT2_3); + DUMP_REGL(GPMC_BCH_RESULT2_4); + DUMP_REGL(GPMC_BCH_RESULT2_5); + DUMP_REGL(GPMC_BCH_RESULT2_6); + DUMP_REGL(GPMC_BCH_RESULT2_7); + + DUMP_REGL(GPMC_BCH_RESULT3_0); + DUMP_REGL(GPMC_BCH_RESULT3_1); + DUMP_REGL(GPMC_BCH_RESULT3_2); + DUMP_REGL(GPMC_BCH_RESULT3_3); + DUMP_REGL(GPMC_BCH_RESULT3_4); + DUMP_REGL(GPMC_BCH_RESULT3_5); + DUMP_REGL(GPMC_BCH_RESULT3_6); + DUMP_REGL(GPMC_BCH_RESULT3_7); + + DUMP_REGL(GPMC_BCH_SWDATA); +#endif +} +#else +# define omap3_gpmc_register_dump() do { } while (0) +#endif /* defined(CFG_NAND_DEBUG) */ + +#if defined(CFG_PRCM_DEBUG) +static void +omap3_prcm_register_dump(void) +{ + printf("\n PRCM Register Dump:\n"); + + DUMP_REGL(PRCM_PRM_CCR_CLKSEL); + DUMP_REGL(PRCM_PRM_GR_CLKSRC_CTRL); + DUMP_REGL(CM_CLKSEL1_PLL); + DUMP_REGL(CM_CLKSEL2_PLL); + DUMP_REGL(CM_CLKSEL3_PLL); + DUMP_REGL(CM_CLKEN_PLL); + DUMP_REGL(CM_CLKSEL1_PLL_MPU); + DUMP_REGL(CM_CLKSEL2_PLL_MPU); + DUMP_REGL(CM_CLKEN_PLL_MPU); + DUMP_REGL(CM_CLKSEL1_PLL_IVA2); + DUMP_REGL(CM_CLKSEL2_PLL_IVA2); + DUMP_REGL(CM_CLKEN_PLL_IVA2); + DUMP_REGL(CM_CLKSEL_CAM); + DUMP_REGL(CM_CLKSEL_CORE); + DUMP_REGL(CM_CLKSEL_DSS); + DUMP_REGL(CM_CLKSEL1_EMU); +} +#else +#define omap3_prcm_register_dump() do { } while (0) +#endif /* CFG_PRCM_DEBUG */ + +/* + * void config_diamond_sdram() + * + * Description: + * This routine initializes the processor's SDRAM Controller (SDRC) + * as appropriate for the Samsung K4X51163PI-FCG6 32 Mb x 16 b (64 + * MiB) DDR SDRAM on the Nest Learning Thermostat board. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +config_diamond_sdram(void) +{ + u32 value, actim_ctrla, actim_ctrlb; + + /* + * Step 1: Reset the SDRC controller and then wait for the reset + * event to clear. + */ + + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_SET, SDRC_SYSCONFIG); + wait_on_value(SDRC_SYSSTATUS_RESETDONE, + SDRC_SYSSTATUS_RESETDONE, + SDRC_STATUS, + 12000000); + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_CLEAR, SDRC_SYSCONFIG); + + /* + * Step 2: Setup the position and geometry of the SDRAM device on + * the controller's bus. + */ + + value = + (SDRC_SHARING_LOCK_OFF | + SDRC_SHARING_CS1MUXCFG_ENCODE(SDRC_SHARING_CS1MUXCFG_16_BIT_16_0) | + SDRC_SHARING_CS0MUXCFG_ENCODE(SDRC_SHARING_CS0MUXCFG_16_BIT_16_0) | + SDRC_SHARING_SDRCTRISTATE_OFF); + __raw_writel(value, SDRC_SHARING); + + /* + * Step 3: Setup the memory configuration, including RAS width, + * CAS width, address multiplexing, size, bank mapping, bus width, + * power mode, DDR type and memory type. + */ + + value = + (SDRC_MCFG_LOCKSTATUS_RW | + SDRC_MCFG_RASWIDTH_ENCODE(SDRC_MCFG_RASWIDTH_14_BITS) | + SDRC_MCFG_CASWIDTH_ENCODE(SDRC_MCFG_CASWIDTH_10_BITS) | + SDRC_MCFG_ADDRMUXLEGACY_FLEXIBLE | + SDRC_MCFG_RAMSIZE_ENCODE(CFG_SDRAM_SIZE_MB) | + SDRC_MCFG_BANKALLOCATION_ENCODE(SDRC_MCFG_BANKALLOCATION_R_B_C)| + SDRC_MCFG_B32NOT16_OFF | + SDRC_MCFG_DEEPPD_SUPPORTED | + SDRC_MCFG_DDRTYPE_ENCODE(SDRC_MCFG_DDRTYPE_MOBILE_DDR) | + SDRC_MCFG_RAMTYPE_ENCODE(SDRC_MCFG_RAMTYPE_DDR)); + __raw_writel(value, SDRC_MCFG_0); + + /* + * Step 4: Establish the AC fine tuning timing characteristics. + */ + + actim_ctrla + = (SDRC_ACTIM_CTRLA_TRFC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRFC) | + SDRC_ACTIM_CTRLA_TRC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRC) | + SDRC_ACTIM_CTRLA_TRAS_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRAS) | + SDRC_ACTIM_CTRLA_TRP_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRP) | + SDRC_ACTIM_CTRLA_TRCD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRCD) | + SDRC_ACTIM_CTRLA_TRRD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRRD) | + SDRC_ACTIM_CTRLA_TDPL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDPL) | + SDRC_ACTIM_CTRLA_TDAL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDAL)); + + actim_ctrlb + = (SDRC_ACTIM_CTRLB_TWTR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TWTR) | + SDRC_ACTIM_CTRLB_TCKE_ENCODE(CFG_SDRC_ACTIM_CTRLB_TCKE) | + SDRC_ACTIM_CTRLB_TXP_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXP) | + SDRC_ACTIM_CTRLB_TXSR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXSR)); + + __raw_writel(actim_ctrla, SDRC_ACTIM_CTRLA_0); + __raw_writel(actim_ctrlb, SDRC_ACTIM_CTRLB_0); + + /* + * Step 5: Establish the memory autorefresh control + */ + + value = + (SDRC_RFR_CTRL_ARCV_ENCODE(1244) | + SDRC_RFR_CTRL_ARE_ENCODE(SDRC_RFR_CTRL_ARE_1_ARCV)); + __raw_writel(value, SDRC_RFR_CTRL_0); + + value = + (SDRC_POWER_REG_WAKEUP_DELAYED | + SDRC_POWER_REG_AUTOCOUNT_ENCODE(0) | + SDRC_POWER_REG_SRFR_ON_RST_ENABLE | + SDRC_POWER_REG_SRFR_ON_IDLE_DISABLE | + SDRC_POWER_REG_CLKCTRL_ENCODE(SDRC_POWER_REG_CLKCTRL_NONE) | + SDRC_POWER_REG_PAGEPOLICY_HPHB); + __raw_writel(value, SDRC_POWER_REG); + + /* + * Step 6: Establish the JEDEC-defined mode and DLL parameters. + */ + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + delay(5000); + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_PRECHARGE_ALL), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + value = + (SDRC_MR_ZERO_1 | + SDRC_MR_WBST_ENABLE | + SDRC_MR_ZERO_0 | + SDRC_MR_CASL_ENCODE(SDRC_MR_CASL_3) | + SDRC_MR_SIL_SERIAL | + SDRC_MR_BL_ENCODE(SDRC_MR_BL_4)); + __raw_writel(value, SDRC_MR_0); + + value = + (SDRC_DLLA_CTRL_FIXED_DELAY_ENCODE(0) | + SDRC_DLLA_CTRL_INIT_LAT_ENCODE(0) | + SDRC_DLLA_CTRL_MODE_ON_IDLE_ENCODE(SDRC_DLLA_CTRL_MODE_ON_IDLE_PWD) | + SDRC_DLLA_CTRL_DLL_ENABLE | + SDRC_DLLA_CTRL_LOCK_TRACKINGDELAY); + __raw_writel(value, SDRC_DLLA_CTRL); + + /* + * Delay for a "reasonably long" period of time to allow the + * requested changes to take effect. + */ + + delay(0x20000); +} + +/* + * void s_init() + * + * Description: + * This routine performs very early system initialization of chip + * pin multiplexing and clocks and is called when ONLY an + * SRAM-based stack is available (i.e. no SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +s_init(void) +{ + watchdog_init(); + try_unlock_memory(); + set_muxconf_regs(); + + delay(100); + + prcm_init(); + per_clocks_enable(); + config_diamond_sdram(); +} + +/* + * int board_init() + * + * Description: + * This routine performs any early, board-specific initialization + * following core CPU initialization but prior to serial and NAND + * initialization. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +board_init(void) +{ + return (0); +} + +/* + * u32 get_device_type() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register DEVICETYPE field, indicating whether the + * device is of TST, EMU, HS or GP type. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register DEVICETYPE field. + * + */ +u32 +get_device_type(void) +{ + const int value = __raw_readl(CONTROL_STATUS); + + return (CONTROL_STATUS_DEVICETYPE_DECODE(value)); +} + +/* + * u32 get_sysboot_value() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register SYSBOOT order subfield, indicating the + * order of memory interfaces from which the processor will attempt + * to boot itself. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register SYSBOOT order subfield. + * + */ +u32 +get_sysboot_value(void) +{ +#if 0 + const u32 value = __raw_readl(CONTROL_STATUS); + const u32 peripheral_type = CONTROL_STATUS_SYSBOOT_TYPE_PERIPHERAL; + + /* + * This routine and callers of it are implicitly expecting the + * MEMORY interface (SYSBOOT[5] == 0) not the PERHIPHERAL + * interface (SYSBOOT[5] == 1) boot order, so check that is + * actually the case. + */ + + if (CONTROL_STATUS_SYSBOOT_TYPE_DECODE(value) == peripheral_type) { + hang(); + } + + return (CONTROL_STATUS_SYSBOOT_ORDER_DECODE(value)); +#else + return __raw_readl(CONTROL_STATUS) & 0x3f; +#endif +} + +/* + * int get_boot_device_list(const u32** device_list) + * + * Description: + * This routine returns a constant list indicating the preferred + * device boot list. + * It gets called from start_armboot in board.c + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The preferred first processor memory boot interface. + * + */ + +int +get_boot_devices_list(const u32** devices_list) +{ + static u32 list[MAX_J49_BOOT_DEVICES]; + const u32 mem_order = get_sysboot_value(); + + // set defaults + int number_of_devices = 0; + *devices_list = &list[0]; + + switch (mem_order) { + case 15: + list[0] = GPMC_NAND; + list[1] = USB_PERIPHERAL; + list[2] = MMC_NAND; + number_of_devices = MAX_J49_BOOT_DEVICES; + break; + case 47: + list[0] = USB_PERIPHERAL; + list[1] = MMC_NAND; + list[2] = GPMC_NAND; + number_of_devices = MAX_J49_BOOT_DEVICES; + break; + default: + break; + } + return number_of_devices; +} + +/* + * int misc_init_r() + * + * Description: + * This routine performs any miscellaneous, board-specific + * initialization following CPU, early board, serial and NAND + * initialization but prior to loading the secondary program loader + * to RAM. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +misc_init_r(void) +{ + return (0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void +wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void +watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +/* + * void foobar() + * + * Description: + * This routine... + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + +#ifdef CONFIG_MMC + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); +#endif + delay(1000); +} + +static int +gpmc_config_0(void) +{ +#if defined(CFG_GPMC_CONFIG1_0) + /* + * First, disable the interface and wait. + */ + __raw_writel(GPMC_CONFIG7_CSVALID_DISABLED, GPMC_CONFIG7_0); + + delay(1000); + + /* + * Next, program the configuration parameters. + */ + __raw_writel(CFG_GPMC_CONFIG1_0, GPMC_CONFIG1_0); + __raw_writel(CFG_GPMC_CONFIG2_0, GPMC_CONFIG2_0); + __raw_writel(CFG_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(CFG_GPMC_CONFIG4_0, GPMC_CONFIG4_0); + __raw_writel(CFG_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __raw_writel(CFG_GPMC_CONFIG6_0, GPMC_CONFIG6_0); + + /* + * Finally, enable the GPMC mapping and spin for the parameters to + * become active. + */ + __raw_writel((CFG_GPMC_CONFIG7_0 | GPMC_CONFIG7_CSVALID_ENABLED), + GPMC_CONFIG7_0); + + delay(2000); + + if (nand_chip()){ + return (1); + } +#endif /* defined(CFG_GPMC_CONFIG1_0) */ + + return (0); +} + +/* + * int nand_init() + * + * Description: + * This routine initializes the General Purpose Memory Controller + * (GPMC) such that on-board NAND devices may be accessed for + * second-stage boot. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if NAND was successfully initialized; otherwise, 1. + * + */ +int +nand_init(void) +{ + int status = 1; + + /* + * Establish GPMC global settings. + */ + + __raw_writel(GPMC_SYSCONFIG_IDLEMODE_SMART, GPMC_SYSCONFIG); + + __raw_writel(GPMC_IRQENABLE_ALL_DISABLE, GPMC_IRQENABLE); + + __raw_writel(GPMC_TIMEOUTENABLE_OFF, GPMC_TIMEOUT_CONTROL); + + if (gpmc_config_0()) { + puts("Unsupported NAND device @ GPMC0!\n"); + goto done; + } + + status = 0; + + done: + /* Dump GPMC and SDRC registers if so configured. */ + + omap3_sdrc_register_dump(); + omap3_gpmc_register_dump(); + omap3_prcm_register_dump(); + + return (status); +} + +/* + * void board_hang() + * + * Description: + * This routine performs any board-specific actions when the system + * hangs by executing hang(). At present, there is nothing to do; + * however, we might later drive the piezo or a LED. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +board_hang (void) +{ + return; +}
diff --git a/x-loader/board/nest/j49-usb-loader/mux.c b/x-loader/board/nest/j49-usb-loader/mux.c new file mode 100644 index 0000000..b8c7df0 --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/mux.c
@@ -0,0 +1,292 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily I/O pad multiplexer configuration. + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> + +#include "platform.h" + +/* + * void set_muxconf_regs() + * + * Description: + * This routines sets the I/O pad multiplexers for UART, GPMC, SDRC, + * GPIO. + * + * The commented string gives the final mux configuration for that pin + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + */ +void +set_muxconf_regs(void) +{ + /* + * The bit fields for these settings are as follows: + * + * I{EN,DIS} - Input Enable/Disable + * PT[DU] - Pull-down, -up + * DIS,EN - Pull-down, -up disabled/enabled + * M[01234567] - Configuration mode 0-7 + */ + + /* + * SDRAM Controller (SDRC) + * + * Most of the SDRC signals are used to drive the Samsung + * K4X51163PI-FCG6 512 Mb x 16-bit (64 MiB) DDR SDRAM. Because we + * interface in 16-bit rather than 32-bit mode, we place the + * unused pins in safe mode (Mode 7). + */ + + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)); // SDRC_D0 + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)); // SDRC_D1 + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)); // SDRC_D2 + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)); // SDRC_D3 + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)); // SDRC_D4 + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)); // SDRC_D5 + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)); // SDRC_D6 + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)); // SDRC_D7 + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)); // SDRC_D8 + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)); // SDRC_D9 + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)); // SDRC_D10 + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)); // SDRC_D11 + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)); // SDRC_D12 + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)); // SDRC_D13 + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)); // SDRC_D14 + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)); // SDRC_D15 + + // Because we interface SDRAM in 16-bit mode, place + // SDRC_DATA[31:16] in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_D16), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D17), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D18), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D19), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D20), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D21), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D22), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D23), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D24), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D25), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D26), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D27), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D28), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D29), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D30), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D31), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)); // SDRC_CLK + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)); // SDRC_DQS0 + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)); // SDRC_DQS1 + + // Place unused DQ pins in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_DQS2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_DQS3), (IDIS | PTD | DIS | M7)); // Unused + + /* + * General Purpose Memory Controller (GPMC) + * + */ + + MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)); // GPMC_A1 + MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)); // GPMC_A2 + MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)); // GPMC_A3 + MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)); // GPMC_A4 + MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)); // GPMC_A5 + MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)); // GPMC_A6 + MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)); // GPMC_A7 + + // Place the unused GPMC_A8 pin in safe mode (Mode 7). + + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_A9 to GPIO_42 used as a push-pull, active low input + // from the USB PHY for USB suspend notification. + + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M7)); // GPIO_42 + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)); // GPMC_D0 + MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)); // GPMC_D1 + MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)); // GPMC_D2 + MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)); // GPMC_D3 + MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)); // GPMC_D4 + MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)); // GPMC_D5 + MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)); // GPMC_D6 + MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)); // GPMC_D7 + MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)); // GPMC_D8 + MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)); // GPMC_D9 + MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)); // GPMC_D10 + MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)); // GPMC_D11 + MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)); // GPMC_D12 + MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)); // GPMC_D13 + MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)); // GPMC_D14 + MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)); // GPMC_D15 + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)); // GPMC_nCS0 + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)); // GPMC_nCS1 + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)); // GPMC_nCS2 + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_NCS6 to GPT11_PWM_EVT used as a push-pull pulse width + // modulated (PWM) signal for the piezo. + + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTD | DIS | M3)); // GPT11_PWM_EVT + + // Assign GPMC_NCS7 to GPIO_58 used as a push-pull output + // PIEZO_NENABLE to the TI SN74LVC2G240 Dual Buffer/Driver With + // 3-State Outputs inputs. + + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTD | DIS | M4)); // GPIO_58 + + MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)); // GPMC_CLK + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); // GPMC_nADV_ALE + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); // GPMC_nOE + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); // GPMC_nWE + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)); // GPMC_nBE0_CLE + + // Assign GPMC_NBE1 to GPIO_61 used as a push-pull output to the + // ZigBee active-low reset. + + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)); // GPIO_61 + + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)); // GPMC_nWP + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)); // GPMC_WAIT0 + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)); // GPMC_WAIT1 + MUX_VAL(CP(GPMC_WAIT2), (IDIS | PTD | DIS | M7)); // Unavailable + + // Assign GPMC_WAIT3 to GPIO_65 used as an active-high, push-pull + // backplate detect input. + + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTD | DIS | M4)); // GPIO_65 + + /* + * Display Subsystem (DSS) + * + * All DSS signals are used in their normal, default mode (Mode 0) + * to drive the Samsung LMS350DF0[13] LCD display panel. + */ + + MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)); // DSS_PCLK + MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)); // DSS_HSYNC + MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)); // DSS_VSYNC + MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)); // DSS_ACBIAS + MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)); // DSS_DATA0 + MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)); // DSS_DATA1 + MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)); // DSS_DATA2 + MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)); // DSS_DATA3 + MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)); // DSS_DATA4 + MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)); // DSS_DATA5 + MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)); // DSS_DATA6 + MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)); // DSS_DATA7 + MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)); // DSS_DATA8 + MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)); // DSS_DATA9 + MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)); // DSS_DATA10 + MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)); // DSS_DATA11 + MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)); // DSS_DATA12 + MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)); // DSS_DATA13 + MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)); // DSS_DATA14 + MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)); // DSS_DATA15 + MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)); // DSS_DATA16 + MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)); // DSS_DATA17 + MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)); // DSS_DATA18 + MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)); // DSS_DATA19 + MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)); // DSS_DATA20 + MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)); // DSS_DATA21 + MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)); // DSS_DATA22 + MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)); // DSS_DATA23 + + MUX_VAL(CP(CAM_WEN), (IDIS | PTD | DIS | M7)); // Unused + + /* + * Universal Asynchronous Receiver / Transmitter (UART) + * + */ + + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); // UART1_TX + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M7)); // UART1_RTS + MUX_VAL(CP(UART1_CTS), (IDIS | PTD | DIS | M7)); // UART1_CTS + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)); // UART1_RX + /* + * Control and Debug + * + */ + + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)); // SYS_32K + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M0)); // SYS_BOOT0 + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M0)); // SYS_BOOT1 + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M0)); // SYS_BOOT2 + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M0)); // SYS_BOOT3 + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M0)); // SYS_BOOT4 + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M0)); // SYS_BOOT5 + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M0)); // SYS_BOOT6 + MUX_VAL(CP(SYS_CLKOUT1), (IDIS | PTU | EN | M0)); // SYS_CLKOUT1 + MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)); // JTAG_nTRST + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)); // JTAG_TCK + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)); // JTAG_TMS + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)); // JTAG_TDI + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)); // JTAG_EMU0 + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)); // JTAG_EMU1 + MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D0_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D1_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D2_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D3_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D4_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D5_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D6_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D7_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D8_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D9_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D12_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D13_ES2), (IDIS | PTD | DIS | M7)); // Unused + + // Assign ETK_D1[45] as MM2_RXRCV and MM2_TXSE0 USB FS/LS Host + // (Mode 5) + + MUX_VAL(CP(ETK_D14_ES2), (IDIS | PTD | DIS | M7)); // MM2_RXRCV + MUX_VAL(CP(ETK_D15_ES2), (IDIS | PTD | DIS | M7)); // MM2_TXSE0 +}
diff --git a/x-loader/board/nest/j49-usb-loader/platform.S b/x-loader/board/nest/j49-usb-loader/platform.S new file mode 100644 index 0000000..0549d27 --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/platform.S
@@ -0,0 +1,557 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific setup for the Nest Learning + * Thermostat board. + * + * It inherits entirely from the equivalent TI OMAP3 EVM + * file. + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG1_0) +flash_cfg3_addr: + .word (GPMC_CONFIG3_0) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG4_0) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG5_0) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL +#endif /* !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) */ + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* + * Tables for 36x/37x devices + * + * (Populated for 13MHz only) + */ +mpu_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_MPU_DPLL_300MHZ) +.word 150, 5, 0, 1 // 12 MHz +.word 300, 12, 0, 1 // 13 MHz +.word 125, 7, 0, 1 // 19.2 MHz +.word 150, 12, 0, 1 // 26 MHz +.word 125, 15, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_MPU_DPLL_600MHZ) +.word 300, 5, 0, 1 // 12 MHz +.word 600, 12, 0, 1 // 13 MHz +.word 125, 3, 0, 1 // 19.2 MHz +.word 300, 12, 0, 1 // 26 MHz +.word 125, 7, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "MPU DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_MPU_DPLL_600MHZ) */ + +iva_36x_dpll_param: +// M N FS M2 +.word 10, 0, 0, 1 // 12 MHz +.word 10, 0, 0, 1 // 13 MHz +.word 10, 0, 0, 1 // 19.2 MHz +.word 10, 0, 0, 1 // 26 MHz +.word 10, 0, 0, 1 // 38.4 MHz +.word 10, 0, 0, 1 // 16.8 MHz + +core_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_CORE_DPLL_200MHZ) +.word 100, 5, 0, 1 // 12 MHz +.word 200, 12, 0, 1 // 13 MHz +.word 375, 35, 0, 1 // 19.2 MHz +.word 100, 12, 0, 1 // 26 MHz +.word 375, 71, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_332MHZ) +.word 166, 5, 0, 1 // 12 MHz +.word 332, 12, 0, 1 // 13 MHz +.word 415, 23, 0, 1 // 19.2 MHz +.word 166, 12, 0, 1 // 26 MHz +.word 415, 47, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_400MHZ) +.word 200, 5, 0, 1 // 12 MHz +.word 400, 12, 0, 1 // 13 MHz +.word 375, 17, 0, 1 // 19.2 MHz +.word 200, 12, 0, 1 // 26 MHz +.word 375, 35, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "Core DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_CORE_DPLL_400MHZ) */ + +/* + * For the peripheral (PER) (aka DPLL4) clock settings, there are only + * effectively two clock choices, 96 MHz or 192 MHz. However, the only + * time 192 MHz is apt to be used in an application is if both SGX and + * TV output are used. + * + * For any given system clock, the dividers are configured thus (per + * Section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" of the OMAP3 TRM): + * + * PER[clkout] = (SYS[clkout] * M) / (N + 1) + * + * M2[clkout]: PER[clkout] / M2 used by UART, MMC, I2C, etc. + * M3[clkout]: PER[clkout] / M3 used by TV out. + * M4[clkout]: PER[clkout] / M4 used by DSS. + * M5[clkout]: PER[clkout] / M5 used by camera. + * M6[clkout]: PER[clkout] / M6 used by emulation. + * + * So, for a 19.2 MHz system clock and the scalar entries below: + * + * PER[clkout] = (19.2 * 540) / (11 + 1) = 864 + * + * M2[clkout]: 864 / 9 = 96 MHz + * M3[clkout]: 864 / 16 = 54 MHz + * M4[clkout]: 864 / 5 = 172.8 MHz + * M5[clkout]: 864 / 4 = 216 MHz + * M6[clkout]: 864 / 3 = 288 MHz + */ +per_36x_dpll_param: +// SYS_CLK M N M2 M3 M4 M5 M6 m2DIV +.word 12000, 432, 5, 9, 16, 9, 4, 3, 1 // 12 MHz +.word 13000, 864, 12, 9, 16, 9, 4, 3, 1 // 13 MHz +.word 19200, 540, 11, 9, 16, 9, 4, 3, 1 // 19.2 MHz +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 // 26 MHz +.word 38400, 270, 11, 9, 16, 9, 4, 3, 1 // 38.4 MHz +.word 16800, 360, 6, 9, 16, 9, 4, 3, 1 // 16.8 MHz + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: + adr r0, mpu_36x_dpll_param + mov pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: + adr r0, iva_36x_dpll_param + mov pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: + adr r0, core_36x_dpll_param + mov pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: + adr r0, per_36x_dpll_param + mov pc, lr
diff --git a/x-loader/board/nest/j49-usb-loader/platform.h b/x-loader/board/nest/j49-usb-loader/platform.h new file mode 100644 index 0000000..8f8c12d --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/platform.h
@@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines data structures and function prototypes for + * accessing Digital Phased Lock Loop (DPLL) parameters and + * settings. + * + */ + +#ifndef _NEST_J49_PLATFORM_H_ +#define _NEST_J49_PLATFORM_H_ + +#include <asm/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Type Definitions + */ + +/* Used to index into DPLL parameter tables */ + +struct dpll_param { + u32 m; + u32 n; + u32 fsel; + u32 m2; +}; + +struct dpll_per_36x_param { + u32 sys_clk; + u32 m; + u32 n; + u32 m2; + u32 m3; + u32 m4; + u32 m5; + u32 m6; + u32 m2div; +}; + +typedef struct dpll_param dpll_param; + +/* + * Inline Functions + */ +static inline void +delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + + +/* + * Function Prototypes + * + * The following functions are exported from platform.S. + */ + +extern dpll_param * get_mpu_dpll_param(void); +extern dpll_param * get_iva_dpll_param(void); +extern dpll_param * get_core_dpll_param(void); +extern dpll_param * get_per_dpll_param(void); + +extern dpll_param * get_36x_mpu_dpll_param(void); +extern dpll_param * get_36x_iva_dpll_param(void); +extern dpll_param * get_36x_core_dpll_param(void); +extern dpll_param * get_36x_per_dpll_param(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NEST_J49_PLATFORM_H_ */
diff --git a/x-loader/board/nest/j49-usb-loader/prcm.c b/x-loader/board/nest/j49-usb-loader/prcm.c new file mode 100644 index 0000000..5625ad7 --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/prcm.c
@@ -0,0 +1,565 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily clock set-up for the processor's Power, Reset and + * Clock Manager (PRCM) + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +#include "platform.h" + +/* + * u32 get_osc_clk_speed() + * + * Description: + * This routine determines the reference oscillator speed based on + * a known 32 kHz clock and general purpose timer. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The reference oscillator clock speed. + * + */ +static u32 +get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & BIT7) + cdiv = 2; + else if (val & BIT6) + cdiv = 1; + else + /* + * Should never reach here! + * TBD: Add a WARN()/BUG() + * For now, assume divider as 1. + */ + cdiv = 1; + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/* + * void get_sys_clkin_sel() + * + * Description: + * This routine sets the value for the PRCM PRM system clock + * frequency selector, which should be written to PRM_CLKSEL. + * + * Input(s): + * hertz - The speed, in MHz, that the system clock is believed + * to be running at. + * sys_clkin_sel - A pointer to storage for the index used to access the + * digital PLL settings. + * + * Output(s): + * sys_clkin_sel - A pointer to the index for the digital PLL settings + * appropriate for the specified system clock rate. + * + * Returns: + * N/A + * + */ +static void +get_sys_clkin_sel(u32 hertz, u32 *sys_clkin_sel) +{ + switch (hertz) { + + case S38_4M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_38_4_MHZ; + break; + + case S26M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_26_0_MHZ; + break; + + case S19_2M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ; + break; + + case S16_8M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_16_8_MHZ; + break; + + case S13M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_13_0_MHZ; + break; + + case S12M: + default: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_12_0_MHZ; + break; + + } +} + +/* + * OMAP34x/35x specific functions + */ +static void +dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_34X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + ptr = (dpll_param *)get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + sr32(CM_CLKSEL2_PLL, 8, 11, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + sr32(CM_CLKEN_PLL, 20, 4, ptr->fsel); + + /* LOCK MODE (EN_PERIPH_DPLL) : CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, ptr->fsel); +} + +static void +iva_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, ptr->fsel); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ +static void +dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_36x_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr += clk_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_36X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct dpll_per_36x_param *ptr; + + ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + sr32(CM_CLKSEL1_EMU, 24, 6, ptr->m6); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + sr32(CM_CLKSEL_CAM, 0, 6, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + sr32(CM_CLKSEL_DSS, 0, 6, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + sr32(CM_CLKSEL_DSS, 8, 6, ptr->m3); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + sr32(CM_CLKSEL2_PLL, 8, 12, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + sr32(CM_CLKSEL_CORE, 12, 2, ptr->m2div); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_36x_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* LOCK MODE (EN_MPU_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); +} + +static void +iva_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * void prcm_init() + * + * Description: + * This routine initializes clocks in a board-specific manner for + * the processor's Power, Reset and Clock Manager (PRCM) and is + * called only when an SRAM-based stack is available (i.e. no + * SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +prcm_init(void) +{ + u32 sys_clk_rate = 0, sys_clkin_sel, sys_clk_div; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + sys_clk_rate = get_osc_clk_speed(); + get_sys_clkin_sel(sys_clk_rate, &sys_clkin_sel); + + /* Set the PRM_CLKSEL_SYS_CLKIN_SEL value in the processor. */ + + sr32(PRCM_PRM_CCR_CLKSEL, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_START, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS, + sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide by two. + * + * On OMAP3630, DDR data corruption has been observed on OFF mode + * exit if the sys clock was lower than 26M. As a work around, + * OMAP3630 is operated at 26M sys clock and this internal division + * is not performed. + */ + + if((is_cpu_family() != CPU_OMAP36XX) && + (sys_clkin_sel > PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ)) { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_2; + clk_index = sys_clkin_sel / 2; + + } else { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_1; + clk_index = sys_clkin_sel / 1; + + } + + sr32(PRCM_PRM_GR_CLKSRC_CTRL, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_START, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS, + sys_clk_div); + + if (is_cpu_family() == CPU_OMAP36XX) { + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + + } else { + sil_index = get_cpu_rev() - 1; + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + iva_init_34xx(sil_index, clk_index); + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +}
diff --git a/x-loader/board/nest/j49-usb-loader/x-load.lds b/x-loader/board/nest/j49-usb-loader/x-load.lds new file mode 100644 index 0000000..e0603a2 --- /dev/null +++ b/x-loader/board/nest/j49-usb-loader/x-load.lds
@@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2010-2011 Nest Labs, Inc. + * All rights reserved. + * + * Description: + * This file is the X-Loader linker scatter file for the Nest + * Learning Thermostat board. + * + */ + +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/nest/j49/Makefile b/x-loader/board/nest/j49/Makefile new file mode 100644 index 0000000..ece4a90 --- /dev/null +++ b/x-loader/board/nest/j49/Makefile
@@ -0,0 +1,62 @@ +# +# Copyright (c) 2010-2011 Nest Labs, Inc. +# All rights reserved. +# +# Description: +# This file is the make file for portions of X-Loader specific +# to the Nest Learning Thermostat board. +# + +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +COBJS := j49.o mux.o prcm.o +SOBJS := platform.o + +CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR) + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(SOBJS) $(OBJS) + $(AR) $(ARFLAGS) $@ $(SOBJS) $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/nest/j49/config.mk b/x-loader/board/nest/j49/config.mk new file mode 100644 index 0000000..881380c --- /dev/null +++ b/x-loader/board/nest/j49/config.mk
@@ -0,0 +1,21 @@ + + +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40200800
diff --git a/x-loader/board/nest/j49/j49.c b/x-loader/board/nest/j49/j49.c new file mode 100644 index 0000000..c934c50 --- /dev/null +++ b/x-loader/board/nest/j49/j49.c
@@ -0,0 +1,1046 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703ACUS, focusing + * primarily on GPIO, RAM and flash initialization. + * + * This is inherited from the OMAP3 EVM equivalent file. + * + * Initialization function order is roughly: + * + * 1) s_init + * 2) board_init + * 3) misc_init_r + */ + +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +#include "platform.h" + +#define MAX_J49_BOOT_DEVICES (3) + +void +udelay(unsigned long usecs) { + delay(usecs); +} + +static inline u32 +get_cpu_id(void) +{ + u32 cpuid = 0; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + + return (cpuid); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 +get_cpu_rev(void) +{ + const u32 cpuid = get_cpu_id(); + + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + if ((cpuid & 0xf) == 0x0) { + return (CPU_3430_ES1); + + } else { + return (CPU_3430_ES2); + + } + +} + +u32 +is_cpu_family(void) +{ + const u32 cpuid = get_cpu_id(); + u32 cpu_family = 0, omap34xx_id = 0; + u16 hawkeye; + + if ((cpuid & 0xf) == 0x0) { + cpu_family = CPU_OMAP34XX; + + } else { + omap34xx_id = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (omap34xx_id >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + + case HAWKEYE_AM35XX: + cpu_family = CPU_AM35XX; + break; + + case HAWKEYE_OMAP36XX: + cpu_family = CPU_OMAP36XX; + break; + + case HAWKEYE_OMAP34XX: + default: + cpu_family = CPU_OMAP34XX; + break; + + } + } + + return (cpu_family); +} +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 +cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/* + * void sr32() + * + * Description: + * This routine clears and sets a value in a bit extent for a + * 32-bit value at the specified address. + * + * Input(s): + * addr - The address at which to clear and set the specified + * specified 32-bit value. + * start_bit - The first bit of the 32-bit data to clear and set. + * num_bits - The range of bits of the 32-bit data to clear and set. + * value - The value to set. + * + * Output(s): + * addr - The address with the specified bit extent cleared and + * set to the specified value. + * + * Returns: + * N/A + * + */ +void +sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + + msk = (1 << num_bits); + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/* + * u32 wait_on_value() + * + * Description: + * This routine reads the register at the specified address and + * busy waits until the specified match value is read or until the + * bounded number of loops have been reached. + * + * Input(s): + * read_bit_mask - The bit mask to apply after reading the register. + * match_value - The value to match on after reading and masking. + * read_addr - The register address to read. + * bound - The maximum number of times to read before giving + * up. + * + * Output(s): + * N/A + * + * Returns: + * True (1) if the match_value was reached; otherwise, false (0). + * + */ +u32 +wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +static void +secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +static void +try_unlock_memory(void) +{ + const int type = get_device_type(); + + /* + * If the processor is a GP device, unlock the device SRAM for + * general use. + */ + + if (type == CONTROL_STATUS_DEVICETYPE_GP) { + secure_unlock(); + } + + return; +} + +#if defined(CFG_SDRAM_DEBUG) +static void +omap3_sdrc_register_dump(void) +{ + printf("\n SDRC Register Dump:\n"); + + DUMP_REGL(SDRC_REVISION); + DUMP_REGL(SDRC_SYSCONFIG); + DUMP_REGL(SDRC_SYSSTATUS); + DUMP_REGL(SDRC_CS_CFG); + DUMP_REGL(SDRC_SHARING); + DUMP_REGL(SDRC_ERR_ADDR); + DUMP_REGL(SDRC_ERR_TYPE); + DUMP_REGL(SDRC_DLLA_CTRL); + DUMP_REGL(SDRC_DLLA_STATUS); + DUMP_REGL(SDRC_POWER_REG); + DUMP_REGL(SDRC_MCFG_0); + DUMP_REGL(SDRC_MR_0); + DUMP_REGL(SDRC_EMR2_0); + DUMP_REGL(SDRC_ACTIM_CTRLA_0); + DUMP_REGL(SDRC_ACTIM_CTRLB_0); + DUMP_REGL(SDRC_RFR_CTRL_0); + DUMP_REGL(SDRC_MANUAL_0); + DUMP_REGL(SDRC_MCFG_1); + DUMP_REGL(SDRC_MR_1); + DUMP_REGL(SDRC_EMR2_1); + DUMP_REGL(SDRC_ACTIM_CTRLA_1); + DUMP_REGL(SDRC_ACTIM_CTRLB_1); + DUMP_REGL(SDRC_RFR_CTRL_1); + DUMP_REGL(SDRC_MANUAL_1); +} +#else +# define omap3_sdrc_register_dump() do { } while (0) +#endif /* defined(CFG_SDRAM_DEBUG) */ + +#if defined(CFG_GPMC_DEBUG) +static void +omap3_gpmc_register_dump(void) +{ + printf("\n GPMC Register Dump:\n"); + + DUMP_REGL(GPMC_REVISION); + DUMP_REGL(GPMC_SYSCONFIG); + DUMP_REGL(GPMC_SYSSTATUS); + DUMP_REGL(GPMC_IRQSTATUS); + DUMP_REGL(GPMC_IRQENABLE); + DUMP_REGL(GPMC_TIMEOUT_CONTROL); + DUMP_REGL(GPMC_ERR_ADDRESS); + DUMP_REGL(GPMC_ERR_TYPE ); + DUMP_REGL(GPMC_CONFIG ); + DUMP_REGL(GPMC_STATUS ); + + DUMP_REGL(GPMC_CONFIG1_0); + DUMP_REGL(GPMC_CONFIG2_0); + DUMP_REGL(GPMC_CONFIG3_0); + DUMP_REGL(GPMC_CONFIG4_0); + DUMP_REGL(GPMC_CONFIG5_0); + DUMP_REGL(GPMC_CONFIG6_0); + DUMP_REGL(GPMC_CONFIG7_0); + + DUMP_REGL(GPMC_CONFIG1_1); + DUMP_REGL(GPMC_CONFIG2_1); + DUMP_REGL(GPMC_CONFIG3_1); + DUMP_REGL(GPMC_CONFIG4_1); + DUMP_REGL(GPMC_CONFIG5_1); + DUMP_REGL(GPMC_CONFIG6_1); + DUMP_REGL(GPMC_CONFIG7_1); + + DUMP_REGL(GPMC_CONFIG1_2); + DUMP_REGL(GPMC_CONFIG2_2); + DUMP_REGL(GPMC_CONFIG3_2); + DUMP_REGL(GPMC_CONFIG5_2); + DUMP_REGL(GPMC_CONFIG4_2); + DUMP_REGL(GPMC_CONFIG6_2); + DUMP_REGL(GPMC_CONFIG7_2); + + DUMP_REGL(GPMC_CONFIG1_3); + DUMP_REGL(GPMC_CONFIG2_3); + DUMP_REGL(GPMC_CONFIG3_3); + DUMP_REGL(GPMC_CONFIG4_3); + DUMP_REGL(GPMC_CONFIG5_3); + DUMP_REGL(GPMC_CONFIG6_3); + DUMP_REGL(GPMC_CONFIG7_3); + + DUMP_REGL(GPMC_CONFIG1_4); + DUMP_REGL(GPMC_CONFIG2_4); + DUMP_REGL(GPMC_CONFIG3_4); + DUMP_REGL(GPMC_CONFIG4_4); + DUMP_REGL(GPMC_CONFIG5_4); + DUMP_REGL(GPMC_CONFIG6_4); + DUMP_REGL(GPMC_CONFIG7_4); + + DUMP_REGL(GPMC_CONFIG1_5); + DUMP_REGL(GPMC_CONFIG2_5); + DUMP_REGL(GPMC_CONFIG3_5); + DUMP_REGL(GPMC_CONFIG4_5); + DUMP_REGL(GPMC_CONFIG5_5); + DUMP_REGL(GPMC_CONFIG6_5); + DUMP_REGL(GPMC_CONFIG7_5); + + DUMP_REGL(GPMC_CONFIG1_6); + DUMP_REGL(GPMC_CONFIG2_6); + DUMP_REGL(GPMC_CONFIG3_6); + DUMP_REGL(GPMC_CONFIG4_6); + DUMP_REGL(GPMC_CONFIG5_6); + DUMP_REGL(GPMC_CONFIG6_6); + DUMP_REGL(GPMC_CONFIG7_6); + + DUMP_REGL(GPMC_CONFIG1_7); + DUMP_REGL(GPMC_CONFIG2_7); + DUMP_REGL(GPMC_CONFIG3_7); + DUMP_REGL(GPMC_CONFIG4_7); + DUMP_REGL(GPMC_CONFIG5_7); + DUMP_REGL(GPMC_CONFIG6_7); + DUMP_REGL(GPMC_CONFIG7_7); + +#if 0 + DUMP_REGL(GPMC_NAND_COMMAND_0); + DUMP_REGL(GPMC_NAND_COMMAND_1); + DUMP_REGL(GPMC_NAND_COMMAND_2); + DUMP_REGL(GPMC_NAND_COMMAND_3); + DUMP_REGL(GPMC_NAND_COMMAND_4); + DUMP_REGL(GPMC_NAND_COMMAND_5); + DUMP_REGL(GPMC_NAND_COMMAND_6); + DUMP_REGL(GPMC_NAND_COMMAND_7); + + DUMP_REGL(GPMC_NAND_ADDRESS_0); + DUMP_REGL(GPMC_NAND_ADDRESS_1); + DUMP_REGL(GPMC_NAND_ADDRESS_2); + DUMP_REGL(GPMC_NAND_ADDRESS_3); + DUMP_REGL(GPMC_NAND_ADDRESS_4); + DUMP_REGL(GPMC_NAND_ADDRESS_5); + DUMP_REGL(GPMC_NAND_ADDRESS_6); + DUMP_REGL(GPMC_NAND_ADDRESS_7); + + DUMP_REGL(GPMC_NAND_DATA_0); + DUMP_REGL(GPMC_NAND_DATA_1); + DUMP_REGL(GPMC_NAND_DATA_2); + DUMP_REGL(GPMC_NAND_DATA_3); + DUMP_REGL(GPMC_NAND_DATA_4); + DUMP_REGL(GPMC_NAND_DATA_5); + DUMP_REGL(GPMC_NAND_DATA_6); + DUMP_REGL(GPMC_NAND_DATA_7); + + DUMP_REGL(GPMC_PREFETCH_CONFIG1); + DUMP_REGL(GPMC_PREFETCH_CONFIG2); + DUMP_REGL(GPMC_PREFETCH_CONTROL); + DUMP_REGL(GPMC_PREFETCH_STATUS); + + DUMP_REGL(GPMC_ECC_CONFIG); + DUMP_REGL(GPMC_ECC_CONTROL); + DUMP_REGL(GPMC_ECC_SIZE_CONFIG); + + DUMP_REGL(GPMC_ECC1_RESULT); + DUMP_REGL(GPMC_ECC2_RESULT); + DUMP_REGL(GPMC_ECC3_RESULT); + DUMP_REGL(GPMC_ECC4_RESULT); + DUMP_REGL(GPMC_ECC5_RESULT); + DUMP_REGL(GPMC_ECC6_RESULT); + DUMP_REGL(GPMC_ECC7_RESULT); + DUMP_REGL(GPMC_ECC8_RESULT); + DUMP_REGL(GPMC_ECC9_RESULT); + + DUMP_REGL(GPMC_BCH_RESULT0_0); + DUMP_REGL(GPMC_BCH_RESULT0_1); + DUMP_REGL(GPMC_BCH_RESULT0_2); + DUMP_REGL(GPMC_BCH_RESULT0_3); + DUMP_REGL(GPMC_BCH_RESULT0_4); + DUMP_REGL(GPMC_BCH_RESULT0_5); + DUMP_REGL(GPMC_BCH_RESULT0_6); + DUMP_REGL(GPMC_BCH_RESULT0_7); + + DUMP_REGL(GPMC_BCH_RESULT1_0); + DUMP_REGL(GPMC_BCH_RESULT1_1); + DUMP_REGL(GPMC_BCH_RESULT1_2); + DUMP_REGL(GPMC_BCH_RESULT1_3); + DUMP_REGL(GPMC_BCH_RESULT1_4); + DUMP_REGL(GPMC_BCH_RESULT1_5); + DUMP_REGL(GPMC_BCH_RESULT1_6); + DUMP_REGL(GPMC_BCH_RESULT1_7); + + DUMP_REGL(GPMC_BCH_RESULT2_0); + DUMP_REGL(GPMC_BCH_RESULT2_1); + DUMP_REGL(GPMC_BCH_RESULT2_2); + DUMP_REGL(GPMC_BCH_RESULT2_3); + DUMP_REGL(GPMC_BCH_RESULT2_4); + DUMP_REGL(GPMC_BCH_RESULT2_5); + DUMP_REGL(GPMC_BCH_RESULT2_6); + DUMP_REGL(GPMC_BCH_RESULT2_7); + + DUMP_REGL(GPMC_BCH_RESULT3_0); + DUMP_REGL(GPMC_BCH_RESULT3_1); + DUMP_REGL(GPMC_BCH_RESULT3_2); + DUMP_REGL(GPMC_BCH_RESULT3_3); + DUMP_REGL(GPMC_BCH_RESULT3_4); + DUMP_REGL(GPMC_BCH_RESULT3_5); + DUMP_REGL(GPMC_BCH_RESULT3_6); + DUMP_REGL(GPMC_BCH_RESULT3_7); + + DUMP_REGL(GPMC_BCH_SWDATA); +#endif +} +#else +# define omap3_gpmc_register_dump() do { } while (0) +#endif /* defined(CFG_NAND_DEBUG) */ + +#if defined(CFG_PRCM_DEBUG) +static void +omap3_prcm_register_dump(void) +{ + printf("\n PRCM Register Dump:\n"); + + DUMP_REGL(PRCM_PRM_CCR_CLKSEL); + DUMP_REGL(PRCM_PRM_GR_CLKSRC_CTRL); + DUMP_REGL(CM_CLKSEL1_PLL); + DUMP_REGL(CM_CLKSEL2_PLL); + DUMP_REGL(CM_CLKSEL3_PLL); + DUMP_REGL(CM_CLKEN_PLL); + DUMP_REGL(CM_CLKSEL1_PLL_MPU); + DUMP_REGL(CM_CLKSEL2_PLL_MPU); + DUMP_REGL(CM_CLKEN_PLL_MPU); + DUMP_REGL(CM_CLKSEL1_PLL_IVA2); + DUMP_REGL(CM_CLKSEL2_PLL_IVA2); + DUMP_REGL(CM_CLKEN_PLL_IVA2); + DUMP_REGL(CM_CLKSEL_CAM); + DUMP_REGL(CM_CLKSEL_CORE); + DUMP_REGL(CM_CLKSEL_DSS); + DUMP_REGL(CM_CLKSEL1_EMU); +} +#else +#define omap3_prcm_register_dump() do { } while (0) +#endif /* CFG_PRCM_DEBUG */ + +/* + * void config_diamond_sdram() + * + * Description: + * This routine initializes the processor's SDRAM Controller (SDRC) + * as appropriate for the Samsung K4X51163PI-FCG6 32 Mb x 16 b (64 + * MiB) DDR SDRAM on the Nest Learning Thermostat board. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +config_diamond_sdram(void) +{ + u32 value, actim_ctrla, actim_ctrlb; + + /* + * Step 1: Reset the SDRC controller and then wait for the reset + * event to clear. + */ + + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_SET, SDRC_SYSCONFIG); + wait_on_value(SDRC_SYSSTATUS_RESETDONE, + SDRC_SYSSTATUS_RESETDONE, + SDRC_STATUS, + 12000000); + __raw_writel(SDRC_SYSCONFIG_SOFTRESET_CLEAR, SDRC_SYSCONFIG); + + /* + * Step 2: Setup the position and geometry of the SDRAM device on + * the controller's bus. + */ + + value = + (SDRC_SHARING_LOCK_OFF | + SDRC_SHARING_CS1MUXCFG_ENCODE(SDRC_SHARING_CS1MUXCFG_16_BIT_16_0) | + SDRC_SHARING_CS0MUXCFG_ENCODE(SDRC_SHARING_CS0MUXCFG_16_BIT_16_0) | + SDRC_SHARING_SDRCTRISTATE_OFF); + __raw_writel(value, SDRC_SHARING); + + /* + * Step 3: Setup the memory configuration, including RAS width, + * CAS width, address multiplexing, size, bank mapping, bus width, + * power mode, DDR type and memory type. + */ + + value = + (SDRC_MCFG_LOCKSTATUS_RW | + SDRC_MCFG_RASWIDTH_ENCODE(SDRC_MCFG_RASWIDTH_14_BITS) | + SDRC_MCFG_CASWIDTH_ENCODE(SDRC_MCFG_CASWIDTH_10_BITS) | + SDRC_MCFG_ADDRMUXLEGACY_FLEXIBLE | + SDRC_MCFG_RAMSIZE_ENCODE(CFG_SDRAM_SIZE_MB) | + SDRC_MCFG_BANKALLOCATION_ENCODE(SDRC_MCFG_BANKALLOCATION_R_B_C)| + SDRC_MCFG_B32NOT16_OFF | + SDRC_MCFG_DEEPPD_SUPPORTED | + SDRC_MCFG_DDRTYPE_ENCODE(SDRC_MCFG_DDRTYPE_MOBILE_DDR) | + SDRC_MCFG_RAMTYPE_ENCODE(SDRC_MCFG_RAMTYPE_DDR)); + __raw_writel(value, SDRC_MCFG_0); + + /* + * Step 4: Establish the AC fine tuning timing characteristics. + */ + + actim_ctrla + = (SDRC_ACTIM_CTRLA_TRFC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRFC) | + SDRC_ACTIM_CTRLA_TRC_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRC) | + SDRC_ACTIM_CTRLA_TRAS_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRAS) | + SDRC_ACTIM_CTRLA_TRP_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRP) | + SDRC_ACTIM_CTRLA_TRCD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRCD) | + SDRC_ACTIM_CTRLA_TRRD_ENCODE(CFG_SDRC_ACTIM_CTRLA_TRRD) | + SDRC_ACTIM_CTRLA_TDPL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDPL) | + SDRC_ACTIM_CTRLA_TDAL_ENCODE(CFG_SDRC_ACTIM_CTRLA_TDAL)); + + actim_ctrlb + = (SDRC_ACTIM_CTRLB_TWTR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TWTR) | + SDRC_ACTIM_CTRLB_TCKE_ENCODE(CFG_SDRC_ACTIM_CTRLB_TCKE) | + SDRC_ACTIM_CTRLB_TXP_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXP) | + SDRC_ACTIM_CTRLB_TXSR_ENCODE(CFG_SDRC_ACTIM_CTRLB_TXSR)); + + __raw_writel(actim_ctrla, SDRC_ACTIM_CTRLA_0); + __raw_writel(actim_ctrlb, SDRC_ACTIM_CTRLB_0); + + /* + * Step 5: Establish the memory autorefresh control + */ + + value = + (SDRC_RFR_CTRL_ARCV_ENCODE(1244) | + SDRC_RFR_CTRL_ARE_ENCODE(SDRC_RFR_CTRL_ARE_1_ARCV)); + __raw_writel(value, SDRC_RFR_CTRL_0); + + value = + (SDRC_POWER_REG_WAKEUP_DELAYED | + SDRC_POWER_REG_AUTOCOUNT_ENCODE(0) | + SDRC_POWER_REG_SRFR_ON_RST_ENABLE | + SDRC_POWER_REG_SRFR_ON_IDLE_DISABLE | + SDRC_POWER_REG_CLKCTRL_ENCODE(SDRC_POWER_REG_CLKCTRL_NONE) | + SDRC_POWER_REG_PAGEPOLICY_HPHB); + __raw_writel(value, SDRC_POWER_REG); + + /* + * Step 6: Establish the JEDEC-defined mode and DLL parameters. + */ + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + delay(5000); + + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_PRECHARGE_ALL), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + __raw_writel(SDRC_MANUAL_CMDCODE_ENCODE(SDRC_MANUAL_CMDCODE_AUTOREFRESH), + SDRC_MANUAL_0); + + value = + (SDRC_MR_ZERO_1 | + SDRC_MR_WBST_ENABLE | + SDRC_MR_ZERO_0 | + SDRC_MR_CASL_ENCODE(SDRC_MR_CASL_3) | + SDRC_MR_SIL_SERIAL | + SDRC_MR_BL_ENCODE(SDRC_MR_BL_4)); + __raw_writel(value, SDRC_MR_0); + + value = + (SDRC_DLLA_CTRL_FIXED_DELAY_ENCODE(0) | + SDRC_DLLA_CTRL_INIT_LAT_ENCODE(0) | + SDRC_DLLA_CTRL_MODE_ON_IDLE_ENCODE(SDRC_DLLA_CTRL_MODE_ON_IDLE_PWD) | + SDRC_DLLA_CTRL_DLL_ENABLE | + SDRC_DLLA_CTRL_LOCK_TRACKINGDELAY); + __raw_writel(value, SDRC_DLLA_CTRL); + + /* + * Delay for a "reasonably long" period of time to allow the + * requested changes to take effect. + */ + + delay(0x20000); +} + +/* + * void s_init() + * + * Description: + * This routine performs very early system initialization of chip + * pin multiplexing and clocks and is called when ONLY an + * SRAM-based stack is available (i.e. no SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +s_init(void) +{ + watchdog_init(); + try_unlock_memory(); + set_muxconf_regs(); + + delay(100); + + prcm_init(); + per_clocks_enable(); + config_diamond_sdram(); +} + +/* + * int board_init() + * + * Description: + * This routine performs any early, board-specific initialization + * following core CPU initialization but prior to serial and NAND + * initialization. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +board_init(void) +{ + return (0); +} + +/* + * u32 get_device_type() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register DEVICETYPE field, indicating whether the + * device is of TST, EMU, HS or GP type. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register DEVICETYPE field. + * + */ +u32 +get_device_type(void) +{ + const int value = __raw_readl(CONTROL_STATUS); + + return (CONTROL_STATUS_DEVICETYPE_DECODE(value)); +} + +/* + * u32 get_sysboot_value() + * + * Description: + * This routine returns the decoded value from the CPU's + * CONTROL_STATUS register SYSBOOT order subfield, indicating the + * order of memory interfaces from which the processor will attempt + * to boot itself. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The decoded CONTROL_STATUS register SYSBOOT order subfield. + * + */ +u32 +get_sysboot_value(void) +{ +#if 0 + const u32 value = __raw_readl(CONTROL_STATUS); + const u32 peripheral_type = CONTROL_STATUS_SYSBOOT_TYPE_PERIPHERAL; + + /* + * This routine and callers of it are implicitly expecting the + * MEMORY interface (SYSBOOT[5] == 0) not the PERHIPHERAL + * interface (SYSBOOT[5] == 1) boot order, so check that is + * actually the case. + */ + + if (CONTROL_STATUS_SYSBOOT_TYPE_DECODE(value) == peripheral_type) { + hang(); + } + + return (CONTROL_STATUS_SYSBOOT_ORDER_DECODE(value)); +#else + return __raw_readl(CONTROL_STATUS) & 0x3f; +#endif +} + +/* + * int get_boot_device_list(const u32** device_list) + * + * Description: + * This routine returns a constant list indicating the preferred + * device boot list. + * It gets called from start_armboot in board.c + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The preferred first processor memory boot interface. + * + */ + +int +get_boot_devices_list(const u32** devices_list) +{ + static u32 list[MAX_J49_BOOT_DEVICES]; + const u32 mem_order = get_sysboot_value(); + + // set defaults + int number_of_devices = 0; + *devices_list = &list[0]; + + switch (mem_order) { + case 15: + list[0] = GPMC_NAND; + list[1] = USB_PERIPHERAL; + list[2] = MMC_NAND; + number_of_devices = MAX_J49_BOOT_DEVICES; + break; + case 47: + list[0] = MMC_NAND; + list[1] = GPMC_NAND; + list[2] = USB_PERIPHERAL; + number_of_devices = MAX_J49_BOOT_DEVICES; + break; + default: + break; + } + return number_of_devices; +} + +/* + * int misc_init_r() + * + * Description: + * This routine performs any miscellaneous, board-specific + * initialization following CPU, early board, serial and NAND + * initialization but prior to loading the secondary program loader + * to RAM. + * + * At present, there is nothing board-specific to do. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if OK; otherwise, non-zero on error. + * + */ +int +misc_init_r(void) +{ + return (0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void +wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void +watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +/* + * void foobar() + * + * Description: + * This routine... + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + +#ifdef CONFIG_MMC + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); +#endif + delay(1000); +} + +static int +gpmc_config_0(void) +{ +#if defined(CFG_GPMC_CONFIG1_0) + /* + * First, disable the interface and wait. + */ + __raw_writel(GPMC_CONFIG7_CSVALID_DISABLED, GPMC_CONFIG7_0); + + delay(1000); + + /* + * Next, program the configuration parameters. + */ + __raw_writel(CFG_GPMC_CONFIG1_0, GPMC_CONFIG1_0); + __raw_writel(CFG_GPMC_CONFIG2_0, GPMC_CONFIG2_0); + __raw_writel(CFG_GPMC_CONFIG3_0, GPMC_CONFIG3_0); + __raw_writel(CFG_GPMC_CONFIG4_0, GPMC_CONFIG4_0); + __raw_writel(CFG_GPMC_CONFIG5_0, GPMC_CONFIG5_0); + __raw_writel(CFG_GPMC_CONFIG6_0, GPMC_CONFIG6_0); + + /* + * Finally, enable the GPMC mapping and spin for the parameters to + * become active. + */ + __raw_writel((CFG_GPMC_CONFIG7_0 | GPMC_CONFIG7_CSVALID_ENABLED), + GPMC_CONFIG7_0); + + delay(2000); + + if (nand_chip()){ + return (1); + } +#endif /* defined(CFG_GPMC_CONFIG1_0) */ + + return (0); +} + +/* + * int nand_init() + * + * Description: + * This routine initializes the General Purpose Memory Controller + * (GPMC) such that on-board NAND devices may be accessed for + * second-stage boot. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * 0 if NAND was successfully initialized; otherwise, 1. + * + */ +int +nand_init(void) +{ + int status = 1; + + /* + * Establish GPMC global settings. + */ + + __raw_writel(GPMC_SYSCONFIG_IDLEMODE_SMART, GPMC_SYSCONFIG); + + __raw_writel(GPMC_IRQENABLE_ALL_DISABLE, GPMC_IRQENABLE); + + __raw_writel(GPMC_TIMEOUTENABLE_OFF, GPMC_TIMEOUT_CONTROL); + + if (gpmc_config_0()) { + puts("Unsupported NAND device @ GPMC0!\n"); + goto done; + } + + status = 0; + + done: + /* Dump GPMC and SDRC registers if so configured. */ + + omap3_sdrc_register_dump(); + omap3_gpmc_register_dump(); + omap3_prcm_register_dump(); + + return (status); +} + +/* + * void board_hang() + * + * Description: + * This routine performs any board-specific actions when the system + * hangs by executing hang(). At present, there is nothing to do; + * however, we might later drive the piezo or a LED. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +board_hang (void) +{ + return; +}
diff --git a/x-loader/board/nest/j49/mux.c b/x-loader/board/nest/j49/mux.c new file mode 100644 index 0000000..b8c7df0 --- /dev/null +++ b/x-loader/board/nest/j49/mux.c
@@ -0,0 +1,292 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily I/O pad multiplexer configuration. + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> + +#include "platform.h" + +/* + * void set_muxconf_regs() + * + * Description: + * This routines sets the I/O pad multiplexers for UART, GPMC, SDRC, + * GPIO. + * + * The commented string gives the final mux configuration for that pin + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + */ +void +set_muxconf_regs(void) +{ + /* + * The bit fields for these settings are as follows: + * + * I{EN,DIS} - Input Enable/Disable + * PT[DU] - Pull-down, -up + * DIS,EN - Pull-down, -up disabled/enabled + * M[01234567] - Configuration mode 0-7 + */ + + /* + * SDRAM Controller (SDRC) + * + * Most of the SDRC signals are used to drive the Samsung + * K4X51163PI-FCG6 512 Mb x 16-bit (64 MiB) DDR SDRAM. Because we + * interface in 16-bit rather than 32-bit mode, we place the + * unused pins in safe mode (Mode 7). + */ + + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)); // SDRC_D0 + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)); // SDRC_D1 + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)); // SDRC_D2 + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)); // SDRC_D3 + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)); // SDRC_D4 + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)); // SDRC_D5 + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)); // SDRC_D6 + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)); // SDRC_D7 + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)); // SDRC_D8 + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)); // SDRC_D9 + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)); // SDRC_D10 + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)); // SDRC_D11 + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)); // SDRC_D12 + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)); // SDRC_D13 + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)); // SDRC_D14 + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)); // SDRC_D15 + + // Because we interface SDRAM in 16-bit mode, place + // SDRC_DATA[31:16] in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_D16), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D17), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D18), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D19), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D20), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D21), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D22), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D23), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D24), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D25), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D26), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D27), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D28), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D29), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D30), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_D31), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)); // SDRC_CLK + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)); // SDRC_DQS0 + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)); // SDRC_DQS1 + + // Place unused DQ pins in safe mode (Mode 7). + + MUX_VAL(CP(SDRC_DQS2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(SDRC_DQS3), (IDIS | PTD | DIS | M7)); // Unused + + /* + * General Purpose Memory Controller (GPMC) + * + */ + + MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)); // GPMC_A1 + MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)); // GPMC_A2 + MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)); // GPMC_A3 + MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)); // GPMC_A4 + MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)); // GPMC_A5 + MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)); // GPMC_A6 + MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)); // GPMC_A7 + + // Place the unused GPMC_A8 pin in safe mode (Mode 7). + + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_A9 to GPIO_42 used as a push-pull, active low input + // from the USB PHY for USB suspend notification. + + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M7)); // GPIO_42 + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M7)); // Unused + + MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)); // GPMC_D0 + MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)); // GPMC_D1 + MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)); // GPMC_D2 + MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)); // GPMC_D3 + MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)); // GPMC_D4 + MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)); // GPMC_D5 + MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)); // GPMC_D6 + MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)); // GPMC_D7 + MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)); // GPMC_D8 + MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)); // GPMC_D9 + MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)); // GPMC_D10 + MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)); // GPMC_D11 + MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)); // GPMC_D12 + MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)); // GPMC_D13 + MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)); // GPMC_D14 + MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)); // GPMC_D15 + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)); // GPMC_nCS0 + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)); // GPMC_nCS1 + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)); // GPMC_nCS2 + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M7)); // Unused + + // Assign GPMC_NCS6 to GPT11_PWM_EVT used as a push-pull pulse width + // modulated (PWM) signal for the piezo. + + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTD | DIS | M3)); // GPT11_PWM_EVT + + // Assign GPMC_NCS7 to GPIO_58 used as a push-pull output + // PIEZO_NENABLE to the TI SN74LVC2G240 Dual Buffer/Driver With + // 3-State Outputs inputs. + + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTD | DIS | M4)); // GPIO_58 + + MUX_VAL(CP(GPMC_CLK), (IDIS | PTU | EN | M0)); // GPMC_CLK + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); // GPMC_nADV_ALE + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); // GPMC_nOE + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); // GPMC_nWE + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)); // GPMC_nBE0_CLE + + // Assign GPMC_NBE1 to GPIO_61 used as a push-pull output to the + // ZigBee active-low reset. + + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)); // GPIO_61 + + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)); // GPMC_nWP + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)); // GPMC_WAIT0 + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)); // GPMC_WAIT1 + MUX_VAL(CP(GPMC_WAIT2), (IDIS | PTD | DIS | M7)); // Unavailable + + // Assign GPMC_WAIT3 to GPIO_65 used as an active-high, push-pull + // backplate detect input. + + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTD | DIS | M4)); // GPIO_65 + + /* + * Display Subsystem (DSS) + * + * All DSS signals are used in their normal, default mode (Mode 0) + * to drive the Samsung LMS350DF0[13] LCD display panel. + */ + + MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)); // DSS_PCLK + MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)); // DSS_HSYNC + MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)); // DSS_VSYNC + MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)); // DSS_ACBIAS + MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)); // DSS_DATA0 + MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)); // DSS_DATA1 + MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)); // DSS_DATA2 + MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)); // DSS_DATA3 + MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)); // DSS_DATA4 + MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)); // DSS_DATA5 + MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)); // DSS_DATA6 + MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)); // DSS_DATA7 + MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)); // DSS_DATA8 + MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)); // DSS_DATA9 + MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)); // DSS_DATA10 + MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)); // DSS_DATA11 + MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)); // DSS_DATA12 + MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)); // DSS_DATA13 + MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)); // DSS_DATA14 + MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)); // DSS_DATA15 + MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)); // DSS_DATA16 + MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)); // DSS_DATA17 + MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)); // DSS_DATA18 + MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)); // DSS_DATA19 + MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)); // DSS_DATA20 + MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)); // DSS_DATA21 + MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)); // DSS_DATA22 + MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)); // DSS_DATA23 + + MUX_VAL(CP(CAM_WEN), (IDIS | PTD | DIS | M7)); // Unused + + /* + * Universal Asynchronous Receiver / Transmitter (UART) + * + */ + + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)); // UART1_TX + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M7)); // UART1_RTS + MUX_VAL(CP(UART1_CTS), (IDIS | PTD | DIS | M7)); // UART1_CTS + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)); // UART1_RX + /* + * Control and Debug + * + */ + + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)); // SYS_32K + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M0)); // SYS_BOOT0 + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M0)); // SYS_BOOT1 + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M0)); // SYS_BOOT2 + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M0)); // SYS_BOOT3 + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M0)); // SYS_BOOT4 + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M0)); // SYS_BOOT5 + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M0)); // SYS_BOOT6 + MUX_VAL(CP(SYS_CLKOUT1), (IDIS | PTU | EN | M0)); // SYS_CLKOUT1 + MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)); // JTAG_nTRST + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)); // JTAG_TCK + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)); // JTAG_TMS + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)); // JTAG_TDI + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)); // JTAG_EMU0 + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)); // JTAG_EMU1 + MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D0_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D1_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D2_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D3_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D4_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D5_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D6_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D7_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D8_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D9_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D12_ES2), (IDIS | PTD | DIS | M7)); // Unused + MUX_VAL(CP(ETK_D13_ES2), (IDIS | PTD | DIS | M7)); // Unused + + // Assign ETK_D1[45] as MM2_RXRCV and MM2_TXSE0 USB FS/LS Host + // (Mode 5) + + MUX_VAL(CP(ETK_D14_ES2), (IDIS | PTD | DIS | M7)); // MM2_RXRCV + MUX_VAL(CP(ETK_D15_ES2), (IDIS | PTD | DIS | M7)); // MM2_TXSE0 +}
diff --git a/x-loader/board/nest/j49/platform.S b/x-loader/board/nest/j49/platform.S new file mode 100644 index 0000000..0549d27 --- /dev/null +++ b/x-loader/board/nest/j49/platform.S
@@ -0,0 +1,557 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, Inc. + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + * + * Description: + * This file is the board-specific setup for the Nest Learning + * Thermostat board. + * + * It inherits entirely from the equivalent TI OMAP3 EVM + * file. + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG1_0) +flash_cfg3_addr: + .word (GPMC_CONFIG3_0) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG4_0) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG5_0) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL +#endif /* !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) */ + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* + * Tables for 36x/37x devices + * + * (Populated for 13MHz only) + */ +mpu_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_MPU_DPLL_300MHZ) +.word 150, 5, 0, 1 // 12 MHz +.word 300, 12, 0, 1 // 13 MHz +.word 125, 7, 0, 1 // 19.2 MHz +.word 150, 12, 0, 1 // 26 MHz +.word 125, 15, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_MPU_DPLL_600MHZ) +.word 300, 5, 0, 1 // 12 MHz +.word 600, 12, 0, 1 // 13 MHz +.word 125, 3, 0, 1 // 19.2 MHz +.word 300, 12, 0, 1 // 26 MHz +.word 125, 7, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "MPU DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_MPU_DPLL_600MHZ) */ + +iva_36x_dpll_param: +// M N FS M2 +.word 10, 0, 0, 1 // 12 MHz +.word 10, 0, 0, 1 // 13 MHz +.word 10, 0, 0, 1 // 19.2 MHz +.word 10, 0, 0, 1 // 26 MHz +.word 10, 0, 0, 1 // 38.4 MHz +.word 10, 0, 0, 1 // 16.8 MHz + +core_36x_dpll_param: +// M N FS M2 +#if defined(CONFIG_SYS_CORE_DPLL_200MHZ) +.word 100, 5, 0, 1 // 12 MHz +.word 200, 12, 0, 1 // 13 MHz +.word 375, 35, 0, 1 // 19.2 MHz +.word 100, 12, 0, 1 // 26 MHz +.word 375, 71, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_332MHZ) +.word 166, 5, 0, 1 // 12 MHz +.word 332, 12, 0, 1 // 13 MHz +.word 415, 23, 0, 1 // 19.2 MHz +.word 166, 12, 0, 1 // 26 MHz +.word 415, 47, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#elif defined(CONFIG_SYS_CORE_DPLL_400MHZ) +.word 200, 5, 0, 1 // 12 MHz +.word 400, 12, 0, 1 // 13 MHz +.word 375, 17, 0, 1 // 19.2 MHz +.word 200, 12, 0, 1 // 26 MHz +.word 375, 35, 0, 1 // 38.4 MHz +.word 0, 0, 0, 1 // 16.8 MHz - TBD +#else +# error "Core DPLL settings are not defined!" +#endif /* defined(CONFIG_SYS_CORE_DPLL_400MHZ) */ + +/* + * For the peripheral (PER) (aka DPLL4) clock settings, there are only + * effectively two clock choices, 96 MHz or 192 MHz. However, the only + * time 192 MHz is apt to be used in an application is if both SGX and + * TV output are used. + * + * For any given system clock, the dividers are configured thus (per + * Section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" of the OMAP3 TRM): + * + * PER[clkout] = (SYS[clkout] * M) / (N + 1) + * + * M2[clkout]: PER[clkout] / M2 used by UART, MMC, I2C, etc. + * M3[clkout]: PER[clkout] / M3 used by TV out. + * M4[clkout]: PER[clkout] / M4 used by DSS. + * M5[clkout]: PER[clkout] / M5 used by camera. + * M6[clkout]: PER[clkout] / M6 used by emulation. + * + * So, for a 19.2 MHz system clock and the scalar entries below: + * + * PER[clkout] = (19.2 * 540) / (11 + 1) = 864 + * + * M2[clkout]: 864 / 9 = 96 MHz + * M3[clkout]: 864 / 16 = 54 MHz + * M4[clkout]: 864 / 5 = 172.8 MHz + * M5[clkout]: 864 / 4 = 216 MHz + * M6[clkout]: 864 / 3 = 288 MHz + */ +per_36x_dpll_param: +// SYS_CLK M N M2 M3 M4 M5 M6 m2DIV +.word 12000, 432, 5, 9, 16, 9, 4, 3, 1 // 12 MHz +.word 13000, 864, 12, 9, 16, 9, 4, 3, 1 // 13 MHz +.word 19200, 540, 11, 9, 16, 9, 4, 3, 1 // 19.2 MHz +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 // 26 MHz +.word 38400, 270, 11, 9, 16, 9, 4, 3, 1 // 38.4 MHz +.word 16800, 360, 6, 9, 16, 9, 4, 3, 1 // 16.8 MHz + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: + adr r0, mpu_36x_dpll_param + mov pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: + adr r0, iva_36x_dpll_param + mov pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: + adr r0, core_36x_dpll_param + mov pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: + adr r0, per_36x_dpll_param + mov pc, lr
diff --git a/x-loader/board/nest/j49/platform.h b/x-loader/board/nest/j49/platform.h new file mode 100644 index 0000000..8f8c12d --- /dev/null +++ b/x-loader/board/nest/j49/platform.h
@@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines data structures and function prototypes for + * accessing Digital Phased Lock Loop (DPLL) parameters and + * settings. + * + */ + +#ifndef _NEST_J49_PLATFORM_H_ +#define _NEST_J49_PLATFORM_H_ + +#include <asm/types.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Type Definitions + */ + +/* Used to index into DPLL parameter tables */ + +struct dpll_param { + u32 m; + u32 n; + u32 fsel; + u32 m2; +}; + +struct dpll_per_36x_param { + u32 sys_clk; + u32 m; + u32 n; + u32 m2; + u32 m3; + u32 m4; + u32 m5; + u32 m6; + u32 m2div; +}; + +typedef struct dpll_param dpll_param; + +/* + * Inline Functions + */ +static inline void +delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + + +/* + * Function Prototypes + * + * The following functions are exported from platform.S. + */ + +extern dpll_param * get_mpu_dpll_param(void); +extern dpll_param * get_iva_dpll_param(void); +extern dpll_param * get_core_dpll_param(void); +extern dpll_param * get_per_dpll_param(void); + +extern dpll_param * get_36x_mpu_dpll_param(void); +extern dpll_param * get_36x_iva_dpll_param(void); +extern dpll_param * get_36x_core_dpll_param(void); +extern dpll_param * get_36x_per_dpll_param(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _NEST_J49_PLATFORM_H_ */
diff --git a/x-loader/board/nest/j49/prcm.c b/x-loader/board/nest/j49/prcm.c new file mode 100644 index 0000000..5625ad7 --- /dev/null +++ b/x-loader/board/nest/j49/prcm.c
@@ -0,0 +1,565 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file is the board-specific set-up for the Nest Learning + * Thermostat board, based on the TI OMAP3 AM3703CUS, focusing + * primarily clock set-up for the processor's Power, Reset and + * Clock Manager (PRCM) + * + * This is originally inherited and split from the OMAP3 EVM + * board file. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +#include "platform.h" + +/* + * u32 get_osc_clk_speed() + * + * Description: + * This routine determines the reference oscillator speed based on + * a known 32 kHz clock and general purpose timer. + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * The reference oscillator clock speed. + * + */ +static u32 +get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & BIT7) + cdiv = 2; + else if (val & BIT6) + cdiv = 1; + else + /* + * Should never reach here! + * TBD: Add a WARN()/BUG() + * For now, assume divider as 1. + */ + cdiv = 1; + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/* + * void get_sys_clkin_sel() + * + * Description: + * This routine sets the value for the PRCM PRM system clock + * frequency selector, which should be written to PRM_CLKSEL. + * + * Input(s): + * hertz - The speed, in MHz, that the system clock is believed + * to be running at. + * sys_clkin_sel - A pointer to storage for the index used to access the + * digital PLL settings. + * + * Output(s): + * sys_clkin_sel - A pointer to the index for the digital PLL settings + * appropriate for the specified system clock rate. + * + * Returns: + * N/A + * + */ +static void +get_sys_clkin_sel(u32 hertz, u32 *sys_clkin_sel) +{ + switch (hertz) { + + case S38_4M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_38_4_MHZ; + break; + + case S26M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_26_0_MHZ; + break; + + case S19_2M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ; + break; + + case S16_8M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_16_8_MHZ; + break; + + case S13M: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_13_0_MHZ; + break; + + case S12M: + default: + *sys_clkin_sel = PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_12_0_MHZ; + break; + + } +} + +/* + * OMAP34x/35x specific functions + */ +static void +dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_34X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + ptr = (dpll_param *)get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + sr32(CM_CLKSEL2_PLL, 8, 11, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + sr32(CM_CLKEN_PLL, 20, 4, ptr->fsel); + + /* LOCK MODE (EN_PERIPH_DPLL) : CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, ptr->fsel); +} + +static void +iva_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, ptr->fsel); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ +static void +dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_36x_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr += clk_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_36X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void +dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct dpll_per_36x_param *ptr; + + ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + sr32(CM_CLKSEL1_EMU, 24, 6, ptr->m6); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + sr32(CM_CLKSEL_CAM, 0, 6, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + sr32(CM_CLKSEL_DSS, 0, 6, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + sr32(CM_CLKSEL_DSS, 8, 6, ptr->m3); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + sr32(CM_CLKSEL2_PLL, 8, 12, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + sr32(CM_CLKSEL_CORE, 12, 2, ptr->m2div); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void +mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_36x_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* LOCK MODE (EN_MPU_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); +} + +static void +iva_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * void prcm_init() + * + * Description: + * This routine initializes clocks in a board-specific manner for + * the processor's Power, Reset and Clock Manager (PRCM) and is + * called only when an SRAM-based stack is available (i.e. no + * SDRAM). + * + * Input(s): + * N/A + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ +void +prcm_init(void) +{ + u32 sys_clk_rate = 0, sys_clkin_sel, sys_clk_div; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + sys_clk_rate = get_osc_clk_speed(); + get_sys_clkin_sel(sys_clk_rate, &sys_clkin_sel); + + /* Set the PRM_CLKSEL_SYS_CLKIN_SEL value in the processor. */ + + sr32(PRCM_PRM_CCR_CLKSEL, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_START, + PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS, + sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide by two. + * + * On OMAP3630, DDR data corruption has been observed on OFF mode + * exit if the sys clock was lower than 26M. As a work around, + * OMAP3630 is operated at 26M sys clock and this internal division + * is not performed. + */ + + if((is_cpu_family() != CPU_OMAP36XX) && + (sys_clkin_sel > PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ)) { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_2; + clk_index = sys_clkin_sel / 2; + + } else { + sys_clk_div = PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_1; + clk_index = sys_clkin_sel / 1; + + } + + sr32(PRCM_PRM_GR_CLKSRC_CTRL, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_START, + PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS, + sys_clk_div); + + if (is_cpu_family() == CPU_OMAP36XX) { + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + + } else { + sil_index = get_cpu_rev() - 1; + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + iva_init_34xx(sil_index, clk_index); + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +}
diff --git a/x-loader/board/nest/j49/x-load.lds b/x-loader/board/nest/j49/x-load.lds new file mode 100644 index 0000000..e0603a2 --- /dev/null +++ b/x-loader/board/nest/j49/x-load.lds
@@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2010-2011 Nest Labs, Inc. + * All rights reserved. + * + * Description: + * This file is the X-Loader linker scatter file for the Nest + * Learning Thermostat board. + * + */ + +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap1710h3/Makefile b/x-loader/board/omap1710h3/Makefile new file mode 100644 index 0000000..f4020af --- /dev/null +++ b/x-loader/board/omap1710h3/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap1710h3.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap1710h3/config.mk b/x-loader/board/omap1710h3/config.mk new file mode 100644 index 0000000..d9e3c76 --- /dev/null +++ b/x-loader/board/omap1710h3/config.mk
@@ -0,0 +1,26 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <gj@denx.de> +# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> +# +# (C) Copyright 2004 +# Texas Instruments, <www.ti.com> +# Kshitij Gupta <Kshitij@ti.com> +# +# TI H3 board with OMAP1710 (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 +# +# + +PLATFORM_LDFLAGS += -no-warn-mismatch +TEXT_BASE = 0x11080000
diff --git a/x-loader/board/omap1710h3/omap1710h3.c b/x-loader/board/omap1710h3/omap1710h3.c new file mode 100644 index 0000000..245cfe2 --- /dev/null +++ b/x-loader/board/omap1710h3/omap1710h3.c
@@ -0,0 +1,89 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * + * (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> + * + * 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> +#if defined(CONFIG_OMAP1710) +#include <./configs/omap1510.h> +#endif + +#define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF) + +int board_init (void) +{ +#ifdef CFG_PRINTF + + /* setup for UART1 */ + *(volatile unsigned int *) ((unsigned int)FUNC_MUX_CTRL_0) &= ~(0x02000000); /* bit 25 */ + /* bit 29 for UART1 */ + *(volatile unsigned int *) ((unsigned int)MOD_CONF_CTRL_0) &= ~(0x00002000); + + /* Enable the power for UART1 */ +#define UART1_48MHZ_ENABLE ((unsigned short)0x0200) +#define SW_CLOCK_REQUEST 0xFFFE0834 + *((volatile unsigned short *)SW_CLOCK_REQUEST) |= UART1_48MHZ_ENABLE; + +#endif + + *(volatile unsigned int *) ((unsigned int)COMP_MODE_CTRL_0) = COMP_MODE_ENABLE; + return 0; +} + +#define GPIO1_DIRECTION 0xFFFBE434 +#define FUNC_MUX_CTRL_F 0xFFFE1094 +#define PU_PD_SEL_4 0xFFFE10C4 +/* + * On H3 board, Nand R/B is tied to GPIO_10 + * We setup this GPIO pin + */ +int nand_init (void) +{ + + /* GPIO_10 for input. it is in GPIO1 module */ + *(volatile unsigned int *) ((unsigned int)GPIO1_DIRECTION) |= 0x0400; + + /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */ + *(volatile unsigned int *) ((unsigned int)FUNC_MUX_CTRL_F) &= 0xC7FFFFFF; + *(volatile unsigned int *) ((unsigned int)FUNC_MUX_CTRL_F) |= 0x08000000; + + /* GPIO10 pullup/down register, Enable pullup on GPIO10 */ + *(volatile unsigned int *) ((unsigned int)PU_PD_SEL_4) |= 0x08; + + if (nand_chip()){ + printf("Unsupported Chip!\n"); + return 1; + } + return 0; +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{} +
diff --git a/x-loader/board/omap1710h3/platform.S b/x-loader/board/omap1710h3/platform.S new file mode 100644 index 0000000..ef64e3e --- /dev/null +++ b/x-loader/board/omap1710h3/platform.S
@@ -0,0 +1,410 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@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 <config.h> +#if defined(CONFIG_OMAP1710) +#include <./configs/omap1510.h> +#endif + + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +.globl platformsetup +platformsetup: + + + /*------------------------------------------------------* + * 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] + + + mov r1, #0x05 /* 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 */ + ldr r1, VAL_ARM_SYSST + 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... * + *------------------------------------------------------*/ + 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 */ + + /* + * 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] + + /* Enable EMIFF TC Doubler in OMAP1710 */ + ldr r0, REG_EMIFF_DOUBLER + mov r0, #0x1; + +common_tc: + /* slow interface */ + ldr r1, VAL_TC_EMIFS_CONFIG + ldr r0, REG_TC_EMIFS_CONFIG + str r1, [r0] + +#ifdef CFG_BOOT_CS0 + /* Chip Select 3 for NAND*/ + ldr r1, VAL_TC_EMIFS_CS3_CONFIG + ldr r0, REG_TC_EMIFS_CS3_CONFIG + str r1, [r0] +#else + /* Chip Select 2 for NAND*/ + ldr r1, VAL_TC_EMIFS_CS2_CONFIG + ldr r0, REG_TC_EMIFS_CS2_CONFIG + 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 + + +REG_TC_EMIFS_CONFIG: /* 32 bits */ + .word 0xfffecc0c +#ifdef CFG_BOOT_CS0 +REG_TC_EMIFS_CS3_CONFIG: /* 32 bits */ + .word 0xfffecc1c +#else +REG_TC_EMIFS_CS2_CONFIG: /* 32 bits */ + .word 0xfffecc18 +#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 + +REG_EMIFF_DOUBLER: + .word 0xfffecc60 + +/* 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 0xfffecc64 +DLL_WRT_CONTROL_VAL: + .word 0x03500002 + +/* URD DLL register */ +REG_DLL_URD_CONTROL: + .word 0xfffeccc0 +DLL_URD_CONTROL_VAL: + .word 0x00000006 + +/* LRD DLL register */ +REG_DLL_LRD_CONTROL: + .word 0xfffecccc + +REG_WATCHDOG: + .word 0xfffec808 + +REG_MPU_LOAD_TIMER: + .word 0xfffec600 +REG_MPU_CNTL_TIMER: + .word 0xfffec500 + +/* 96 MHz Samsung Mobile DDR */ +SDRAM_CONFIG_VAL: + .word 0x0c028af4 + +DLL_LRD_CONTROL_VAL: + .word 0x00000006 + +VAL_ARM_CKCTL: + .word 0x350e +VAL_ARM_SYSST: + .word 0x1001 + +VAL_DPLL1_CTL: + .word 0x2810 + +#ifdef CFG_BOOT_CS0 +VAL_TC_EMIFS_CONFIG: + .word 0x00000010 +VAL_TC_EMIFS_CS3_CONFIG: + .word 0xff80fff3 +#else +VAL_TC_EMIFS_CONFIG: + .word 0x00000012 /*swap CS0/CS3 addressing */ +VAL_TC_EMIFS_CS2_CONFIG: + .word 0xff80fff3 +#endif + + +VAL_TC_EMIFF_SDRAM_CONFIG: + .word 0x010290fc +VAL_TC_EMIFF_MRS: + .word 0x00000027 + +VAL_ARM_IDLECT1: + .word 0x000014c6 + +VAL_ARM_IDLECT2: + .word 0x000009ff +VAL_ARM_IDLECT3: + .word 0x0000003f + +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
diff --git a/x-loader/board/omap1710h3/x-load.lds b/x-loader/board/omap1710h3/x-load.lds new file mode 100644 index 0000000..7b84eea --- /dev/null +++ b/x-loader/board/omap1710h3/x-load.lds
@@ -0,0 +1,49 @@ +/* + * (C) Copyright 2004 Texas Instruments + * + * (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 : + { + cpu/arm926ejs/start.o (.text) + *(.text) + } + . = ALIGN(4); + .rodata : { *(.rodata) } + . = ALIGN(4); + .data : { *(.data) } + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap2420h4/Makefile b/x-loader/board/omap2420h4/Makefile new file mode 100644 index 0000000..5a47428 --- /dev/null +++ b/x-loader/board/omap2420h4/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap2420h4.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap2420h4/config.mk b/x-loader/board/omap2420h4/config.mk new file mode 100644 index 0000000..1c770f3 --- /dev/null +++ b/x-loader/board/omap2420h4/config.mk
@@ -0,0 +1,26 @@ +# +# (C) Copyright 2004 +# Texas Instruments, <www.ti.com> +# +# TI H4 board with OMAP2420 (ARM1136) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0 +# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) ES2 will be configurable +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# For use with external or internal boots. +# CONFIG_PARTIAL_SRAM must be defined to use this. +TEXT_BASE = 0x80e80000 + +# Used with full SRAM boot. +# This is either with a GP system or a signed boot image. +# easiest, and safest way to go if you can. +# Comment out //CONFIG_PARTIAL_SRAM for this one. +# +#TEXT_BASE = 0x40280000 +
diff --git a/x-loader/board/omap2420h4/omap2420h4.c b/x-loader/board/omap2420h4/omap2420h4.c new file mode 100644 index 0000000..ef81b49 --- /dev/null +++ b/x-loader/board/omap2420h4/omap2420h4.c
@@ -0,0 +1,598 @@ +/* + * Copyright (C) 2005 Texas Instruments. + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 <asm/arch/omap2420.h> +#include <asm/arch/bits.h> + +#include <asm/arch/mem.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +static void wait_for_command_complete(unsigned int wd_base); +static void watchdog_init(void); +static void peripheral_enable(void); +static void muxSetupUART1(void); +static u32 get_cpu_rev(void); + + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +#ifdef CFG_SDRAM_DDR +void +config_sdram_ddr(u32 rev) +{ + /* ball D11, mode 0 */ + __raw_writeb(0x08, 0x48000032); + + /* SDRC_CS0 Configuration */ + if (rev == CPU_2420_2422_ES1) { + __raw_writel(H4_2422_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(H4_2422_SDRC_SHARING, SDRC_SHARING); + } else { + __raw_writel(H4_2420_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + } + + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, SDRC_RFR_CTRL); + __raw_writel(H4_242x_SDRC_ACTIM_CTRLA_0_ES1, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_242x_SDRC_ACTIM_CTRLB_0_ES1, SDRC_ACTIM_CTRLB_0); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + + /* + * CS0 SDRC Mode Register + * Burst length = 4 - DDR memory + * Serial mode + * CAS latency = 3 + */ + __raw_writel(0x00000032, SDRC_MR_0); + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + if (rev == CPU_2420_2422_ES1) { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00000002, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00000002, SDRC_DLLB_CTRL); + } else { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00000008, SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00000008, SDRC_DLLB_CTRL); // ES2.x + } + +} +#endif // CFG_SDRAM_DDR + + +#ifdef CFG_SDRAM_COMBO +void +config_sdram_combo(u32 rev) +{ + + u32 dllctrl=0; + + /* ball C12, mode 0 */ + __raw_writeb(0x00, 0x480000a1); + /* ball D11, mode 0 */ + __raw_writeb(0x00, 0x48000032); + /* ball B13, mode 0 - for CKE1 (not needed rkw for combo) */ + __raw_writeb(0x00, 0x480000a3); + + /*configure sdrc 32 bit for COMBO ddr sdram. Issue soft reset */ + __raw_writel(0x00000012, SDRC_SYSCONFIG); + delay(200000); + __raw_writel(0x00000010, SDRC_SYSCONFIG); + + /* SDRCTriState: no Tris */ + /* CS0MuxCfg: 000 (32-bit SDRAM on D31..0) */ + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + + /* CS0 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX9: 1x8Mbx32 */ + __raw_writel(H4_2420_COMBO_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, SDRC_RFR_CTRL); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* CS0 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2422_SDRC_MR_0_DDR, SDRC_MR_0); + + /* CS1 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX9: 1x8Mbx32 */ + __raw_writel(H4_2420_COMBO_MDCFG_0_DDR, SDRC_MCFG_1); + __raw_writel(H4_242X_SDRC_ACTIM_CTRLA_0_100MHz, SDRC_ACTIM_CTRLA_1); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_1); + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, 0x680090d4); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_1); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + + /* CS1 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2422_SDRC_MR_0_DDR, SDRC_MR_1); + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + if (rev == CPU_242X_ES1) + dllctrl = (BIT0|BIT3); + else + dllctrl = BIT0; + + if (rev == CPU_2420_2422_ES1) { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00007306, SDRC_DLLA_CTRL); + __raw_writel(0x00007302, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00007306, SDRC_DLLB_CTRL); /* load ctr value */ + __raw_writel(0x00007302, SDRC_DLLB_CTRL); /* lock and go */ + } + else { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); // ES2.x + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLA_CTRL); // ES2.x + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLB_CTRL); // ES2.x ? + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLB_CTRL); // ES2.x + } +} + +#endif // CFG_SDRAM_COMBO + +#ifdef CFG_SDRAM_SDR +void +config_sdram_sdr(u32 rev) +{ + u32 dllctrl=0; + + /* ball D11, mode 0 */ + __raw_writeb(0x00, 0x48000032); + + __raw_writel(0x00000012, SDRC_SYSCONFIG); + delay(200000); + __raw_writel(0x00000010, SDRC_SYSCONFIG); + + /* Chip-level shared interface management */ + /* SDRCTriState: no Tris */ + /* CS0MuxCfg: 000 (32-bit SDRAM on D31..0) */ + /* CS1MuxCfg: 000 (32-bit SDRAM on D31..0) */ + if (rev == CPU_2420_2422_ES1) + __raw_writel(H4_2422_SDRC_SHARING, SDRC_SHARING); + else + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + /* CS0 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX14: 32Mbx32 */ + __raw_writel(H4_2420_SDRC_MDCFG_0_SDR, SDRC_MCFG_0); /* diff from combo case */ + __raw_writel(H4_2420_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, SDRC_RFR_CTRL); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* CS0 SDRC Mode Register */ + /* Burst length = 2 - SDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2420_SDRC_MR_0_SDR, SDRC_MR_0); /* diff from combo case */ + + /* SDRC DLLA control register */ + /* Enable DLL, Load counter with 115 (middle of range) */ + /* Delay is 90 degrees */ + + if (rev == CPU_242X_ES1) + dllctrl = (BIT0|BIT3); + else + dllctrl = BIT0; + + if (rev == CPU_2420_2422_ES1) { + __raw_writel(0x00007306, SDRC_DLLA_CTRL); + __raw_writel(0x00007302, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00007306, SDRC_DLLB_CTRL); /* load ctr value */ + __raw_writel(0x00007302, SDRC_DLLB_CTRL); /* lock and go */ + } + else { + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); // ES2.x + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLB_CTRL); // ES2.x + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLB_CTRL); // ES2.x + } + +} +#endif // CFG_SDRAM_SDR + +#ifdef CFG_SDRAM_STACKED +void +config_sdram_stacked(u32 rev) +{ + + /* Pin Muxing for SDRC */ + __raw_writeb(0x00, 0x480000a1); /* mux mode 0 (CS1) */ + __raw_writeb(0x00, 0x480000a3); /* mux mode 0 (CKE1) */ + __raw_writeb(0x00, 0x48000032); /* connect sdrc_a12 */ + __raw_writeb(0x00, 0x48000031); /* connect sdrc_a13 */ + + /* configure sdrc 32 bit for COMBO ddr sdram */ + __raw_writel(0x00000010, SDRC_SYSCONFIG); /* no idle ack and RESET enable */ + delay(200000); + __raw_writel(0x00000010, SDRC_SYSCONFIG); /* smart idle mode */ + + /* SDRC_SHARING */ + /* U-boot is writing 0x00000100 though (H4_2420_SDRC_SHARING ) */ + //__raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + __raw_writel(0x00004900, SDRC_SHARING); + + /* SDRC_CS0 Configuration */ + /* None for ES2.1 */ + + /* SDRC_CS1 Configuration */ + __raw_writel(0x00000000, SDRC_CS_CFG); /* Remap CS1 to 0x80000000 */ + + /* Disable power down of CKE */ + __raw_writel(0x00000085, SDRC_POWER); + + __raw_writel(0x01A02019, SDRC_MCFG_1); /* SDRC_MCFG1 */ + __raw_writel(0x0003DD03, SDRC_RFR_CTRL1); /* SDRC_RFR_CTRL1 */ + __raw_writel(0x92DDC485, SDRC_ACTIM_CTRLA_1); /* SDRC_ACTIM_CTRLA0 */ + __raw_writel(0x00000014, SDRC_ACTIM_CTRLB_1); /* SDRC_ACTIM_CTRLB0 */ + + /*Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_1); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1); + + /* CS0 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(0x00000032, SDRC_MR_1); + __raw_writel(0x00000020, SDRC_EMR2_1); /* weak-strength driver */ + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + if (rev == CPU_2420_2422_ES1) { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00007302, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00007302, SDRC_DLLB_CTRL); + } + else { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00003108, SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00003108, SDRC_DLLB_CTRL); // ES2.x + } +} +#endif // CFG_SDRAM_STACKED + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ +int s_init(int skip) +{ + u32 rev; + + rev = get_cpu_rev(); + + watchdog_init(); + muxSetupUART1(); + delay(100); + + /*DPLL out = 2x DPLL --> core clock */ + __raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); + + /*DPLL into low power bypass (others off) */ + __raw_writel(0x00000001, CM_CLKEN_PLL); + + /*MPU core clock = Core /2 = 300 */ + __raw_writel(MPU_DIV, CM_CLKSEL_MPU); + + /*DSPif=200, DSPif=100, IVA=200 */ + __raw_writel(DSP_DIV, CM_CLKSEL_DSP); + + /*GFX clock (L3/2) 50MHz */ + __raw_writel(GFX_DIV, CM_CLKSEL_GFX); + + /*L3=100, L4=100, DisplaySS=50 Vlync=96Mhz,ssi=100, usb=50 */ + __raw_writel(BUS_DIV, CM_CLKSEL1_CORE); + + /*12MHz apll src, 12/(1+1)*50=300 */ + __raw_writel(DPLL_VAL, CM_CLKSEL1_PLL); + + /*Valid the configuration */ + __raw_writel(0x00000001, PRCM_CLKCFG_CTRL); + delay(1000); + + /*Enable DPLL=300, 96MHz APLL locked. */ + __raw_writel(0x0000000F, CM_CLKEN_PLL); + delay(200000); + +#ifdef CFG_SDRAM_DDR + config_sdram_ddr(rev); +#elif defined(CFG_SDRAM_COMBO) + config_sdram_combo(rev); +#elif defined(CFG_SDRAM_SDR) + config_sdram_sdr(rev); +#elif defined(CFG_SDRAM_STACKED) + config_sdram_stacked(rev); +#else +#error SDRAM type not supported +#endif + + delay(20000); + peripheral_enable(); + return(0); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +static void watchdog_init(void) +{ +#define GP (BIT8|BIT9) + + /* There are 4 watch dogs. 1 secure, and 3 general purpose. + * I would expect that the ROM takes care of the secure one, + * but we will try also. Of the 3 GP ones, 1 can reset us + * directly, the other 2 only generate MPU interrupts. + */ + __raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR); + +#if MPU_WD_CLOCKED /* value 0x10 stick on aptix, BIT4 polarity seems oppsite*/ + __raw_writel(WD_UNLOCK1 ,WD3_BASE+WSPR); + wait_for_command_complete(WD3_BASE); + __raw_writel(WD_UNLOCK2 ,WD3_BASE+WSPR); + + __raw_writel(WD_UNLOCK1 ,WD4_BASE+WSPR); + wait_for_command_complete(WD4_BASE); + __raw_writel(WD_UNLOCK2 ,WD4_BASE+WSPR); +#endif + +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base+WWPS); + } while (pending); +} + + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +static void peripheral_enable(void) +{ + unsigned int v, if_clks=0, func_clks=0; + + /* Enable GP2 timer.*/ + if_clks |= BIT4; + func_clks |= BIT4; + v = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* Sys_clk input OMAP2420_GPT2 */ + __raw_writel(v, CM_CLKSEL2_CORE); + __raw_writel(0x1, CM_CLKSEL_WKUP); + +#ifdef CFG_NS16550 + /* Enable UART1 clock */ + func_clks |= BIT21; + if_clks |= BIT21; +#endif + v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */ + __raw_writel(v,CM_ICLKEN1_CORE ); + v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */ + __raw_writel(v, CM_FCLKEN1_CORE); + delay(1000); + +#ifndef KERNEL_UPDATED + { +#define V1 0xffffffff +#define V2 0x00000007 + + __raw_writel(V1, CM_FCLKEN1_CORE); + __raw_writel(V2, CM_FCLKEN2_CORE); + __raw_writel(V1, CM_ICLKEN1_CORE); + __raw_writel(V1, CM_ICLKEN2_CORE); + } +#endif + +} + +/* Pin Muxing registers used for UART1 */ +#define CONTROL_PADCONF_UART1_CTS ((volatile unsigned char *)0x480000C5) +#define CONTROL_PADCONF_UART1_RTS ((volatile unsigned char *)0x480000C6) +#define CONTROL_PADCONF_UART1_TX ((volatile unsigned char *)0x480000C7) +#define CONTROL_PADCONF_UART1_RX ((volatile unsigned char *)0x480000C8) +/**************************************** + * Routine: muxSetupUART1 (ostboot) + * Description: Set up uart1 muxing + *****************************************/ +static void muxSetupUART1(void) +{ + volatile unsigned char *MuxConfigReg; + + /* UART1_CTS pin configuration, PIN = D21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_CTS; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_RTS pin configuration, PIN = H21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RTS; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_TX pin configuration, PIN = L20 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_TX; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + + /* UART1_RX pin configuration, PIN = T21 */ + MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RX; + *MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +int nand_init(void) +{ + u32 rev; + + rev = get_cpu_rev(); + + + /* GPMC pin muxing */ + (*(volatile int*)0x48000070) &= 0x000000FF; + (*(volatile int*)0x48000074) &= 0x00000000; + (*(volatile int*)0x48000078) &= 0x00000000; + (*(volatile int*)0x4800007C) &= 0x00000000; + (*(volatile int*)0x48000080) &= 0xFF000000; + + /* GPMC_IO_DIR */ + (*(volatile int*)0x4800008C) = 0x19000000; + + /* GPMC Configuration */ + (*(volatile int*)0x6800A010) = 0x0000000A; + while (((*(volatile int *)0x6800A014) & 0x00000001) == 0); + + (*(volatile int*)0x6800A050) = 0x00000001; + (*(volatile int*)0x6800A060) = 0x00001800; + (*(volatile int*)0x6800A064) = 0x00141400; + (*(volatile int*)0x6800A068) = 0x00141400; + (*(volatile int*)0x6800A06C) = 0x0F010F01; + (*(volatile int*)0x6800A070) = 0x010C1414; + (*(volatile int*)0x6800A074) = 0x00000A80; + (*(volatile int*)0x6800A078) = 0x00000C44; //base 0x04000000 + + (*(volatile int*)0x6800A0A8) = 0x00000000; + delay(1000); +#ifdef CFG_SDRAM_STACKED + (*(volatile int*)0x6800A090) = 0x00011000; +#else + (*(volatile int*)0x6800A090) = 0x00011200; +#endif + (*(volatile int*)0x6800A094) = 0x001f1f00; + (*(volatile int*)0x6800A098) = 0x00080802; + (*(volatile int*)0x6800A09C) = 0x1C091C09; + (*(volatile int*)0x6800A0A0) = 0x031A1F1F; + (*(volatile int*)0x6800A0A4) = 0x000003C2; + (*(volatile int*)0x6800A0A8) = 0x00000F48; + + if (rev != CPU_2420_2422_ES1) + (*(volatile int*)0x6800A040) = 0x1FF0; // es2.x + + if (nand_chip()){ + printf("Unsupported Chip!\n"); + return 1; + } + return 0; +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 v; + v = __raw_readl(TAP_IDCODE_REG); + v = v >> 28; + return(v+1); /* currently 2422 and 2420 match up */ +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{} + + +
diff --git a/x-loader/board/omap2420h4/platform.S b/x-loader/board/omap2420h4/platform.S new file mode 100644 index 0000000..5cc37e5 --- /dev/null +++ b/x-loader/board/omap2420h4/platform.S
@@ -0,0 +1,218 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/omap2420.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#ifdef CONFIG_PARTIAL_SRAM + +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = PRCM_CLKCFG_CTRL - addr of valid reg + * R1 = CM_CLKEN_PLL - addr dpll ctlr reg + * R2 = dpll value + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + ******************************************************************************/ +.global go_to_speed + go_to_speed: + sub sp, sp, #0x4 /* get some stack space */ + str r4, [sp] /* save r4's value */ + + /* move into fast relock bypass */ + ldr r8, pll_ctl_add + mov r4, #0x2 + str r4, [r8] + ldr r4, pll_stat +block: + ldr r8, [r4] /* wait for bypass to take effect */ + and r8, r8, #0x3 + cmp r8, #0x1 + bne block + + /* set new dpll dividers _after_ in bypass */ + ldr r4, pll_div_add + ldr r8, pll_div_val + str r8, [r4] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r4, cfg3_0_addr + ldr r8, cfg3_0_val + str r8, [r4] + ldr r4, cfg4_0_addr + ldr r8, cfg4_0_val + str r8, [r4] + ldr r4, cfg1_0_addr + ldr r8, [r4] + orr r8, r8, #0x3 /* up gpmc divider */ + str r8, [r4] + + /* setup to 2x loop though code. The first loop pre-loads the + * icache, the 2nd commits the prcm config, and locks the dpll + */ + mov r4, #0x1000 /* spin spin spin */ + mov r8, #0x4 /* first pass condition & set registers */ + cmp r8, #0x4 +2: + ldrne r8, [r3] /* DPLL lock check */ + and r8, r8, #0x7 + cmp r8, #0x2 + beq 4f +3: + subeq r8, r8, #0x1 + streq r8, [r0] /* commit dividers (2nd time) */ + nop +lloop1: + sub r4, r4, #0x1 /* Loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop1 + mov r4, #0x40000 + cmp r8, #0x1 + nop + streq r2, [r1] /* lock dpll (2nd time) */ + nop +lloop2: + sub r4, r4, #0x1 /* loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop2 + mov r4, #0x40000 + cmp r8, #0x1 + nop + ldreq r8, [r3] /* get lock condition for dpll */ + cmp r8, #0x4 /* first time though? */ + bne 2b + moveq r8, #0x2 /* set to dpll check condition. */ + beq 3b /* if condition not true branch */ +4: + ldr r4, [sp] + add sp, sp, #0x4 /* return stack space */ + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +cfg3_0_addr: + .word GPMC_CONFIG3_0 +cfg3_0_val: + .word SMNAND_GPMC_CONFIG3 +cfg4_0_addr: + .word GPMC_CONFIG4_0 +cfg4_0_val: + .word SMNAND_GPMC_CONFIG4 +cfg1_0_addr: + .word GPMC_CONFIG1_0 +pll_ctl_add: + .word CM_CLKEN_PLL +pll_stat: + .word CM_IDLEST_CKGEN +pll_div_add: + .word CM_CLKSEL1_PLL +pll_div_val: + .word DPLL_VAL /* DPLL setting (300MHz default) */ +#endif + +.globl platformsetup +platformsetup: + mov r3, r0 /* save skip information */ +#ifdef CONFIG_APTIX + ldr r0, REG_SDRC_MCFG_0 + ldr r1, VAL_SDRC_MCFG_0 + str r1, [r0] + ldr r0, REG_SDRC_MR_0 + ldr r1, VAL_SDRC_MR_0 + str r1, [r0] + /* a ddr needs emr1 set here */ + ldr r0, REG_SDRC_SHARING + ldr r1, VAL_SDRC_SHARING + str r1, [r0] + ldr r0, REG_SDRC_RFR_CTRL_0 + ldr r1, VAL_SDRC_RFR_CTRL_0 + str r1, [r0] + + /* little delay after init */ + mov r2, #0x1800 +1: + subs r2, r2, #0x1 + bne 1b +#endif +#ifdef CONFIG_PARTIAL_SRAM + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + mov r0, r3 /* pass skip info to s_init */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ +#endif + + /* map interrupt controller */ + ldr r0, VAL_INTH_SETUP + mcr p15, 0, r0, c15, c2, 4 + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +VAL_INTH_SETUP: + .word PERIFERAL_PORT_BASE +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + + + + +
diff --git a/x-loader/board/omap2420h4/x-load.lds b/x-loader/board/omap2420h4/x-load.lds new file mode 100644 index 0000000..f664ca7 --- /dev/null +++ b/x-loader/board/omap2420h4/x-load.lds
@@ -0,0 +1,54 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004 Texas Instruments + * + * (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 : + { + cpu/arm1136/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap2430sdp/Makefile b/x-loader/board/omap2430sdp/Makefile new file mode 100644 index 0000000..56c941d --- /dev/null +++ b/x-loader/board/omap2430sdp/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap2430sdp.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap2430sdp/config.mk b/x-loader/board/omap2430sdp/config.mk new file mode 100644 index 0000000..7bc5078 --- /dev/null +++ b/x-loader/board/omap2430sdp/config.mk
@@ -0,0 +1,28 @@ +# +# (C) Copyright 2004 +# Texas Instruments, <www.ti.com> +# +# TI H4 board with OMAP2420 (ARM1136) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0 +# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) ES2 will be configurable +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# 2430 h4 has same mem configuration as h4. + +# For use with external or internal boots. +# CONFIG_PARTIAL_SRAM must be defined to use this. +TEXT_BASE = 0x80e80000 + +# Used with full SRAM boot. +# This is either with a GP system or a signed boot image. +# easiest, and safest way to go if you can. +# Comment out //CONFIG_PARTIAL_SRAM for this one. +# +#TEXT_BASE = 0x40280000 +
diff --git a/x-loader/board/omap2430sdp/omap2430sdp.c b/x-loader/board/omap2430sdp/omap2430sdp.c new file mode 100644 index 0000000..f2a7b42 --- /dev/null +++ b/x-loader/board/omap2430sdp/omap2430sdp.c
@@ -0,0 +1,746 @@ +/* + * (C) Copyright 2004-2005 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 <asm/arch/omap2430.h> +#include <asm/arch/bits.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> + +static void wait_for_command_complete(unsigned int wd_base); +static void watchdog_init(void); +static void peripheral_enable(void); +static void muxSetupAll(void); +static u32 get_cpu_rev(void); +static u32 get_device_type(void); +static void prcm_init(void); + + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 v; + v = __raw_readl(TAP_IDCODE_REG); + v = v >> 28; + return(v+1); /* currently 2422 and 2420 match up */ +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); + return(mode >>= 8); +} + +/************************************************************* + * Helper function to wait for the status of a register + *************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return(1); + if (i==bound) + return(0); + } while (1); +} + +/************************************************************* + * Support for multiple type of memory types + *************************************************************/ +#ifdef CFG_SDRAM_DDR +void +config_sdram_ddr(u32 rev) +{ + /* ball D11, mode 0 */ + __raw_writeb(0x08, 0x48000032); + + /* SDRC_CS0 Configuration */ + __raw_writel(H4_2420_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, SDRC_RFR_CTRL); + __raw_writel(H4_242x_SDRC_ACTIM_CTRLA_0_ES1, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_242x_SDRC_ACTIM_CTRLB_0_ES1, SDRC_ACTIM_CTRLB_0); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + + /* + * CS0 SDRC Mode Register + * Burst length = 4 - DDR memory + * Serial mode + * CAS latency = 3 + */ + __raw_writel(0x00000032, SDRC_MR_0); + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00000008, SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00000008, SDRC_DLLB_CTRL); // ES2.x + +} +#endif // CFG_SDRAM_DDR + +#ifdef CFG_SDRAM_COMBO +void +config_sdram_combo(u32 rev) +{ + + u32 dllctrl=0; + + /* ball C12, mode 0 */ + __raw_writeb(0x00, 0x480000a1); + /* ball D11, mode 0 */ + __raw_writeb(0x00, 0x48000032); + /* ball B13, mode 0 - for CKE1 (not needed rkw for combo) */ + __raw_writeb(0x00, 0x480000a3); + + /*configure sdrc 32 bit for COMBO ddr sdram. Issue soft reset */ + __raw_writel(0x00000012, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); /* wait till reset done set */ + __raw_writel(0x00000000, SDRC_SYSCONFIG); + + /* SDRCTriState: no Tris */ + /* CS0MuxCfg: 000 (32-bit SDRAM on D31..0) */ + if (rev == CPU_2420_2422_ES1) + __raw_writel(H4_2422_SDRC_SHARING, SDRC_SHARING); + else + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + + /* CS0 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX9: 1x8Mbx32 */ + __raw_writel(H4_2420_COMBO_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + + /* This is reqd only for ES1 */ + if (rev == CPU_242X_ES1) + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, SDRC_RFR_CTRL); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* CS0 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2422_SDRC_MR_0_DDR, SDRC_MR_0); + + /* CS1 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX9: 1x8Mbx32 */ + __raw_writel(H4_2420_COMBO_MDCFG_0_DDR, SDRC_MCFG_1); + __raw_writel(H4_242X_SDRC_ACTIM_CTRLA_0_100MHz, SDRC_ACTIM_CTRLA_1); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_1); + /* This is reqd only for ES1 */ + if (rev == CPU_242X_ES1) + __raw_writel(H4_242x_SDRC_RFR_CTRL_ES1, 0x680090d4); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, 0x680090d8); + __raw_writel(CMD_PRECHARGE, 0x680090d8); + __raw_writel(CMD_AUTOREFRESH, 0x680090d8); + __raw_writel(CMD_AUTOREFRESH, 0x680090d8); + + /* CS1 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2422_SDRC_MR_0_DDR, 0x680090b4); + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + + if (rev == CPU_242X_ES1) + dllctrl = (BIT0|BIT3); + else + dllctrl = BIT0; + + if (rev == CPU_2420_2422_ES1) { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00007306, SDRC_DLLA_CTRL); + __raw_writel(0x00007302, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00007306, SDRC_DLLB_CTRL); /* load ctr value */ + __raw_writel(0x00007302, SDRC_DLLB_CTRL); /* lock and go */ + } + else { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); // ES2.x + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLA_CTRL); // ES2.x + // __raw_writel(0x00009808, SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(H4_2420_SDRC_DLLAB_CTRL, SDRC_DLLB_CTRL); // ES2.x ? + __raw_writel(H4_2420_SDRC_DLLAB_CTRL & ~(LOADDLL|dllctrl), SDRC_DLLB_CTRL); // ES2.x + //__raw_writel(0x00009808, SDRC_DLLB_CTRL); // ES2.x + } +} + +#endif // CFG_SDRAM_COMBO + +#ifdef CFG_2430SDRAM_DDR +void +config_2430sdram_ddr(u32 rev) +{ + u32 dllstat, dllctrl; + + __raw_writel(0x00000012, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); /* wait till reset done set */ + __raw_writel(0x00000000, SDRC_SYSCONFIG); + + /* Chip-level shared interface management */ + /* SDRCTriState: no Tris */ + /* CS0MuxCfg: 000 (32-bit SDRAM on D31..0) */ + /* CS1MuxCfg: 000 (32-bit SDRAM on D31..0) */ + __raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + /* CS0 SDRC Memory Configuration, */ + /* DDR-SDRAM, External SDRAM is x32bit, */ + /* Configure to MUX14: 32Mbx32 */ + __raw_writel(SDP_2430_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + __raw_writel(SDP_2430_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(H4_2420_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + + __raw_writel(H4_2420_SDRC_RFR_CTRL, SDRC_RFR_CTRL); + + /* Manual Command sequence */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* CS0 SDRC Mode Register */ + /* Burst length = 2 - SDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(H4_2420_SDRC_MR_0_DDR, SDRC_MR_0); + + /* Set up SDRC DLL values for 2430 DDR */ + dllctrl = (SDP_2430_SDRC_DLLAB_CTRL & ~BIT2); /* set target ctrl val */ + __raw_writel(dllctrl, SDRC_DLLA_CTRL); /* set lock mode */ + __raw_writel(dllctrl, SDRC_DLLB_CTRL); /* set lock mode */ + delay(0x1000); /* time to track to center */ + dllstat = __raw_readl(SDRC_DLLA_STATUS) & 0xFF00; /* get status */ + dllctrl = (dllctrl & 0x00FF) | dllstat | BIT2; /* build unlock value */ + __raw_writel(dllctrl, SDRC_DLLA_CTRL); /* set unlock mode */ + __raw_writel(dllctrl, SDRC_DLLB_CTRL); /* set unlock mode */ +} +#endif // CFG_2430SDRAM_DDR + +#ifdef CFG_SDRAM_STACKED +void +config_sdram_stacked(u32 rev) +{ + + /* Pin Muxing for SDRC */ + __raw_writeb(0x00, 0x480000a1); /* mux mode 0 (CS1) */ + __raw_writeb(0x00, 0x480000a3); /* mux mode 0 (CKE1) */ + __raw_writeb(0x00, 0x48000032); /* connect sdrc_a12 */ + __raw_writeb(0x00, 0x48000031); /* connect sdrc_a13 */ + + /* configure sdrc 32 bit for COMBO ddr sdram */ + __raw_writel(0x00000010, SDRC_SYSCONFIG); /* no idle ack and RESET enable */ + delay(200000); + __raw_writel(0x00000010, SDRC_SYSCONFIG); /* smart idle mode */ + + /* SDRC_SHARING */ + /* U-boot is writing 0x00000100 though (H4_2420_SDRC_SHARING ) */ + //__raw_writel(H4_2420_SDRC_SHARING, SDRC_SHARING); + + __raw_writel(0x00004900, SDRC_SHARING); + + /* SDRC_CS0 Configuration */ + /* None for ES2.1 */ + + /* SDRC_CS1 Configuration */ + __raw_writel(0x00000000, SDRC_CS_CFG); /* Remap CS1 to 0x80000000 */ + + /* Disable power down of CKE */ + __raw_writel(0x00000085, SDRC_POWER); + + __raw_writel(0x01A02019, SDRC_MCFG_1); /* SDRC_MCFG1 */ + __raw_writel(0x0003DD03, SDRC_RFR_CTRL1); /* SDRC_RFR_CTRL1 */ + __raw_writel(0x92DDC485, SDRC_ACTIM_CTRLA_1); /* SDRC_ACTIM_CTRLA0 */ + __raw_writel(0x00000014, SDRC_ACTIM_CTRLB_1); /* SDRC_ACTIM_CTRLB0 */ + + /*Manual Command sequence */ + __raw_writel(0x00000000, 0x680090D8); + __raw_writel(0x00000001, 0x680090D8); + __raw_writel(0x00000002, 0x680090D8); + __raw_writel(0x00000002, 0x680090D8); + + /* CS0 SDRC Mode Register */ + /* Burst length = 4 - DDR memory */ + /* Serial mode */ + /* CAS latency = 3 */ + __raw_writel(0x00000032, 0x680090B4); + __raw_writel(0x00000020, 0x680090BC); /* weak-strength driver */ + + /* SDRC DLLA control register */ + /* Delay is 90 degrees */ + if (rev == CPU_2420_2422_ES1) { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00007302, SDRC_DLLA_CTRL); + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00007302, SDRC_DLLB_CTRL); + } + else { + /* Enable DLL, Load counter with 115 (middle of range) */ + __raw_writel(0x00003108, SDRC_DLLA_CTRL); // ES2.x + /* Enable DLL, Load counter with 128 (middle of range) */ + __raw_writel(0x00003108, SDRC_DLLB_CTRL); // ES2.x + } +} +#endif // CFG_SDRAM_STACKED + +/************************************************************* + * get_sys_clk_speed - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *************************************************************/ +u32 get_osc_clk_speed(u32 *shift) +{ +#define GPT_EN ((0<<2)|BIT1|BIT0) /* enable sys_clk NO-prescale /1 */ +#define GPT_CTR OMAP24XX_GPT2+TCRR /* read counter address */ + u32 start, cstart, cend, cdiff, val; + unsigned int v, if_clks=0, func_clks=0 ; + + + + if(__raw_readl(PRCM_CLKSRC_CTRL) & BIT7){ /* if currently /2 */ + *shift = 1; + }else{ + *shift = 0; + } + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* mask for sys_clk use */ + __raw_writel(val, CM_CLKSEL2_CORE); /* timer2 source to sys_clk */ + __raw_writel(BIT4, CM_ICLKEN1_CORE); /* timer2 interface clock on */ + __raw_writel(BIT4, CM_FCLKEN1_CORE); /* timer2 function clock on */ + /* Enable GP2 timer.*/ + if_clks |= BIT4; + func_clks |= BIT4; + v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */ + __raw_writel(v,CM_ICLKEN1_CORE ); + v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */ + __raw_writel(v, CM_FCLKEN1_CORE); + __raw_writel(0, OMAP24XX_GPT2+TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP24XX_GPT2+TCLR); /* enable clock */ + /* enable 32kHz source */ /* enabled out of reset */ + /* determine sys_clk via gauging */ + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles*/ + while(__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(GPT_CTR); /* get start sys_clk count */ + while(__raw_readl(S32K_CR) < (start+20)); /* wait for 40 cycles */ + cend = __raw_readl(GPT_CTR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + /* based on number of ticks assign speed */ + if(cdiff > (19000 >> *shift)) + return(S38_4M); + else if (cdiff > (15200 >> *shift)) + return(S26M); + else if (cdiff > (13000 >> *shift)) + return(S24M); + else if (cdiff > (9000 >> *shift)) + return(S19_2M); + else if (cdiff > (7600 >> *shift)) + return(S13M); + else + return(S12M); +} + +/********************************************************************************* + * prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default). + * -- called from SRAM + *********************************************************************************/ +void +prcm_init() +{ + u32 div, speed, val, div_by_2; + + val = __raw_readl(PRCM_CLKSRC_CTRL) & ~(BIT1 | BIT0); +#if defined(OMAP2430_SQUARE_CLOCK_INPUT) + __raw_writel(val, PRCM_CLKSRC_CTRL); +#else + __raw_writel((val | BIT0), PRCM_CLKSRC_CTRL); +#endif + speed = get_osc_clk_speed(&div_by_2); + if((speed > S19_2M) && (!div_by_2)){ /* if fast && /2 off, enable it */ + val = ~(BIT6|BIT7) & __raw_readl(PRCM_CLKSRC_CTRL); + val |= (0x2 << 6); /* divide by 2 if (24,26,38.4) -> (12/13/19.2) */ + __raw_writel(val, PRCM_CLKSRC_CTRL); + } + + __raw_writel(0, CM_FCLKEN1_CORE); /* stop all clocks to reduce ringing */ + __raw_writel(0, CM_FCLKEN2_CORE); /* may not be necessary */ + __raw_writel(0, CM_ICLKEN1_CORE); + __raw_writel(0, CM_ICLKEN2_CORE); + + /*DPLL into low power bypass (others off) */ + __raw_writel(0x00000001, CM_CLKEN_PLL); + + __raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); /* set DPLL out */ + __raw_writel(MPU_DIV, CM_CLKSEL_MPU); /* set MPU divider */ + __raw_writel(DSP_DIV, CM_CLKSEL_DSP); /* set dsp and iva dividers */ + __raw_writel(GFX_DIV, CM_CLKSEL_GFX); /* set gfx dividers */ + __raw_writel(MDM_DIV, CM_CLKSEL_MDM); /* set mdm dividers */ + + div = BUS_DIV; + __raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/SSi dividers */ + delay(1000); + + /*13MHz apll src, PRCM 'x' DPLL rate */ + __raw_writel(DPLL_VAL, CM_CLKSEL1_PLL); + + /*Valid the configuration */ + __raw_writel(0x00000001, PRCM_CLKCFG_CTRL); + delay(1000); + + /* set up APLLS_CLKIN per crystal */ + if (speed > S19_2M) + speed >>= 1; /* if fast shift to /2 range */ + val = (0x2 << 23); /* default to 13Mhz for 2430c */ + if (speed == S12M) + val = (0x3 << 23); + else if (speed == S19_2M) + val = (0x0 << 23); + val |= (~(BIT23|BIT24|BIT25) & __raw_readl(CM_CLKSEL1_PLL)); + __raw_writel(val, CM_CLKSEL1_PLL); + + __raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL); /* enable apll */ + wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY);/* wait for apll lock */ + + delay(200000); +} + +void SEC_generic(void) +{ +/* Permission values for registers -Full fledged permissions to all */ +#define UNLOCK_1 0xFFFFFFFF +#define UNLOCK_2 0x00000000 +#define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, PM_RT_APE_BASE_ADDR_ARM + 0x68); /* REQ_INFO_PERMISSION_1 L*/ + __raw_writel(UNLOCK_1, PM_RT_APE_BASE_ADDR_ARM + 0x50); /* READ_PERMISSION_0 L*/ + __raw_writel(UNLOCK_1, PM_RT_APE_BASE_ADDR_ARM + 0x58); /* WRITE_PERMISSION_0 L*/ + __raw_writel(UNLOCK_2, PM_RT_APE_BASE_ADDR_ARM + 0x60); /* ADDR_MATCH_1 L*/ + + + __raw_writel(UNLOCK_3, PM_GPMC_BASE_ADDR_ARM + 0x48); /* REQ_INFO_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_GPMC_BASE_ADDR_ARM + 0x50); /* READ_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_GPMC_BASE_ADDR_ARM + 0x58); /* WRITE_PERMISSION_0 L*/ + + __raw_writel(UNLOCK_3, PM_OCM_RAM_BASE_ADDR_ARM + 0x48); /* REQ_INFO_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_OCM_RAM_BASE_ADDR_ARM + 0x50); /* READ_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_OCM_RAM_BASE_ADDR_ARM + 0x58); /* WRITE_PERMISSION_0 L*/ + __raw_writel(UNLOCK_2, PM_OCM_RAM_BASE_ADDR_ARM + 0x80); /* ADDR_MATCH_2 L*/ + + /* IVA Changes */ + __raw_writel(UNLOCK_3, PM_IVA2_BASE_ADDR_ARM + 0x48); /* REQ_INFO_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_IVA2_BASE_ADDR_ARM + 0x50); /* READ_PERMISSION_0 L*/ + __raw_writel(UNLOCK_3, PM_IVA2_BASE_ADDR_ARM + 0x58); /* WRITE_PERMISSION_0 L*/ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for general use. + ***********************************************************/ +void try_unlock_sram(void) +{ + int mode; + + /* if GP device unlock device SRAM for general use */ + mode = get_device_type(); + + if ((mode == GP_DEVICE) || (mode == HS_DEVICE) || (mode == EMU_DEVICE) + || (mode == TST_DEVICE)) { + /* Secure or Emulation device - HS/E/T */ + SEC_generic(); + } + return; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +int s_init(int skip) +{ + u32 rev; + + rev = get_cpu_rev(); + + watchdog_init(); + try_unlock_sram(); + muxSetupAll(); + delay(100); + prcm_init(); + +#ifdef CFG_SDRAM_DDR + config_sdram_ddr(rev); +#elif defined(CFG_SDRAM_COMBO) + config_sdram_combo(rev); +#elif defined(CFG_2430SDRAM_DDR) + config_2430sdram_ddr(rev); +#elif defined(CFG_SDRAM_STACKED) + config_sdram_stacked(rev); +#else +#error SDRAM type not supported +#endif + + delay(20000); + peripheral_enable(); + return(0); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +static void watchdog_init(void) +{ +#define GP (BIT8|BIT9) + + /* There are 4 watch dogs. 1 secure, and 3 general purpose. + * I would expect that the ROM takes care of the secure one, + * but we will try also. Of the 3 GP ones, 1 can reset us + * directly, the other 2 only generate MPU interrupts. + */ + __raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR); + +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base+WWPS); + } while (pending); +} + + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +static void peripheral_enable(void) +{ + unsigned int v, if_clks=0, if_clks2 = 0, func_clks=0, func_clks2 = 0; + + /* Enable GP2 timer.*/ + if_clks |= BIT4; + func_clks |= BIT4; + v = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* Sys_clk input OMAP24XX_GPT2 */ + __raw_writel(v, CM_CLKSEL2_CORE); + __raw_writel(0x1, CM_CLKSEL_WKUP); + +#ifdef CFG_NS16550 + /* Enable UART1 clock */ + func_clks |= BIT21; + if_clks |= BIT21; +#endif + v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */ + __raw_writel(v,CM_ICLKEN1_CORE ); + v = __raw_readl(CM_ICLKEN2_CORE) | if_clks2; /* Interface clocks on */ + __raw_writel(v, CM_ICLKEN2_CORE); + v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */ + __raw_writel(v, CM_FCLKEN1_CORE); + v = __raw_readl(CM_FCLKEN2_CORE) | func_clks2; /* Functional Clocks on */ + __raw_writel(v, CM_FCLKEN2_CORE); + delay(1000); + +} + +/* Do pin muxing for all the devices used in X-Loader */ +#define MUX_VAL(OFFSET,VALUE)\ + __raw_writeb(VALUE, OMAP24XX_CTRL_BASE + OFFSET); +static void muxSetupAll(void) +{ + /* UART 1*/ + MUX_VAL(0x00B1, 0x1B) /* uart1_cts- EN, HI, 3, ->gpio_32 */ + MUX_VAL(0x00B2, 0x1B) /* uart1_rts- EN, HI, 3, ->gpio_8 */ + MUX_VAL(0x00B3, 0x1B) /* uart1_tx- EN, HI, 3, ->gpio_9 */ + MUX_VAL(0x00B4, 0x1B) /* uart1_rx- EN, HI, 3, ->gpio_10 */ + MUX_VAL(0x0107, 0x01) /* ssi1_dat_tx- Dis, 1, ->uart1_tx */ + MUX_VAL(0x0108, 0x01) /* ssi1_flag_tx- Dis, 1, ->uart1_rts */ + MUX_VAL(0x0109, 0x01) /* ssi1_rdy_tx- Dis, 1, ->uart1_cts */ + MUX_VAL(0x010A, 0x01) /* ssi1_dat_rx- Dis, 1, ->uart1_rx */ + + /* Mux settings for SDRC */ + MUX_VAL(0x0054, 0x1B) /* sdrc_a14 - EN, HI, 3, ->gpio_0 */ + MUX_VAL(0x0055, 0x1B) /* sdrc_a13 - EN, HI, 3, ->gpio_1 */ + MUX_VAL(0x0056, 0x00) /* sdrc_a12 - Dis, 0 */ + MUX_VAL(0x0046, 0x00) /* sdrc_ncs1 - Dis, 0 */ + MUX_VAL(0x0048, 0x00) /* sdrc_cke1 - Dis, 0 */ + /* GPMC */ + MUX_VAL(0x0030, 0x00) /* gpmc_clk - Dis, 0 */ + MUX_VAL(0x0032, 0x00) /* gpmc_ncs1- Dis, 0 */ + MUX_VAL(0x0033, 0x00) /* gpmc_ncs2- Dis, 0 */ + MUX_VAL(0x0034, 0x03) /* gpmc_ncs3- Dis, 3, ->gpio_24 */ + MUX_VAL(0x0035, 0x03) /* gpmc_ncs4- Dis, 3, ->gpio_25 */ + MUX_VAL(0x0036, 0x00) /* gpmc_ncs5- Dis, 0 */ + MUX_VAL(0x0037, 0x03) /* gpmc_ncs6- Dis, 3, ->gpio_27 */ + MUX_VAL(0x0038, 0x00) /* gpmc_ncs7- Dis, 0 */ + MUX_VAL(0x0040, 0x18) /* gpmc_wait1- Dis, 0 */ + MUX_VAL(0x0041, 0x18) /* gpmc_wait2- Dis, 0 */ + MUX_VAL(0x0042, 0x1B) /* gpmc_wait3- EN, HI, 3, ->gpio_35 */ + MUX_VAL(0x0085, 0x1B) /* gpmc_a10- EN, HI, 3, ->gpio_3 */ +} + +int nand_init(void) +{ + u32 rev; + + /* GPMC Configuration */ + rev = get_cpu_rev(); + + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ +#ifdef CFG_NAND + __raw_writel(0x001, GPMC_CONFIG); /* set nWP, disable limited addr */ +#endif + + /* Set the GPMC Vals . For NAND boot on 2430SDP, NAND is mapped at CS0 + * , NOR at CS1 and MPDB at CS5. And oneNAND boot, we map oneNAND at CS0. + * We configure only GPMC CS0 with required values. Configiring other devices + * at other CS in done in u-boot anyway. So we don't have to bother doing it here. + */ + __raw_writel(0, GPMC_CONFIG7_0); + sdelay(1000); + +#ifdef CFG_NAND + __raw_writel( SMNAND_GPMC_CONFIG1, GPMC_CONFIG1_0); + __raw_writel( SMNAND_GPMC_CONFIG2, GPMC_CONFIG2_0); + __raw_writel( SMNAND_GPMC_CONFIG3, GPMC_CONFIG3_0); + __raw_writel( SMNAND_GPMC_CONFIG4, GPMC_CONFIG4_0); + __raw_writel( SMNAND_GPMC_CONFIG5, GPMC_CONFIG5_0); + __raw_writel( SMNAND_GPMC_CONFIG6, GPMC_CONFIG6_0); + +#else /* CFG_ONENAND */ + __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1_0); + __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2_0); + __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3_0); + __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4_0); + __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5_0); + __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6_0); +#endif + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP24XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((OMAP24XX_GPMC_CS0_MAP>>24) & 0x3F) | + (1<<6) ), GPMC_CONFIG7_0); + sdelay(2000); +#ifdef CFG_NAND + if (nand_chip()){ +#ifdef CFG_PRINTF + printf("Unsupported Chip!\n"); +#endif + return 1; + } +#else + if (onenand_chip()){ +#ifdef CFG_PRINTF + printf("OneNAND Unsupported !\n"); +#endif + return 1; + } + +#endif + return 0; +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{ while (0) {};}
diff --git a/x-loader/board/omap2430sdp/platform.S b/x-loader/board/omap2430sdp/platform.S new file mode 100644 index 0000000..f221d7e --- /dev/null +++ b/x-loader/board/omap2430sdp/platform.S
@@ -0,0 +1,198 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004-2005 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/mem.h> +#include <asm/arch/omap2430.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = PRCM_CLKCFG_CTRL - addr of valid reg + * R1 = CM_CLKEN_PLL - addr dpll ctlr reg + * R2 = dpll value + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + ******************************************************************************/ +.global go_to_speed + go_to_speed: + sub sp, sp, #0x4 /* get some stack space */ + str r4, [sp] /* save r4's value */ + + /* move into fast relock bypass */ + ldr r8, pll_ctl_add + mov r4, #0x2 + str r4, [r8] + ldr r4, pll_stat +block: + ldr r8, [r4] /* wait for bypass to take effect */ + and r8, r8, #0x3 + cmp r8, #0x1 + bne block + + /* set new dpll dividers _after_ in bypass */ + ldr r4, pll_div_add + ldr r8, pll_div_val + str r8, [r4] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r4, flash_cfg3_addr + ldr r8, flash_cfg3_val + str r8, [r4] + ldr r4, flash_cfg4_addr + ldr r8, flash_cfg4_val + str r8, [r4] + ldr r4, flash_cfg1_addr + ldr r8, [r4] + orr r8, r8, #0x3 /* up gpmc divider */ + str r8, [r4] + + /* setup to 2x loop though code. The first loop pre-loads the + * icache, the 2nd commits the prcm config, and locks the dpll + */ + mov r4, #0x1000 /* spin spin spin */ + mov r8, #0x4 /* first pass condition & set registers */ + cmp r8, #0x4 +2: + ldrne r8, [r3] /* DPLL lock check */ + and r8, r8, #0x7 + cmp r8, #0x2 + beq 4f +3: + subeq r8, r8, #0x1 + streq r8, [r0] /* commit dividers (2nd time) */ + nop +lloop1: + sub r4, r4, #0x1 /* Loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop1 + mov r4, #0x40000 + cmp r8, #0x1 + nop + streq r2, [r1] /* lock dpll (2nd time) */ + nop +lloop2: + sub r4, r4, #0x1 /* loop currently necessary else bad jumps */ + nop + cmp r4, #0x0 + bne lloop2 + mov r4, #0x40000 + cmp r8, #0x1 + nop + ldreq r8, [r3] /* get lock condition for dpll */ + cmp r8, #0x4 /* first time though? */ + bne 2b + moveq r8, #0x2 /* set to dpll check condition. */ + beq 3b /* if condition not true branch */ +4: + ldr r4, [sp] + add sp, sp, #0x4 /* return stack space */ + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +#ifdef CFG_ONENAND +flash_cfg3_addr: + .word GPMC_CONFIG3_0 +flash_cfg3_val: + .word ONENAND_GPMC_CONFIG3 +flash_cfg4_addr: + .word GPMC_CONFIG4_0 +flash_cfg4_val: + .word ONENAND_GPMC_CONFIG4 +flash_cfg1_addr: + .word GPMC_CONFIG1_0 +#else +flash_cfg3_addr: + .word GPMC_CONFIG3_0 +flash_cfg3_val: + .word SMNAND_GPMC_CONFIG3 +flash_cfg4_addr: + .word GPMC_CONFIG4_0 +flash_cfg4_val: + .word SMNAND_GPMC_CONFIG4 +flash_cfg1_addr: + .word GPMC_CONFIG1_0 +#endif +pll_ctl_add: + .word CM_CLKEN_PLL +pll_stat: + .word CM_IDLEST_CKGEN +pll_div_add: + .word CM_CLKSEL1_PLL +pll_div_val: + .word DPLL_VAL /* DPLL setting (300MHz default) */ + +.globl platformsetup +platformsetup: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* map interrupt controller */ + ldr r0, VAL_INTH_SETUP + mcr p15, 0, r0, c15, c2, 4 + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +VAL_INTH_SETUP: + .word PERIFERAL_PORT_BASE +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK +
diff --git a/x-loader/board/omap2430sdp/x-load.lds b/x-loader/board/omap2430sdp/x-load.lds new file mode 100644 index 0000000..f12e8f8 --- /dev/null +++ b/x-loader/board/omap2430sdp/x-load.lds
@@ -0,0 +1,54 @@ +/* + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2005 Texas Instruments + * + * (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 : + { + cpu/arm1136/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap3430labrador/Makefile b/x-loader/board/omap3430labrador/Makefile new file mode 100755 index 0000000..d78b8a3 --- /dev/null +++ b/x-loader/board/omap3430labrador/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap3430sdp.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap3430labrador/config.mk b/x-loader/board/omap3430labrador/config.mk new file mode 100755 index 0000000..d6ad6c5 --- /dev/null +++ b/x-loader/board/omap3430labrador/config.mk
@@ -0,0 +1,22 @@ +# +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# SDP3430 board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# SDP3430 has 1 bank of 32MB or 128MB mDDR-SDRAM on CS0 +# SDP3430 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000'0000 (bank1) - re-mappable below CS1 + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40208800
diff --git a/x-loader/board/omap3430labrador/omap3430sdp.c b/x-loader/board/omap3430labrador/omap3430sdp.c new file mode 100755 index 0000000..af9fedb --- /dev/null +++ b/x-loader/board/omap3430labrador/omap3430sdp.c
@@ -0,0 +1,744 @@ +/* + * (C) Copyright 2006-2008 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +/* Used to index into DPLL parameter tables */ +struct dpll_param { + unsigned int m; + unsigned int n; + unsigned int fsel; + unsigned int m2; +}; + +typedef struct dpll_param dpll_param; + +#define MAX_SIL_INDEX 3 + +/* Following functions are exported from lowlevel_init.S */ +extern dpll_param * get_mpu_dpll_param(void); +extern dpll_param * get_iva_dpll_param(void); +extern dpll_param * get_core_dpll_param(void); +extern dpll_param * get_per_dpll_param(void); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); + return(mode >>= 8); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid=0; + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + if((cpuid & 0xf) == 0x0) + return CPU_3430_ES1; + else + return CPU_3430_ES2; + +} + +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +#ifdef CFG_3430SDRAM_DDR +/********************************************************************* + * config_3430sdram_ddr() - Init DDR on 3430SDP dev board. + *********************************************************************/ +void config_3430sdram_ddr(void) +{ + /* reset sdrc controller */ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + __raw_writel(0, SDRC_SYSCONFIG); + + /* setup sdrc to ball mux */ + __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* set mdcfg */ + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + + /* set timing */ + __raw_writel(SDP_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(SDP_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL); + + /* init sequence for mDDR/mSDR using manual commands (DDR is different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* set mr0 */ + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0); + + /* set up dll */ + __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); + delay(0x2000); /* give time to lock */ + +} +#endif // CFG_3430SDRAM_DDR + +/************************************************************* + * get_sys_clk_speed - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *************************************************************/ +u32 get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + /* If SYS_CLK is being divided by 2, remove for now */ + val = (val & (~BIT7)) | BIT6; + __raw_writel(val, PRM_CLKSRC_CTRL); + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/****************************************************************************** + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on + * -- input oscillator clock frequency. + * + *****************************************************************************/ +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) +{ + if(osc_clk == S38_4M) + *sys_clkin_sel= 4; + else if(osc_clk == S26M) + *sys_clkin_sel = 3; + else if(osc_clk == S19_2M) + *sys_clkin_sel = 2; + else if(osc_clk == S13M) + *sys_clkin_sel = 1; + else if(osc_clk == S12M) + *sys_clkin_sel = 0; +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * -- called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + u32 osc_clk=0, sys_clkin_sel; + dpll_param *dpll_param_p; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + osc_clk = get_osc_clk_speed(); + get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + + sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ + + /* If the input clock is greater than 19.2M always divide/2 */ + if(sys_clkin_sel > 2) { + sr32(PRM_CLKSRC_CTRL, 6, 2, 2);/* input clock divider */ + clk_index = sys_clkin_sel/2; + } else { + sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ + clk_index = sys_clkin_sel; + } + + sr32(PRM_CLKSRC_CTRL, 0, 2, 0);/* Bypass mode: T2 inputs a square clock */ + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + if(cpu_is_3410()) + sil_index = 2; + else { + if(get_cpu_rev() == CPU_3430_ES1) + sil_index = 0; + else if(get_cpu_rev() == CPU_3430_ES2) + sil_index = 1; + } + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + /* Getting the base address of Core DPLL param table*/ + dpll_param_p = (dpll_param *)get_core_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* CORE DPLL */ + /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + /* For 3430 ES1.0 Errata 1.50, default value directly doesnt + work. write another value and then default value. */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2 + 1); /* m3x2 */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ + sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb ES1 only */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to PER DPLL param table*/ + dpll_param_p = (dpll_param *)get_per_dpll_param(); + /* Moving it to the right sysclk base */ + dpll_param_p = dpll_param_p + clk_index; + /* PER DPLL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ + sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m); /* set m */ + sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n); /* set n */ + sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel);/* FREQSEL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to MPU DPLL param table*/ + dpll_param_p = (dpll_param *)get_mpu_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* MPU DPLL (unlocked already) */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + + /* Getting the base address to IVA DPLL param table*/ + dpll_param_p = (dpll_param *)get_iva_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* IVA DPLL (set to 12*20=240MHz) */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, dpll_param_p->m2); /* set M2 */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, dpll_param_p->m); /* set M */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, dpll_param_p->n); /* set N */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +void secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +void try_unlock_memory(void) +{ + int mode; + + /* if GP device unlock device SRAM for general use */ + /* secure code breaks for Secure/Emulation device - HS/E/T*/ + mode = get_device_type(); + if (mode == GP_DEVICE) { + secure_unlock(); + } + return; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +void s_init(void) +{ + watchdog_init(); +#ifdef CONFIG_3430_AS_3410 + /* setup the scalability control register for + * 3430 to work in 3410 mode + */ + __raw_writel(0x5ABF,CONTROL_SCALABLE_OMAP_OCP); +#endif + try_unlock_memory(); + set_muxconf_regs(); + delay(100); + prcm_init(); + per_clocks_enable(); + config_3430sdram_ddr(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 +////#ifdef CONFIG_SERIAL3 + sr32(CM_FCLKEN_PER, 11, 1, 0x1); + sr32(CM_ICLKEN_PER, 11, 1, 0x1); +////#else + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +////#endif +#endif + delay(1000); +} + +/* Set MUX for UART, GPMC, SDRC, GPIO */ + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ +#define MUX_DEFAULT()\ + /*SDRC*/\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ + /*GPMC*/\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /*GPMC_A1*/\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /*GPMC_A2*/\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /*GPMC_A3*/\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /*GPMC_A4*/\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /*GPMC_A5*/\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /*GPMC_A6*/\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /*GPMC_A7*/\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /*GPMC_A8*/\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /*GPMC_A9*/\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /*GPMC_A10*/\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /*GPMC_D0*/\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /*GPMC_D1*/\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /*GPMC_D2*/\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /*GPMC_D3*/\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /*GPMC_D4*/\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /*GPMC_D5*/\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /*GPMC_D6*/\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /*GPMC_D7*/\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /*GPMC_D8*/\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /*GPMC_D9*/\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /*GPMC_D10*/\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /*GPMC_D11*/\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /*GPMC_D12*/\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /*GPMC_D13*/\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /*GPMC_D14*/\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /*GPMC_D15*/\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /*GPMC_NCS0*/\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_NCS1*/\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_NCS2*/\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_NCS3*/\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /*GPMC_NCS4 lab*/\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTD | DIS | M0)) /*GPMC_NCS5 lab*/\ + MUX_VAL(CP(GPMC_NCS6), (IEN | PTD | DIS | M1)) /*sys_ndmareq1 lab*/\ + MUX_VAL(CP(GPMC_NCS7), (IEN | PTU | EN | M1)) /*GPMC_IO_DIR lab*/\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /*GPMC_CLK*/\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_NADV_ALE*/\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_NOE*/\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_NWE*/\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /*GPMC_NBE0_CLE*/\ + MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /*GPMC_NBE1 lab*/\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /*GPMC_NWP*/\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ + MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M0)) /*gpmc_nWait lab*/\ + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M0)) /*gpmc_nWait lab*/\ + MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)) /*DSS_DATA18*/\ + MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)) /*DSS_DATA19*/\ + MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)) /*DSS_DATA20*/\ + MUX_VAL(CP(CAM_XCLKB), (IDIS | PTD | DIS | M0)) /*CAM_XCLKB*/\ + MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ + MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ + MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M4)) /*GPIO_158*/\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /*GPIO_8 */\ + MUX_VAL(CP(SYS_CLKOUT1), (IDIS | PTD | DIS | M0)) /*sys_clkout2 lab*/\ + MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTD | DIS | M0)) /*sys_clkout2 lab*/\ + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ + MUX_VAL(CP(ETK_CLK), (IEN | PTD | DIS | M4)) /*GPIO_12*/\ + MUX_VAL(CP(ETK_CTL), (IEN | PTD | DIS | M4)) /*GPIO_13*/\ + MUX_VAL(CP(ETK_D0 ), (IEN | PTD | DIS | M4)) /*GPIO_14*/\ + MUX_VAL(CP(ETK_D1 ), (IEN | PTD | DIS | M4)) /*GPIO_15*/\ + MUX_VAL(CP(ETK_D2 ), (IEN | PTD | DIS | M4)) /*GPIO_16*/\ + MUX_VAL(CP(ETK_D10), (IEN | PTD | DIS | M4)) /*GPIO_24*/\ + MUX_VAL(CP(ETK_D11), (IEN | PTD | DIS | M4)) /*GPIO_25*/\ + MUX_VAL(CP(ETK_D12), (IEN | PTD | DIS | M4)) /*GPIO_26*/\ + MUX_VAL(CP(ETK_D13), (IEN | PTD | DIS | M4)) /*GPIO_27*/\ + MUX_VAL(CP(ETK_D14), (IEN | PTD | DIS | M4)) /*GPIO_28*/\ + MUX_VAL(CP(ETK_D15), (IEN | PTD | DIS | M4)) /*GPIO_29*/\ + MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0)) /*UART3_CTS_RCTX */\ + MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0)) /*UART3_RTS_SD */\ + MUX_VAL(CP(UART3_RX_IRRX ), (IEN | PTD | DIS | M0)) /*UART3_RX_IRRX*/\ + MUX_VAL(CP(UART3_TX_IRTX ), (IDIS | PTD | DIS | M0)) /*UART3_TX_IRTX*/\ + MUX_VAL(CP(sdrc_cke0), (IDIS | PTU | EN | M0)) /*sdrc_cke0 */\ + MUX_VAL(CP(sdrc_cke1), (IDIS | PTD | DIS | M7)) /*sdrc_cke1 not used*/ +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware. Many pins need + * to be moved from protect to primary mode. + *********************************************************/ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} + +/********************************************************** + * Routine: nand+_init + * Description: Set up nand for nand and jffs2 commands + *********************************************************/ +int nand_init(void) +{ + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ +#ifdef CFG_NAND + __raw_writel(0x001, GPMC_CONFIG); /* set nWP, disable limited addr */ +#endif + + /* setup CS0 for Micron NAND, leave other CS's to u-boot */ + __raw_writel(0 , GPMC_CONFIG7 + GPMC_CONFIG_CS0); + delay(1000); + +#ifdef CFG_NAND + __raw_writel( M_NAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + +#else /* CFG_ONENAND */ + __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); +#endif + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((OMAP34XX_GPMC_CS0_MAP>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); + +#ifdef CFG_NAND + if (nand_chip()){ +#ifdef CFG_PRINTF + printf("Unsupported Chip!\n"); +#endif + return 1; + } +#else + if (onenand_chip()){ +#ifdef CFG_PRINTF + printf("OneNAND Unsupported !\n"); +#endif + return 1; + } +#endif + return 0; +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{ while (0) {};}
diff --git a/x-loader/board/omap3430labrador/platform.S b/x-loader/board/omap3430labrador/platform.S new file mode 100755 index 0000000..5869270 --- /dev/null +++ b/x-loader/board/omap3430labrador/platform.S
@@ -0,0 +1,360 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL + +#endif + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE,0x07,0x05,0x01 +/* ES2 */ +.word 0x0FA,0x05,0x07,0x01 +/* 3410 */ +.word 0x085,0x05,0x07,0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D,0x0C,0x03,0x01 +/* ES2 */ +.word 0x1F4,0x0C,0x03,0x01 +/* 3410 */ +.word 0x10A,0x0C,0x03,0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179,0x12,0x04,0x01 +/* ES2 */ +.word 0x271,0x17,0x03,0x01 +/* 3410 */ +.word 0x14C,0x17,0x03,0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D,0x19,0x03,0x01 +/* ES2 */ +.word 0x0FA,0x0C,0x07,0x01 +/* 3410 */ +.word 0x085,0x0C,0x07,0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA,0x32,0x03,0x01 +/* ES2 */ +.word 0x271,0x2F,0x03,0x01 +/* 3410 */ +.word 0x14C,0x2F,0x03,0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D,0x05,0x07,0x01 +/* ES2 */ +.word 0x0B4,0x05,0x07,0x01 +/* 3410 */ +.word 0x085,0x05,0x07,0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA,0x0C,0x03,0x01 +/* ES2 */ +.word 0x168,0x0C,0x03,0x01 +/* 3410 */ +.word 0x10A,0x0C,0x03,0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082,0x09,0x07,0x01 +/* ES2 */ +.word 0x0E1,0x0B,0x06,0x01 +/* 3410 */ +.word 0x14C,0x17,0x03,0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D,0x0C,0x07,0x01 +/* ES2 */ +.word 0x0B4,0x0C,0x07,0x01 +/* 3410 */ +.word 0x085,0x0C,0x07,0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F,0x30,0x03,0x01 +/* ES2 */ +.word 0x0E1,0x17,0x06,0x01 +/* 3410 */ +.word 0x14C,0x2F,0x03,0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +/* Core DPLL targets for L3 at 166 & L133 */ +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word M_12_ES1,M_12_ES1,FSL_12_ES1,M2_12_ES1 +/* ES2 */ +.word M_12,N_12,FSEL_12,M2_12 +/* 3410 */ +.word M_12,N_12,FSEL_12,M2_12 + +/* 13MHz */ +/* ES1 */ +.word M_13_ES1,N_13_ES1,FSL_13_ES1,M2_13_ES1 +/* ES2 */ +.word M_13,N_13,FSEL_13,M2_13 +/* 3410 */ +.word M_13,N_13,FSEL_13,M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word M_19p2_ES1,N_19p2_ES1,FSL_19p2_ES1,M2_19p2_ES1 +/* ES2 */ +.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 +/* 3410 */ +.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 + +/* 26MHz */ +/* ES1 */ +.word M_26_ES1,N_26_ES1,FSL_26_ES1,M2_26_ES1 +/* ES2 */ +.word M_26,N_26,FSEL_26,M2_26 +/* 3410 */ +.word M_26,N_26,FSEL_26,M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word M_38p4_ES1,N_38p4_ES1,FSL_38p4_ES1,M2_38p4_ES1 +/* ES2 */ +.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 +/* 3410 */ +.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8,0x05,0x07,0x09 + +/* 13MHz */ +.word 0x1B0,0x0C,0x03,0x09 + +/* 19.2MHz */ +.word 0xE1,0x09,0x07,0x09 + +/* 26MHz */ +.word 0xD8,0x0C,0x07,0x09 + +/* 38.4MHz */ +.word 0xE1,0x13,0x07,0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr +
diff --git a/x-loader/board/omap3430labrador/x-load.lds b/x-loader/board/omap3430labrador/x-load.lds new file mode 100755 index 0000000..9402f74 --- /dev/null +++ b/x-loader/board/omap3430labrador/x-load.lds
@@ -0,0 +1,54 @@ +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap3430sdp/Makefile b/x-loader/board/omap3430sdp/Makefile new file mode 100644 index 0000000..5d5ce17 --- /dev/null +++ b/x-loader/board/omap3430sdp/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap3430sdp.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap3430sdp/config.mk b/x-loader/board/omap3430sdp/config.mk new file mode 100644 index 0000000..d6ad6c5 --- /dev/null +++ b/x-loader/board/omap3430sdp/config.mk
@@ -0,0 +1,22 @@ +# +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# SDP3430 board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# SDP3430 has 1 bank of 32MB or 128MB mDDR-SDRAM on CS0 +# SDP3430 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000'0000 (bank1) - re-mappable below CS1 + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40208800
diff --git a/x-loader/board/omap3430sdp/omap3430sdp.c b/x-loader/board/omap3430sdp/omap3430sdp.c new file mode 100644 index 0000000..b609aaf --- /dev/null +++ b/x-loader/board/omap3430sdp/omap3430sdp.c
@@ -0,0 +1,774 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 <command.h> +#include <part.h> +#include <fat.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +/* Used to index into DPLL parameter tables */ +struct dpll_param { + unsigned int m; + unsigned int n; + unsigned int fsel; + unsigned int m2; +}; + +typedef struct dpll_param dpll_param; + +#define MAX_SIL_INDEX 3 + +/* Following functions are exported from lowlevel_init.S */ +extern dpll_param * get_mpu_dpll_param(); +extern dpll_param * get_iva_dpll_param(); +extern dpll_param * get_core_dpll_param(); +extern dpll_param * get_per_dpll_param(); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); + return(mode >>= 8); +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid=0; + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + if((cpuid & 0xf) == 0x0) + return CPU_3430_ES1; + else + return CPU_3430_ES2; + +} + +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +#ifdef CFG_3430SDRAM_DDR +/********************************************************************* + * config_3430sdram_ddr() - Init DDR on 3430SDP dev board. + *********************************************************************/ +void config_3430sdram_ddr(void) +{ + /* reset sdrc controller */ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + __raw_writel(0, SDRC_SYSCONFIG); + + /* setup sdrc to ball mux */ + __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* set mdcfg */ + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + + /* set timing */ + __raw_writel(SDP_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(SDP_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL); + + /* init sequence for mDDR/mSDR using manual commands (DDR is different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* set mr0 */ + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0); + + /* set up dll */ + __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); + delay(0x2000); /* give time to lock */ + +} +#endif // CFG_3430SDRAM_DDR + +/************************************************************* + * get_sys_clk_speed - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *************************************************************/ +u32 get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + /* If SYS_CLK is being divided by 2, remove for now */ + val = (val & (~BIT7)) | BIT6; + __raw_writel(val, PRM_CLKSRC_CTRL); + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/****************************************************************************** + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on + * -- input oscillator clock frequency. + * + *****************************************************************************/ +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) +{ + if(osc_clk == S38_4M) + *sys_clkin_sel= 4; + else if(osc_clk == S26M) + *sys_clkin_sel = 3; + else if(osc_clk == S19_2M) + *sys_clkin_sel = 2; + else if(osc_clk == S13M) + *sys_clkin_sel = 1; + else if(osc_clk == S12M) + *sys_clkin_sel = 0; +} + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * -- called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + u32 osc_clk=0, sys_clkin_sel; + dpll_param *dpll_param_p; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + osc_clk = get_osc_clk_speed(); + get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + + sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ + + /* If the input clock is greater than 19.2M always divide/2 */ + if(sys_clkin_sel > 2) { + sr32(PRM_CLKSRC_CTRL, 6, 2, 2);/* input clock divider */ + clk_index = sys_clkin_sel/2; + } else { + sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ + clk_index = sys_clkin_sel; + } + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + if(cpu_is_3410()) + sil_index = 2; + else { + if(get_cpu_rev() == CPU_3430_ES1) + sil_index = 0; + else if(get_cpu_rev() == CPU_3430_ES2) + sil_index = 1; + } + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + /* Getting the base address of Core DPLL param table*/ + dpll_param_p = (dpll_param *)get_core_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* CORE DPLL */ + /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */ + sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */ + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to PER DPLL param table*/ + dpll_param_p = (dpll_param *)get_per_dpll_param(); + /* Moving it to the right sysclk base */ + dpll_param_p = dpll_param_p + clk_index; + /* PER DPLL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2); /* set M2 */ + sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m); /* set m */ + sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n); /* set n */ + sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel);/* FREQSEL */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); + + /* Getting the base address to MPU DPLL param table*/ + dpll_param_p = (dpll_param *)get_mpu_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* MPU DPLL (unlocked already) */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2); /* Set M2 */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m); /* Set M */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n); /* Set N */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + + /* Getting the base address to IVA DPLL param table*/ + dpll_param_p = (dpll_param *)get_iva_dpll_param(); + /* Moving it to the right sysclk and ES rev base */ + dpll_param_p = dpll_param_p + MAX_SIL_INDEX*clk_index + sil_index; + /* IVA DPLL (set to 12*20=240MHz) */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, dpll_param_p->m2); /* set M2 */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, dpll_param_p->m); /* set M */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, dpll_param_p->n); /* set N */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, dpll_param_p->fsel); /* FREQSEL */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); /* lock mode */ + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +void secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +void try_unlock_memory(void) +{ + int mode; + + /* if GP device unlock device SRAM for general use */ + /* secure code breaks for Secure/Emulation device - HS/E/T*/ + mode = get_device_type(); + if (mode == GP_DEVICE) { + secure_unlock(); + } + return; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +void s_init(void) +{ + watchdog_init(); +#ifdef CONFIG_3430_AS_3410 + /* setup the scalability control register for + * 3430 to work in 3410 mode + */ + __raw_writel(0x5ABF,CONTROL_SCALABLE_OMAP_OCP); +#endif + try_unlock_memory(); + set_muxconf_regs(); + delay(100); + prcm_init(); + per_clocks_enable(); + config_3430sdram_ddr(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + delay(1000); +} + +/* Set MUX for UART, GPMC, SDRC, GPIO */ + +#define MUX_VAL(OFFSET,VALUE)\ + __raw_writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET)); + +#define CP(x) (CONTROL_PADCONF_##x) +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ +#define MUX_DEFAULT()\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /*GPMC_A1*/\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /*GPMC_A2*/\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /*GPMC_A3*/\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /*GPMC_A4*/\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /*GPMC_A5*/\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /*GPMC_A6*/\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /*GPMC_A7*/\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /*GPMC_A8*/\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /*GPMC_A9*/\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /*GPMC_A10*/\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /*GPMC_D0*/\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /*GPMC_D1*/\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /*GPMC_D2*/\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /*GPMC_D3*/\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /*GPMC_D4*/\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /*GPMC_D5*/\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /*GPMC_D6*/\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /*GPMC_D7*/\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /*GPMC_D8*/\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /*GPMC_D9*/\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /*GPMC_D10*/\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /*GPMC_D11*/\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /*GPMC_D12*/\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /*GPMC_D13*/\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /*GPMC_D14*/\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /*GPMC_D15*/\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /*GPMC_NCS0*/\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_NCS1*/\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_NCS2*/\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_NCS3*/\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /*GPMC_NCS4*/\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /*GPMC_NCS5*/\ + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTU | EN | M0)) /*GPMC_NCS6*/\ + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /*GPMC_NCS7*/\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /*GPMC_CLK*/\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_NADV_ALE*/\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_NOE*/\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_NWE*/\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /*GPMC_NBE0_CLE*/\ + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)) /*GPIO_61*/\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /*GPMC_NWP*/\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ + MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M4)) /*GPIO_64*/\ + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M4)) /*GPIO_65*/\ + MUX_VAL(CP(DSS_DATA18), (IEN | PTD | DIS | M4)) /*GPIO_88*/\ + MUX_VAL(CP(DSS_DATA19), (IEN | PTD | DIS | M4)) /*GPIO_89*/\ + MUX_VAL(CP(DSS_DATA20), (IEN | PTD | DIS | M4)) /*GPIO_90*/\ + MUX_VAL(CP(DSS_DATA21), (IEN | PTD | DIS | M4)) /*GPIO_91*/\ + MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ + MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ + MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M4)) /*GPIO_158*/\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /*GPIO_8 */\ + MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M4)) /*GPIO_186*/\ + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ + MUX_VAL(CP(ETK_CLK), (IEN | PTD | DIS | M4)) /*GPIO_12*/\ + MUX_VAL(CP(ETK_CTL), (IEN | PTD | DIS | M4)) /*GPIO_13*/\ + MUX_VAL(CP(ETK_D0 ), (IEN | PTD | DIS | M4)) /*GPIO_14*/\ + MUX_VAL(CP(ETK_D1 ), (IEN | PTD | DIS | M4)) /*GPIO_15*/\ + MUX_VAL(CP(ETK_D2 ), (IEN | PTD | DIS | M4)) /*GPIO_16*/\ + MUX_VAL(CP(ETK_D10), (IEN | PTD | DIS | M4)) /*GPIO_24*/\ + MUX_VAL(CP(ETK_D11), (IEN | PTD | DIS | M4)) /*GPIO_25*/\ + MUX_VAL(CP(ETK_D12), (IEN | PTD | DIS | M4)) /*GPIO_26*/\ + MUX_VAL(CP(ETK_D13), (IEN | PTD | DIS | M4)) /*GPIO_27*/\ + MUX_VAL(CP(ETK_D14), (IEN | PTD | DIS | M4)) /*GPIO_28*/\ + MUX_VAL(CP(ETK_D15), (IEN | PTD | DIS | M4)) /*GPIO_29*/ + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware. Many pins need + * to be moved from protect to primary mode. + *********************************************************/ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} + +/********************************************************** + * Routine: nand+_init + * Description: Set up nand for nand and jffs2 commands + *********************************************************/ +int nand_init(void) +{ + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ +#ifdef CFG_NAND + __raw_writel(0x001, GPMC_CONFIG); /* set nWP, disable limited addr */ +#endif + + /* Set the GPMC Vals . For NAND boot on 3430SDP, NAND is mapped at CS0 + * , NOR at CS1 and MPDB at CS3. And oneNAND boot, we map oneNAND at CS0. + * We configure only GPMC CS0 with required values. Configiring other devices + * at other CS in done in u-boot anyway. So we don't have to bother doing it here. + */ + __raw_writel(0 , GPMC_CONFIG7 + GPMC_CONFIG_CS0); + delay(1000); + +#ifdef CFG_NAND + __raw_writel( SMNAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( SMNAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( SMNAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( SMNAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( SMNAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( SMNAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + +#else /* CFG_ONENAND */ + __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); +#endif + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((OMAP34XX_GPMC_CS0_MAP>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); +#if defined(CFG_NAND) + if (nand_chip()){ +#ifdef CFG_PRINTF + printf("Unsupported Chip!\n"); +#endif + return 1; + } +#elif defined(CFG_ONENAND) + if (onenand_chip()){ +#ifdef CFG_PRINTF + printf("OneNAND Unsupported !\n"); +#endif + return 1; + } +#endif + return 0; +} + +#ifdef CFG_CMD_FAT +typedef int (mmc_boot_addr) (void); +int mmc_boot(void) +{ + long size, i; + unsigned long offset = CFG_LOADADDR; + unsigned long count; + char buf[12]; + block_dev_desc_t *dev_desc = NULL; + int dev = 0; + int part = 1; + char *ep; + unsigned char ret = 0; + + printf("Starting X-loader on MMC \n"); + + ret = mmc_init(1); + if(ret == 0){ + printf("\n MMC init failed \n"); + return 0; + } + + dev_desc = mmc_get_dev(0); + fat_register_device(dev_desc, 1); + size = file_fat_read("u-boot.bin", (unsigned char *)offset, 0); + if (size == -1) { + return 0; + } + printf("\n%ld Bytes Read from MMC \n", size); + + printf("Starting OS Bootloader from MMC...\n"); + + ((mmc_boot_addr *) CFG_LOADADDR) (); + + return 0; +} +#endif + +/* optionally do something like blinking LED */ +void board_hang (void) +{ while (0) {};}
diff --git a/x-loader/board/omap3430sdp/platform.S b/x-loader/board/omap3430sdp/platform.S new file mode 100644 index 0000000..5869270 --- /dev/null +++ b/x-loader/board/omap3430sdp/platform.S
@@ -0,0 +1,360 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL + +#endif + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE,0x07,0x05,0x01 +/* ES2 */ +.word 0x0FA,0x05,0x07,0x01 +/* 3410 */ +.word 0x085,0x05,0x07,0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D,0x0C,0x03,0x01 +/* ES2 */ +.word 0x1F4,0x0C,0x03,0x01 +/* 3410 */ +.word 0x10A,0x0C,0x03,0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179,0x12,0x04,0x01 +/* ES2 */ +.word 0x271,0x17,0x03,0x01 +/* 3410 */ +.word 0x14C,0x17,0x03,0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D,0x19,0x03,0x01 +/* ES2 */ +.word 0x0FA,0x0C,0x07,0x01 +/* 3410 */ +.word 0x085,0x0C,0x07,0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA,0x32,0x03,0x01 +/* ES2 */ +.word 0x271,0x2F,0x03,0x01 +/* 3410 */ +.word 0x14C,0x2F,0x03,0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D,0x05,0x07,0x01 +/* ES2 */ +.word 0x0B4,0x05,0x07,0x01 +/* 3410 */ +.word 0x085,0x05,0x07,0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA,0x0C,0x03,0x01 +/* ES2 */ +.word 0x168,0x0C,0x03,0x01 +/* 3410 */ +.word 0x10A,0x0C,0x03,0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082,0x09,0x07,0x01 +/* ES2 */ +.word 0x0E1,0x0B,0x06,0x01 +/* 3410 */ +.word 0x14C,0x17,0x03,0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D,0x0C,0x07,0x01 +/* ES2 */ +.word 0x0B4,0x0C,0x07,0x01 +/* 3410 */ +.word 0x085,0x0C,0x07,0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F,0x30,0x03,0x01 +/* ES2 */ +.word 0x0E1,0x17,0x06,0x01 +/* 3410 */ +.word 0x14C,0x2F,0x03,0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +/* Core DPLL targets for L3 at 166 & L133 */ +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word M_12_ES1,M_12_ES1,FSL_12_ES1,M2_12_ES1 +/* ES2 */ +.word M_12,N_12,FSEL_12,M2_12 +/* 3410 */ +.word M_12,N_12,FSEL_12,M2_12 + +/* 13MHz */ +/* ES1 */ +.word M_13_ES1,N_13_ES1,FSL_13_ES1,M2_13_ES1 +/* ES2 */ +.word M_13,N_13,FSEL_13,M2_13 +/* 3410 */ +.word M_13,N_13,FSEL_13,M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word M_19p2_ES1,N_19p2_ES1,FSL_19p2_ES1,M2_19p2_ES1 +/* ES2 */ +.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 +/* 3410 */ +.word M_19p2,N_19p2,FSEL_19p2,M2_19p2 + +/* 26MHz */ +/* ES1 */ +.word M_26_ES1,N_26_ES1,FSL_26_ES1,M2_26_ES1 +/* ES2 */ +.word M_26,N_26,FSEL_26,M2_26 +/* 3410 */ +.word M_26,N_26,FSEL_26,M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word M_38p4_ES1,N_38p4_ES1,FSL_38p4_ES1,M2_38p4_ES1 +/* ES2 */ +.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 +/* 3410 */ +.word M_38p4,N_38p4,FSEL_38p4,M2_38p4 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8,0x05,0x07,0x09 + +/* 13MHz */ +.word 0x1B0,0x0C,0x03,0x09 + +/* 19.2MHz */ +.word 0xE1,0x09,0x07,0x09 + +/* 26MHz */ +.word 0xD8,0x0C,0x07,0x09 + +/* 38.4MHz */ +.word 0xE1,0x13,0x07,0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr +
diff --git a/x-loader/board/omap3430sdp/x-load.lds b/x-loader/board/omap3430sdp/x-load.lds new file mode 100644 index 0000000..9402f74 --- /dev/null +++ b/x-loader/board/omap3430sdp/x-load.lds
@@ -0,0 +1,54 @@ +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/board/omap3evm/Makefile b/x-loader/board/omap3evm/Makefile new file mode 100755 index 0000000..e399c5b --- /dev/null +++ b/x-loader/board/omap3evm/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# 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).a + +OBJS := omap3evm.o +SOBJS := platform.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/board/omap3evm/config.mk b/x-loader/board/omap3evm/config.mk new file mode 100755 index 0000000..a45ec22 --- /dev/null +++ b/x-loader/board/omap3evm/config.mk
@@ -0,0 +1,19 @@ +# (C) Copyright 2006 +# Texas Instruments, <www.ti.com> +# +# OMAP3EVM board uses OMAP3430 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments# +# +# OMAP3EVM has 1 bank of 128MB mPOP-SDRAM on CS0 +# Physical Address: +# 8000'0000 (bank0) + +# For use if you want X-Loader to relocate from SRAM to DDR +#TEXT_BASE = 0x80e80000 + +# For XIP in 64K of SRAM or debug (GP device has it all availabe) +# SRAM 40200000-4020FFFF base +# initial stack at 0x4020fffc used in s_init (below xloader). +# The run time stack is (above xloader, 2k below) +# If any globals exist there needs to be room for them also +TEXT_BASE = 0x40200800
diff --git a/x-loader/board/omap3evm/omap3evm.c b/x-loader/board/omap3evm/omap3evm.c new file mode 100755 index 0000000..1d7b994 --- /dev/null +++ b/x-loader/board/omap3evm/omap3evm.c
@@ -0,0 +1,1239 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * Richard Woodruff <r-woodruff2@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 <command.h> +#include <part.h> +#include <fat.h> +#include <asm/arch/cpu.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/clocks.h> +#include <asm/arch/mem.h> + +/* Used to index into DPLL parameter tables */ +struct dpll_param { + unsigned int m; + unsigned int n; + unsigned int fsel; + unsigned int m2; +}; + +struct dpll_per_36x_param { + unsigned int sys_clk; + unsigned int m; + unsigned int n; + unsigned int m2; + unsigned int m3; + unsigned int m4; + unsigned int m5; + unsigned int m6; + unsigned int m2div; +}; + +typedef struct dpll_param dpll_param; + +#define MAX_SIL_INDEX 3 + +/* Following functions are exported from lowlevel_init.S */ +extern dpll_param *get_mpu_dpll_param(void); +extern dpll_param *get_iva_dpll_param(void); +extern dpll_param *get_core_dpll_param(void); +extern dpll_param *get_per_dpll_param(void); + +extern dpll_param *get_36x_mpu_dpll_param(void); +extern dpll_param *get_36x_iva_dpll_param(void); +extern dpll_param *get_36x_core_dpll_param(void); +extern dpll_param *get_36x_per_dpll_param(void); + +extern int mmc_init(int verbose); +extern block_dev_desc_t *mmc_get_dev(int dev); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay(unsigned long loops) +{ + __asm__ volatile ("1:\n" "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0"(loops)); +} + +void udelay (unsigned long usecs) { + delay(usecs); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ + return 0; +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (DEVICE_MASK); + return(mode >>= 8); +} + +/************************************************ + * get_sysboot_value(void) - return SYS_BOOT[4:0] + ************************************************/ +u32 get_sysboot_value(void) +{ + int mode; + mode = __raw_readl(CONTROL_STATUS) & (SYSBOOT_MASK); + return mode; +} +/************************************************************* + * Routine: get_mem_type(void) - returns the kind of memory connected + * to GPMC that we are trying to boot form. Uses SYS BOOT settings. + *************************************************************/ +u32 get_mem_type(void) +{ + u32 mem_type = get_sysboot_value(); + switch (mem_type){ + case 0: + case 2: + case 4: + case 16: + case 22: return GPMC_ONENAND; + + case 1: + case 12: + case 15: + case 21: + case 27: return GPMC_NAND; + + case 3: + case 6: return MMC_ONENAND; + + case 8: + case 11: + case 14: + case 20: + case 26: return GPMC_MDOC; + + case 17: + case 18: + case 24: return MMC_NAND; + + case 7: + case 10: + case 13: + case 19: + case 25: + default: return GPMC_NOR; + } +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid=0; + /* On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate + * between ES2.0 and ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r" (cpuid)); + if((cpuid & 0xf) == 0x0) + return CPU_3430_ES1; + else + return CPU_3430_ES2; + +} + +u32 is_cpu_family(void) +{ + u32 cpuid = 0, cpu_family = 0; + u16 hawkeye; + + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); + if ((cpuid & 0xf) == 0x0) { + cpu_family = CPU_OMAP34XX; + } else { + cpuid = __raw_readl(OMAP34XX_CONTROL_ID); + hawkeye = (cpuid >> HAWKEYE_SHIFT) & 0xffff; + + switch (hawkeye) { + case HAWKEYE_OMAP34XX: + cpu_family = CPU_OMAP34XX; + break; + case HAWKEYE_AM35XX: + cpu_family = CPU_AM35XX; + break; + case HAWKEYE_OMAP36XX: + cpu_family = CPU_OMAP36XX; + break; + default: + cpu_family = CPU_OMAP34XX; + break; + } + } + return cpu_family; +} +/****************************************** + * cpu_is_3410(void) - returns true for 3410 + ******************************************/ +u32 cpu_is_3410(void) +{ + int status; + if(get_cpu_rev() < CPU_3430_ES2) { + return 0; + } else { + /* read scalability status and return 1 for 3410*/ + status = __raw_readl(CONTROL_SCALABLE_OMAP_STATUS); + /* Check whether MPU frequency is set to 266 MHz which + * is nominal for 3410. If yes return true else false + */ + if (((status >> 8) & 0x3) == 0x2) + return 1; + else + return 0; + } +} + +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = __raw_readl(addr) & ~(msk << start_bit); + tmp |= value << start_bit; + __raw_writel(tmp, addr); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + * volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ + u32 i = 0, val; + do { + ++i; + val = __raw_readl(read_addr) & read_bit_mask; + if (val == match_value) + return (1); + if (i == bound) + return (0); + } while (1); +} + +#ifdef CFG_OMAPEVM_DDR +#ifdef CONFIG_DDR_256MB_STACKED +/************************************************************************** + * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow + * command line mem=xyz use all memory with out discontinuous support + * compiled in. Could do it at the ATAG, but there really is two banks... + * Called as part of 2nd phase DDR init. + **************************************************************************/ +void make_cs1_contiguous(void) +{ + u32 size, a_add_low, a_add_high; + + size = get_sdr_cs_size(SDRC_CS0_OSET); + size /= SZ_32M; /* find size to offset CS1 */ + a_add_high = (size & 3) << 8; /* set up low field */ + a_add_low = (size & 0x3C) >> 2; /* set up high field */ + __raw_writel((a_add_high | a_add_low), SDRC_CS_CFG); +} + +/*********************************************************************** + * get_cs0_size() - get size of chip select 0/1 + ************************************************************************/ +u32 get_sdr_cs_size(u32 offset) +{ + u32 size; + + /* get ram size field */ + size = __raw_readl(SDRC_MCFG_0 + offset) >> 8; + size &= 0x3FF; /* remove unwanted bits */ + size *= SZ_2M; /* find size in MB */ + return size; +} +#endif + +/********************************************************************* + * config_3430sdram_ddr() - Init DDR on 3430SDP dev board. + *********************************************************************/ +void config_3430sdram_ddr(void) +{ + +#ifndef CONFIG_DDR_256MB_STACKED + /* reset sdrc controller */ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + __raw_writel(0, SDRC_SYSCONFIG); + + /* setup sdrc to ball mux */ + __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* set mdcfg */ + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); + + /* set timing */ + if (is_cpu_family() == CPU_OMAP36XX) { + __raw_writel(HYNIX_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(HYNIX_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + + } else { + if ((get_mem_type() == GPMC_ONENAND) || (get_mem_type() == MMC_ONENAND)){ + __raw_writel(INFINEON_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(INFINEON_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + } + if ((get_mem_type() == GPMC_NAND) ||(get_mem_type() == MMC_NAND)){ + __raw_writel(MICRON_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_0); + __raw_writel(MICRON_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_0); + } + } + + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL); + __raw_writel(SDP_SDRC_POWER_POP, SDRC_POWER); + + /* init sequence for mDDR/mSDR using manual commands (DDR is different) */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0); + delay(5000); + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0); + + /* set mr0 */ + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0); + + /* set up dll */ + __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL); + delay(0x2000); /* give time to lock */ +#else + /* reset sdrc controller */ + __raw_writel(SOFTRESET, SDRC_SYSCONFIG); + wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); + __raw_writel(0, SDRC_SYSCONFIG); + + /* setup sdrc to ball mux */ + __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); + + /* SDRC_MCFG0 register */ + (*(unsigned int*)0x6D000080) = 0x02584099;//from Micron + + if (is_cpu_family() == CPU_OMAP36XX) { + /* SDRC_ACTIM_CTRLA0 register */ + (*(unsigned int*)0x6D00009c) = 0x92e1c4c6;// for 200M + /* SDRC_ACTIM_CTRLB0 register */ + (*(unsigned int*)0x6D0000a0) = 0x0002111c; + } else { + /* SDRC_ACTIM_CTRLA0 register */ + (*(unsigned int*)0x6D00009c) = 0xaa9db4c6;// for 166M from rkw + /* SDRC_ACTIM_CTRLB0 register */ + (*(unsigned int*)0x6D0000a0) = 0x00011517; + } + + + (*(unsigned int*)0x6D0000a4) =0x0004DC01; + + /* Disble Power Down of CKE cuz of 1 CKE on combo part */ + (*(unsigned int*)0x6D000070) = 0x00000081; + + /* SDRC_Manual command register */ + (*(unsigned int*)0x6D0000a8) = 0x00000000; // NOP command + delay(5000); + (*(unsigned int*)0x6D0000a8) = 0x00000001; // Precharge command + (*(unsigned int*)0x6D0000a8) = 0x00000002; // Auto-refresh command + (*(unsigned int*)0x6D0000a8) = 0x00000002; // Auto-refresh command + + /* SDRC MR0 register */ + (*(int*)0x6D000084) = 0x00000032; // Burst length =4 + // CAS latency = 3 + // Write Burst = Read Burst + // Serial Mode + + /* SDRC DLLA control register */ + (*(unsigned int*)0x6D000060) = 0x0000A; + delay(0x20000); // some delay + +#endif + +#ifdef CONFIG_DDR_256MB_STACKED + make_cs1_contiguous(); + + __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0 + SDRC_CS1_OSET); + __raw_writel(MICRON_SDRC_ACTIM_CTRLA_0, SDRC_ACTIM_CTRLA_1); + __raw_writel(MICRON_SDRC_ACTIM_CTRLB_0, SDRC_ACTIM_CTRLB_1); + + __raw_writel(SDP_SDRC_RFR_CTRL, SDRC_RFR_CTRL + SDRC_CS1_OSET); + /* init sequence for mDDR/mSDR using manual commands */ + __raw_writel(CMD_NOP, SDRC_MANUAL_0 + SDRC_CS1_OSET); + delay(5000); /* supposed to be 100us per design spec for mddr/msdr */ + __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0 + SDRC_CS1_OSET); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0 + SDRC_CS1_OSET); + __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0 + SDRC_CS1_OSET); + __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0 + SDRC_CS1_OSET); +#endif +} +#endif /* CFG_OMAPEVM_DDR */ + +/************************************************************* + * get_sys_clk_speed - determine reference oscillator speed + * based on known 32kHz clock and gptimer. + *************************************************************/ +u32 get_osc_clk_speed(void) +{ + u32 start, cstart, cend, cdiff, cdiv, val; + + val = __raw_readl(PRM_CLKSRC_CTRL); + + if (val & BIT7) + cdiv = 2; + else if (val & BIT6) + cdiv = 1; + else + /* + * Should never reach here! + * TBD: Add a WARN()/BUG() + * For now, assume divider as 1. + */ + cdiv = 1; + + /* enable timer2 */ + val = __raw_readl(CM_CLKSEL_WKUP) | BIT0; + __raw_writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */ + + /* Enable I and F Clocks for GPT1 */ + val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2; + __raw_writel(val, CM_ICLKEN_WKUP); + val = __raw_readl(CM_FCLKEN_WKUP) | BIT0; + __raw_writel(val, CM_FCLKEN_WKUP); + + __raw_writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */ + __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */ + /* enable 32kHz source *//* enabled out of reset */ + /* determine sys_clk via gauging */ + + start = 20 + __raw_readl(S32K_CR); /* start time in 20 cycles */ + while (__raw_readl(S32K_CR) < start); /* dead loop till start time */ + cstart = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get start sys_clk count */ + while (__raw_readl(S32K_CR) < (start + 20)); /* wait for 40 cycles */ + cend = __raw_readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + + if (cdiv == 2) + { + cdiff *= 2; + } + + /* based on number of ticks assign speed */ + if (cdiff > 19000) + return (S38_4M); + else if (cdiff > 15200) + return (S26M); + else if (cdiff > 13000) + return (S24M); + else if (cdiff > 9000) + return (S19_2M); + else if (cdiff > 7600) + return (S13M); + else + return (S12M); +} + +/****************************************************************************** + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on + * -- input oscillator clock frequency. + * + *****************************************************************************/ +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel) +{ + if(osc_clk == S38_4M) + *sys_clkin_sel= 4; + else if(osc_clk == S26M) + *sys_clkin_sel = 3; + else if(osc_clk == S19_2M) + *sys_clkin_sel = 2; + else if(osc_clk == S13M) + *sys_clkin_sel = 1; + else if(osc_clk == S12M) + *sys_clkin_sel = 0; +} + +/* + * OMAP34x/35x specific functions + */ +static void dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_34X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + ptr = (dpll_param *)get_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2); /* set M6 */ + sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2); /* set M5 */ + sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2); /* set M4 */ + sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2); /* set M3 */ + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + sr32(CM_CLKSEL2_PLL, 8, 11, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + sr32(CM_CLKEN_PLL, 20, 4, ptr->fsel); + + /* LOCK MODE (EN_PERIPH_DPLL) : CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + sr32(CM_CLKEN_PLL_MPU, 4, 4, ptr->fsel); +} + +static void iva_init_34xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + 2*clk_index + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + sr32(CM_CLKEN_PLL_IVA2, 4, 4, ptr->fsel); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ +static void dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address of Core DPLL param table*/ + ptr = (dpll_param *)get_36x_core_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr += clk_index; + + /* CORE DPLL */ + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + sr32(CM_CLKSEL1_PLL, 27, 5, ptr->m2); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + sr32(CM_CLKSEL1_PLL, 16, 11, ptr->m); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + sr32(CM_CLKSEL1_PLL, 8, 7, ptr->n); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + sr32(CM_CLKSEL1_PLL, 6, 1, 0); + + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */ + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */ + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */ + sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV); /* l3 */ + + sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV_36X); /* gfx */ + sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM); /* reset mgr */ + + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + sr32(CM_CLKEN_PLL, 4, 4, ptr->fsel); + sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK); /* lock mode */ + + wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY); +} + +static void dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct dpll_per_36x_param *ptr; + + ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP); + wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + sr32(CM_CLKSEL1_EMU, 24, 6, ptr->m6); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + sr32(CM_CLKSEL_CAM, 0, 6, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + sr32(CM_CLKSEL_DSS, 0, 6, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + sr32(CM_CLKSEL_DSS, 8, 6, ptr->m3); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + sr32(CM_CLKSEL3_PLL, 0, 5, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + sr32(CM_CLKSEL2_PLL, 8, 12, ptr->m); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + sr32(CM_CLKSEL2_PLL, 0, 7, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + sr32(CM_CLKSEL_CORE, 12, 2, ptr->m2div); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK); + wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY); +} + +static void mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to MPU DPLL param table*/ + ptr = (dpll_param *)get_36x_mpu_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + sr32(CM_CLKSEL2_PLL_MPU, 0, 5, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + sr32(CM_CLKSEL1_PLL_MPU, 8, 11, ptr->m); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + sr32(CM_CLKSEL1_PLL_MPU, 0, 7, ptr->n); + + /* LOCK MODE (EN_MPU_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); +} + +static void iva_init_36xx(u32 sil_index, u32 clk_index) +{ + dpll_param *ptr; + + /* Getting the base address to IVA DPLL param table*/ + ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving it to the right sysclk and ES rev base */ + ptr = ptr + (2*clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, ptr->m); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, ptr->n); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK); + + wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY); +} + + +/****************************************************************************** + * prcm_init() - inits clocks for PRCM as defined in clocks.h + * -- called from SRAM, or Flash (using temp SRAM stack). + *****************************************************************************/ +void prcm_init(void) +{ + u32 osc_clk=0, sys_clkin_sel; + u32 clk_index, sil_index; + + /* Gauge the input clock speed and find out the sys_clkin_sel + * value corresponding to the input clock. + */ + osc_clk = get_osc_clk_speed(); + get_sys_clkin_sel(osc_clk, &sys_clkin_sel); + + sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */ + + /* If the input clock is greater than 19.2M always divide/2 */ + /* + * On OMAP3630, DDR data corruption has been observed on OFF mode + * exit if the sys clock was lower than 26M. As a work around, + * OMAP3630 is operated at 26M sys clock and this internal division + * is not performed. + */ + if((is_cpu_family() != CPU_OMAP36XX) && (sys_clkin_sel > 2)) { + sr32(PRM_CLKSRC_CTRL, 6, 2, 2);/* input clock divider */ + clk_index = sys_clkin_sel/2; + } else { + sr32(PRM_CLKSRC_CTRL, 6, 2, 1);/* input clock divider */ + clk_index = sys_clkin_sel; + } + + if (is_cpu_family() == CPU_OMAP36XX) { + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + } else { + sil_index = get_cpu_rev() - 1; + + /* The DPLL tables are defined according to sysclk value and + * silicon revision. The clk_index value will be used to get + * the values for that input sysclk from the DPLL param table + * and sil_index will get the values for that SysClk for the + * appropriate silicon rev. + */ + + /* Unlock MPU DPLL (slows things down, and needed later) */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS); + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + iva_init_34xx(sil_index, clk_index); + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); + wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + sr32(CM_CLKSEL_PER, 0, 8, 0xff); + sr32(CM_CLKSEL_WKUP, 0, 1, 1); + + delay(5000); +} + +/***************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************/ +void secure_unlock(void) +{ + /* Permission values for registers -Full fledged permissions to all */ + #define UNLOCK_1 0xFFFFFFFF + #define UNLOCK_2 0x00000000 + #define UNLOCK_3 0x0000FFFF + /* Protection Module Register Target APE (PM_RT)*/ + __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1); + __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0); + __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1); + + __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0); + __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2); + + /* IVA Changes */ + __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0); + __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0); + + __raw_writel(UNLOCK_1, SMS_RG_ATT0); /* SDRC region 0 public */ +} + +/********************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP type, unlock the SRAM for + * general use. + ***********************************************************/ +void try_unlock_memory(void) +{ + int mode; + + /* if GP device unlock device SRAM for general use */ + /* secure code breaks for Secure/Emulation device - HS/E/T*/ + mode = get_device_type(); + if (mode == GP_DEVICE) { + secure_unlock(); + } + return; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ + +void s_init(void) +{ + watchdog_init(); +#ifdef CONFIG_3430_AS_3410 + /* setup the scalability control register for + * 3430 to work in 3410 mode + */ + __raw_writel(0x5ABF,CONTROL_SCALABLE_OMAP_OCP); +#endif + try_unlock_memory(); + set_muxconf_regs(); + delay(100); + prcm_init(); + per_clocks_enable(); + config_3430sdram_ddr(); +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ + return(0); +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +void wait_for_command_complete(unsigned int wd_base) +{ + int pending = 1; + do { + pending = __raw_readl(wd_base + WWPS); + } while (pending); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ + /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is + * either taken care of by ROM (HS/EMU) or not accessible (GP). + * We need to take care of WD2-MPU or take a PRCM reset. WD3 + * should not be running and does not generate a PRCM reset. + */ + sr32(CM_FCLKEN_WKUP, 5, 1, 1); + sr32(CM_ICLKEN_WKUP, 5, 1, 1); + wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5); /* some issue here */ + + __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); + wait_for_command_complete(WD2_BASE); + __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ + return 0; +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void per_clocks_enable(void) +{ + /* Enable GP2 timer. */ + sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */ + sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */ + sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */ + +#ifdef CFG_NS16550 + /* Enable UART1 clocks */ + sr32(CM_FCLKEN1_CORE, 13, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 13, 1, 0x1); +#endif + +#ifdef CONFIG_MMC + /* Enable MMC1 clocks */ + sr32(CM_FCLKEN1_CORE, 24, 1, 0x1); + sr32(CM_ICLKEN1_CORE, 24, 1, 0x1); +#endif + delay(1000); +} + +/* Set MUX for UART, GPMC, SDRC, GPIO */ + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ +#define MUX_DEFAULT()\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /*SDRC_D0*/\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /*SDRC_D1*/\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /*SDRC_D2*/\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /*SDRC_D3*/\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /*SDRC_D4*/\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /*SDRC_D5*/\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /*SDRC_D6*/\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /*SDRC_D7*/\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /*SDRC_D8*/\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /*SDRC_D9*/\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /*SDRC_D10*/\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /*SDRC_D11*/\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /*SDRC_D12*/\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /*SDRC_D13*/\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /*SDRC_D14*/\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /*SDRC_D15*/\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /*SDRC_D16*/\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /*SDRC_D17*/\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /*SDRC_D18*/\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /*SDRC_D19*/\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /*SDRC_D20*/\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /*SDRC_D21*/\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /*SDRC_D22*/\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /*SDRC_D23*/\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /*SDRC_D24*/\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /*SDRC_D25*/\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /*SDRC_D26*/\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /*SDRC_D27*/\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /*SDRC_D28*/\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /*SDRC_D29*/\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /*SDRC_D30*/\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /*SDRC_D31*/\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /*SDRC_CLK*/\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /*SDRC_DQS0*/\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /*SDRC_DQS1*/\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /*SDRC_DQS2*/\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /*SDRC_DQS3*/\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /*GPMC_A1*/\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /*GPMC_A2*/\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /*GPMC_A3*/\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /*GPMC_A4*/\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /*GPMC_A5*/\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /*GPMC_A6*/\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /*GPMC_A7*/\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /*GPMC_A8*/\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /*GPMC_A9*/\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /*GPMC_A10*/\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /*GPMC_D0*/\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /*GPMC_D1*/\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /*GPMC_D2*/\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /*GPMC_D3*/\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /*GPMC_D4*/\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /*GPMC_D5*/\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /*GPMC_D6*/\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /*GPMC_D7*/\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /*GPMC_D8*/\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /*GPMC_D9*/\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /*GPMC_D10*/\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /*GPMC_D11*/\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /*GPMC_D12*/\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /*GPMC_D13*/\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /*GPMC_D14*/\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /*GPMC_D15*/\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /*GPMC_NCS0*/\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /*GPMC_NCS1*/\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /*GPMC_NCS2*/\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /*GPMC_NCS3*/\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /*GPMC_NCS4*/\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /*GPMC_NCS5*/\ + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTU | EN | M0)) /*GPMC_NCS6*/\ + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /*GPMC_NCS7*/\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /*GPMC_CLK*/\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /*GPMC_NADV_ALE*/\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /*GPMC_NOE*/\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /*GPMC_NWE*/\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /*GPMC_NBE0_CLE*/\ + MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)) /*GPIO_61*/\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /*GPMC_NWP*/\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /*GPMC_WAIT0*/\ + MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0)) /*GPMC_WAIT1*/\ + MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | EN | M4)) /*GPIO_64*/\ + MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M4)) /*GPIO_65*/\ + MUX_VAL(CP(DSS_DATA18), (IEN | PTD | DIS | M4)) /*GPIO_88*/\ + MUX_VAL(CP(DSS_DATA19), (IEN | PTD | DIS | M4)) /*GPIO_89*/\ + MUX_VAL(CP(DSS_DATA20), (IEN | PTD | DIS | M4)) /*GPIO_90*/\ + MUX_VAL(CP(DSS_DATA21), (IEN | PTD | DIS | M4)) /*GPIO_91*/\ + MUX_VAL(CP(CAM_WEN), (IEN | PTD | DIS | M4)) /*GPIO_167*/\ + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)) /*UART1_TX*/\ + MUX_VAL(CP(UART1_RTS), (IDIS | PTD | DIS | M0)) /*UART1_RTS*/\ + MUX_VAL(CP(UART1_CTS), (IEN | PTU | DIS | M0)) /*UART1_CTS*/\ + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)) /*UART1_RX*/\ + MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M4)) /*GPIO_158*/\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /*SYS_32K*/\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /*GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /*GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /*GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /*GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /*GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /*GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /*GPIO_8 */\ + MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M4)) /*GPIO_186*/\ + MUX_VAL(CP(JTAG_nTRST), (IEN | PTD | DIS | M0)) /*JTAG_nTRST*/\ + MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)) /*JTAG_TCK*/\ + MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)) /*JTAG_TMS*/\ + MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)) /*JTAG_TDI*/\ + MUX_VAL(CP(JTAG_EMU0), (IEN | PTD | DIS | M0)) /*JTAG_EMU0*/\ + MUX_VAL(CP(JTAG_EMU1), (IEN | PTD | DIS | M0)) /*JTAG_EMU1*/\ + MUX_VAL(CP(ETK_CLK), (IEN | PTD | DIS | M4)) /*GPIO_12*/\ + MUX_VAL(CP(ETK_CTL), (IEN | PTD | DIS | M4)) /*GPIO_13*/\ + MUX_VAL(CP(ETK_D0 ), (IEN | PTD | DIS | M4)) /*GPIO_14*/\ + MUX_VAL(CP(ETK_D1 ), (IEN | PTD | DIS | M4)) /*GPIO_15*/\ + MUX_VAL(CP(ETK_D2 ), (IEN | PTD | DIS | M4)) /*GPIO_16*/\ + MUX_VAL(CP(ETK_D10), (IEN | PTD | DIS | M4)) /*GPIO_24*/\ + MUX_VAL(CP(ETK_D11), (IEN | PTD | DIS | M4)) /*GPIO_25*/\ + MUX_VAL(CP(ETK_D12), (IEN | PTD | DIS | M4)) /*GPIO_26*/\ + MUX_VAL(CP(ETK_D13), (IEN | PTD | DIS | M4)) /*GPIO_27*/\ + MUX_VAL(CP(ETK_D14), (IEN | PTD | DIS | M4)) /*GPIO_28*/\ + MUX_VAL(CP(ETK_D15), (IEN | PTD | DIS | M4)) /*GPIO_29*/ + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + * specific to the hardware. Many pins need + * to be moved from protect to primary mode. + *********************************************************/ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} + +/********************************************************** + * Routine: nand+_init + * Description: Set up nand for nand and jffs2 commands + *********************************************************/ + +int nand_init(void) +{ + /* global settings */ + __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ + __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ + __raw_writel(0, GPMC_TIMEOUT_CONTROL);/* timeout disable */ + + /* Set the GPMC Vals . For NAND boot on 3430SDP, NAND is mapped at CS0 + * , NOR at CS1 and MPDB at CS3. And oneNAND boot, we map oneNAND at CS0. + * We configure only GPMC CS0 with required values. Configiring other devices + * at other CS in done in u-boot anyway. So we don't have to bother doing it here. + */ + __raw_writel(0 , GPMC_CONFIG7 + GPMC_CONFIG_CS0); + delay(1000); + + if ((get_mem_type() == GPMC_NAND) || (get_mem_type() == MMC_NAND)){ + __raw_writel( M_NAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( M_NAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((NAND_BASE_ADR>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); + + if (nand_chip()){ +#ifdef CFG_PRINTF + printf("Unsupported Chip!\n"); +#endif + return 1; + } + + } + + if ((get_mem_type() == GPMC_ONENAND) || (get_mem_type() == MMC_ONENAND)){ + __raw_writel( ONENAND_GPMC_CONFIG1, GPMC_CONFIG1 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG2, GPMC_CONFIG2 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG3, GPMC_CONFIG3 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG4, GPMC_CONFIG4 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG5, GPMC_CONFIG5 + GPMC_CONFIG_CS0); + __raw_writel( ONENAND_GPMC_CONFIG6, GPMC_CONFIG6 + GPMC_CONFIG_CS0); + + /* Enable the GPMC Mapping */ + __raw_writel(( ((OMAP34XX_GPMC_CS0_SIZE & 0xF)<<8) | + ((ONENAND_BASE>>24) & 0x3F) | + (1<<6) ), (GPMC_CONFIG7 + GPMC_CONFIG_CS0)); + delay(2000); + + if (onenand_chip()){ +#ifdef CFG_PRINTF + printf("OneNAND Unsupported !\n"); +#endif + return 1; + } + } + return 0; +} + + +typedef int (mmc_boot_addr) (void); +int mmc_boot(unsigned char *buf) +{ + + long size = 0; +#ifdef CFG_CMD_FAT + block_dev_desc_t *dev_desc = NULL; + unsigned char ret = 0; + + printf("Starting X-loader on MMC\n"); + + ret = mmc_init(1); + if(ret == 0){ + printf("\n MMC init failed\n"); + return 0; + } + + dev_desc = mmc_get_dev(0); + fat_register_device(dev_desc, 1); + size = file_fat_read("u-boot.bin", buf, 0); + if (size == -1) { + return 0; + } + printf("\n%ld Bytes Read from MMC\n", size); + + printf("Starting OS Bootloader from MMC...\n"); +#endif + return size; +} + +/* optionally do something like blinking LED */ +void board_hang (void) +{ while (0) {};}
diff --git a/x-loader/board/omap3evm/platform.S b/x-loader/board/omap3evm/platform.S new file mode 100755 index 0000000..73a3c48 --- /dev/null +++ b/x-loader/board/omap3evm/platform.S
@@ -0,0 +1,484 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: + .word TEXT_BASE /* sdram load addr from config.mk */ + +#if !defined(CFG_NAND_BOOT) && !defined(CFG_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* get addr of clock setting code */ + mov r2, #384 /* r2 size to copy (div by 32 bytes) */ + mov r1, r1 /* r1 <- dest address (passed in) */ + add r2, r2, r0 /* r2 <- source end address */ +next2: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next2 + mov pc, lr /* back to caller */ + +/* **************************************************************************** + * NOTE: 3430 X-loader currently does not use this code. +* It could be removed its is kept for compatabily with u-boot. + * + * go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + * -executed from SRAM. + * R0 = CM_CLKEN_PLL-bypass value + * R1 = CM_CLKSEL1_PLL-m, n, and divider values + * R2 = CM_CLKSEL_CORE-divider values + * R3 = CM_IDLEST_CKGEN - addr dpll lock wait + * + * Note: If core unlocks/relocks and SDRAM is running fast already it gets + * confused. A reset of the controller gets it back. Taking away its + * L3 when its not in self refresh seems bad for it. Normally, this code + * runs from flash before SDR is init so that should be ok. + ******************************************************************************/ +.global go_to_speed + go_to_speed: + stmfd sp!, {r4-r6} + + /* move into fast relock bypass */ + ldr r4, pll_ctl_add + str r0, [r4] +wait1: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + beq wait1 /* if lock, loop */ + + /* set new dpll dividers _after_ in bypass */ + ldr r5, pll_div_add1 + str r1, [r5] /* set m, n, m2 */ + ldr r5, pll_div_add2 + str r2, [r5] /* set l3/l4/.. dividers*/ + ldr r5, pll_div_add3 /* wkup */ + ldr r2, pll_div_val3 /* rsm val */ + str r2, [r5] + ldr r5, pll_div_add4 /* gfx */ + ldr r2, pll_div_val4 + str r2, [r5] + ldr r5, pll_div_add5 /* emu */ + ldr r2, pll_div_val5 + str r2, [r5] + + /* now prepare GPMC (flash) for new dpll speed */ + /* flash needs to be stable when we jump back to it */ + ldr r5, flash_cfg3_addr + ldr r2, flash_cfg3_val + str r2, [r5] + ldr r5, flash_cfg4_addr + ldr r2, flash_cfg4_val + str r2, [r5] + ldr r5, flash_cfg5_addr + ldr r2, flash_cfg5_val + str r2, [r5] + ldr r5, flash_cfg1_addr + ldr r2, [r5] + orr r2, r2, #0x3 /* up gpmc divider */ + str r2, [r5] + + /* lock DPLL3 and wait a bit */ + orr r0, r0, #0x7 /* set up for lock mode */ + str r0, [r4] /* lock */ + nop /* ARM slow at this point working at sys_clk */ + nop + nop + nop +wait2: + ldr r5, [r3] /* get status */ + and r5, r5, #0x1 /* isolate core status */ + cmp r5, #0x1 /* still locked? */ + bne wait2 /* if lock, loop */ + nop + nop + nop + nop + ldmfd sp!, {r4-r6} + mov pc, lr /* back to caller, locked */ + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +/* The Nor has to be in the Flash Base CS0 for this condition to happen */ +flash_cfg1_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0 + GPMC_CONFIG5) +pll_ctl_add: + .word CM_CLKEN_PLL +pll_div_add1: + .word CM_CLKSEL1_PLL +pll_div_add2: + .word CM_CLKSEL_CORE +pll_div_add3: + .word CM_CLKSEL_WKUP +pll_div_val3: + .word (WKUP_RSM << 1) +pll_div_add4: + .word CM_CLKSEL_GFX +pll_div_val4: + .word (GFX_DIV << 0) +pll_div_add5: + .word CM_CLKSEL1_EMU +pll_div_val5: + .word CLSEL1_EMU_VAL + +#endif + +.globl lowlevel_init +lowlevel_init: + ldr sp, SRAM_STACK + str ip, [sp] /* stash old link register */ + mov ip, lr /* save link reg across call */ + bl s_init /* go setup pll,mux,memory */ + ldr ip, [sp] /* restore save ip */ + mov lr, ip /* restore link reg */ + + /* back to arch calling code */ + mov pc, lr + + /* the literal pools origin */ + .ltorg + +REG_CONTROL_STATUS: + .word CONTROL_STATUS +SRAM_STACK: + .word LOW_LEVEL_SRAM_STACK + + +/* DPLL(1-4) PARAM TABLES */ +/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal + * OPP (1.2V). The fields are defined according to dpll_param struct(clock.c). + * The values are defined for all possible sysclk and for ES1 and ES2. + */ + +mpu_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x0FE +.word 0x07 +.word 0x05 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x17D +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x1F4 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x179 +.word 0x12 +.word 0x04 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x17D +.word 0x19 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0FA +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x1FA +.word 0x32 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x271 +.word 0x2F +.word 0x03 +.word 0x01 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x07D +.word 0x05 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x0FA +.word 0x0C +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x168 +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x082 +.word 0x09 +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x0B +.word 0x06 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x07D +.word 0x0C +.word 0x07 +.word 0x01 +/* ES2 */ +.word 0x0B4 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x13F +.word 0x30 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0E1 +.word 0x17 +.word 0x06 +.word 0x01 + + +.globl get_iva_dpll_param +get_iva_dpll_param: + adr r0, iva_dpll_param + mov pc, lr + +core_dpll_param: +/* 12MHz */ +/* ES1 */ +.word 0x19F +.word 0x0E +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x05 +.word 0x07 +.word 0x01 + +/* 13MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x10 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x14C +.word 0x0C +.word 0x03 +.word 0x01 + +/* 19.2MHz */ +/* ES1 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x17 +.word 0x03 +.word 0x01 + +/* 26MHz */ +/* ES1 */ +.word 0x1B2 +.word 0x21 +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x0A6 +.word 0x0C +.word 0x07 +.word 0x01 + +/* 38.4MHz */ +/* ES1 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 +/* ES2 */ +.word 0x19F +.word 0x2F +.word 0x03 +.word 0x01 + +.globl get_core_dpll_param +get_core_dpll_param: + adr r0, core_dpll_param + mov pc, lr + +/* PER DPLL values are same for both ES1 and ES2 */ +per_dpll_param: +/* 12MHz */ +.word 0xD8 +.word 0x05 +.word 0x07 +.word 0x09 + +/* 13MHz */ +.word 0x1B0 +.word 0x0C +.word 0x03 +.word 0x09 + +/* 19.2MHz */ +.word 0xE1 +.word 0x09 +.word 0x07 +.word 0x09 + +/* 26MHz */ +.word 0xD8 +.word 0x0C +.word 0x07 +.word 0x09 + +/* 38.4MHz */ +.word 0xE1 +.word 0x13 +.word 0x07 +.word 0x09 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* + * Tables for 36x/37x devices + * + * (Populated for 13MHz only) + */ +mpu_36x_dpll_param: +.word 300, 12, 0, 1 +.word 300, 12, 0, 1 +.word 300, 12, 0, 1 +.word 300, 12, 0, 1 + +iva_36x_dpll_param: +.word 10, 0, 0, 1 +.word 10, 0, 0, 1 +.word 10, 0, 0, 1 +.word 10, 0, 0, 1 + +core_36x_dpll_param: +.word 200, 12, 0, 1 +.word 200, 12, 0, 1 +.word 200, 12, 0, 1 +.word 200, 12, 0, 1 + +per_36x_dpll_param: +/* SYSCLK M N M2 M3 M4 M5 M6 m2DIV */ +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 + +.globl get_36x_mpu_dpll_param +get_36x_mpu_dpll_param: + adr r0, mpu_36x_dpll_param + mov pc, lr + +.globl get_36x_iva_dpll_param +get_36x_iva_dpll_param: + adr r0, iva_36x_dpll_param + mov pc, lr + +.globl get_36x_core_dpll_param +get_36x_core_dpll_param: + adr r0, core_36x_dpll_param + mov pc, lr + +.globl get_36x_per_dpll_param +get_36x_per_dpll_param: + adr r0, per_36x_dpll_param + mov pc, lr
diff --git a/x-loader/board/omap3evm/x-load.lds b/x-loader/board/omap3evm/x-load.lds new file mode 100755 index 0000000..5f352d3 --- /dev/null +++ b/x-loader/board/omap3evm/x-load.lds
@@ -0,0 +1,54 @@ +/* + * November 2006 - Changed to support 3430sdp device + * Copyright (c) 2004-2006 Texas Instruments + * + * (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 : + { + cpu/omap3/start.o (.text) + *(.text) + } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .got : { *(.got) } + + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + _end = .; +}
diff --git a/x-loader/boards.cfg b/x-loader/boards.cfg new file mode 100644 index 0000000..210a921 --- /dev/null +++ b/x-loader/boards.cfg
@@ -0,0 +1,26 @@ +# +# List of boards +# +# Syntax: +# white-space separated list of entries; +# each entry has the following fields: +# +# Targetname Architecture CPU Boardname Vendor SoC +# +# Unused fields can be specified as "-", or omitted if they +# are the last field on the line. +# +# Lines starting with '#' are comments. +# Blank lines are ignored. +# +# To keep the list sorted, use something like +# +# :.,$! sort -f -k2,2 -k3,3 -k6,6 -k5,5 -k1,1 +# +# Target ARCH SoC Board name Vendor SoC +########################################################################### + +diamond arm omap3 diamond nest +diamond-usb-loader arm omap3 diamond-usb-loader nest +j49 arm omap3 j49 nest +j49-usb-loader arm omap3 j49-usb-loader nest
diff --git a/x-loader/common/Makefile b/x-loader/common/Makefile new file mode 100644 index 0000000..b6f72ba --- /dev/null +++ b/x-loader/common/Makefile
@@ -0,0 +1,54 @@ +# +# (C) Copyright 2004-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)libcommon.a + +AOBJS = + +# core +COBJS-y += bootm.o +COBJS-y += main.o +COBJS-y += console.o +COBJS-y += image.o + +COBJS := $(sort $(COBJS-y)) +SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) + +CPPFLAGS += -I.. + +all: $(LIB) $(AOBJS) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/common/bootm.c b/x-loader/common/bootm.c new file mode 100644 index 0000000..62ba220 --- /dev/null +++ b/x-loader/common/bootm.c
@@ -0,0 +1,160 @@ +/* + * Copyright (c) 2010 Grant Erickson <marathon96@gmail.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 + * + * Description: + * This file implements functions that boot the second-stage + * boot loader from memory, in either raw, binary format or + * in u-boot 'mkimage' format. + */ + +#include <common.h> +#include <bootm.h> +#include <image.h> + +typedef void (spl)(void); + +static void exec(ulong address, const char *what) +{ + printf("\nStarting %s ...", what); + + ((spl *)address)(); +} + +int bootm(const uint8_t *buffer) +{ + int status = BOOTM_STATUS_FAILURE; +#if defined(CONFIG_BOOTM_IMAGE) + const int format = genimg_get_format((void *)buffer); + const image_header_t * header = (const image_header_t *)buffer; + + switch (format) { + + case IMAGE_FORMAT_LEGACY: + status = bootm_image(header); + break; + + case IMAGE_FORMAT_FIT: + printf("Unsupported image format FIT (%d)\n", format); + break; + + case IMAGE_FORMAT_INVALID: + default: + printf("Unknown or invalid image format (%d)\n", format); + break; + + } +#else + status = bootm_binary(buffer); +#endif /* defined(CONFIG_BOOTM_IMAGE) */ + + return (status); +} + +int bootm_binary(const uint8_t *buffer) +{ + /* This should never return. */ + + exec((ulong)buffer, "second-stage boot loader"); + + /* However, if it does, return failed status. */ + + return (BOOTM_STATUS_FAILURE); +} + +#if defined(CONFIG_BOOTM_IMAGE) +int bootm_image(const image_header_t *header) +{ + const char * failure = NULL; + const char * type_name = NULL; + uint32_t load, image_start, image_len; + + /* Display to standard output the image contents. */ + + image_print_contents(header); + + /* Validate the image header and image data CRCs */ + + puts(" Verifying Checksum ... "); + + { + if (!image_check_hcrc(header)) { + failure = "Header Invalid\n"; + goto fail; + } + + if (!image_check_dcrc(header)) { + failure = "Data Invalid\n"; + goto fail; + } + } + + puts("OK\n"); + + /* We ONLY support uncompressed ARM U-Boot firmware images. Check + * to make sure that's what we are going to boot. + */ + + if (!image_check_type(header, IH_TYPE_FIRMWARE)) { + failure = "Image is not a firmware image\n"; + goto fail; + } + + if (!image_check_os(header, IH_OS_U_BOOT)) { + failure = "Image is not u-boot firmware\n"; + goto fail; + } + + if (image_get_comp(header) != IH_COMP_NONE) { + failure = "Image is compressed\n"; + goto fail; + } + + if (!image_check_target_arch(header)) { + failure = "Image is not built for this processor\n"; + goto fail; + } + + type_name = genimg_get_type_name(image_get_type(header)); + + printf(" Loading %s ... ", type_name); + + { + load = image_get_load(header); + image_start = image_get_data(header); + image_len = image_get_data_size(header); + + memmove_wd((void *)load, (void *)image_start, image_len, CHUNKSZ); + } + + puts("OK\n"); + + /* This should never return. */ + + exec(load, type_name); + + /* However, if it does, return failed status. */ + + fail: + puts(failure); + + return (BOOTM_STATUS_FAILURE); +} +#endif /* defined(CONFIG_BOOTM_IMAGE) */
diff --git a/x-loader/common/console.c b/x-loader/common/console.c new file mode 100644 index 0000000..0ea3cb7 --- /dev/null +++ b/x-loader/common/console.c
@@ -0,0 +1,30 @@ +/* + * (C) Copyright 2000 + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it + * + * 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> + +void puts(const char *s) +{ + serial_puts(s); +} +
diff --git a/x-loader/common/image.c b/x-loader/common/image.c new file mode 100644 index 0000000..a916e95 --- /dev/null +++ b/x-loader/common/image.c
@@ -0,0 +1,2541 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (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 + */ + +#ifndef USE_HOSTCC +#include <common.h> +#include <watchdog.h> + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +#include <status_led.h> +#endif + +#ifdef CONFIG_HAS_DATAFLASH +#include <dataflash.h> +#endif + +#ifdef CONFIG_LOGBUFFER +#include <logbuff.h> +#endif + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) +#include <rtc.h> +#endif + +#include <image.h> + +#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#endif + +#if defined(CONFIG_FIT) +#include <u-boot/md5.h> +#include <sha1.h> + +static int fit_check_ramdisk (const void *fit, int os_noffset, + uint8_t arch, int verify); +#endif + +#else +#include "mkimage.h" +#include <u-boot/md5.h> +#include <time.h> +#include <image.h> +#endif /* !USE_HOSTCC*/ + +static table_entry_t uimage_arch[] = { + { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, + { IH_ARCH_ALPHA, "alpha", "Alpha", }, + { IH_ARCH_ARM, "arm", "ARM", }, + { IH_ARCH_I386, "x86", "Intel x86", }, + { IH_ARCH_IA64, "ia64", "IA64", }, + { IH_ARCH_M68K, "m68k", "M68K", }, + { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_ARCH_MIPS, "mips", "MIPS", }, + { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_ARCH_NIOS2, "nios2", "NIOS II", }, + { IH_ARCH_PPC, "powerpc", "PowerPC", }, + { IH_ARCH_PPC, "ppc", "PowerPC", }, + { IH_ARCH_S390, "s390", "IBM S390", }, + { IH_ARCH_SH, "sh", "SuperH", }, + { IH_ARCH_SPARC, "sparc", "SPARC", }, + { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, + { IH_ARCH_AVR32, "avr32", "AVR32", }, + { -1, "", "", }, +}; + +static table_entry_t uimage_os[] = { + { IH_OS_INVALID, NULL, "Invalid OS", }, + { IH_OS_LINUX, "linux", "Linux", }, +#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) + { IH_OS_LYNXOS, "lynxos", "LynxOS", }, +#endif + { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_RTEMS, "rtems", "RTEMS", }, + { IH_OS_U_BOOT, "u-boot", "U-Boot", }, +#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) + { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_VXWORKS, "vxworks", "VxWorks", }, +#endif +#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC) + { IH_OS_INTEGRITY,"integrity", "INTEGRITY", }, +#endif +#ifdef USE_HOSTCC + { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, + { IH_OS_DELL, "dell", "Dell", }, + { IH_OS_ESIX, "esix", "Esix", }, + { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, + { IH_OS_IRIX, "irix", "Irix", }, + { IH_OS_NCR, "ncr", "NCR", }, + { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, + { IH_OS_PSOS, "psos", "pSOS", }, + { IH_OS_SCO, "sco", "SCO", }, + { IH_OS_SOLARIS, "solaris", "Solaris", }, + { IH_OS_SVR4, "svr4", "SVR4", }, +#endif + { -1, "", "", }, +}; + +static table_entry_t uimage_type[] = { + { IH_TYPE_INVALID, NULL, "Invalid Image", }, + { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, + { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, + { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, + { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, + { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, + { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",}, + { IH_TYPE_IMXIMAGE, "imximage", "Freescale i.MX Boot Image",}, + { -1, "", "", }, +}; + +static table_entry_t uimage_comp[] = { + { IH_COMP_NONE, "none", "uncompressed", }, + { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, + { IH_COMP_GZIP, "gzip", "gzip compressed", }, + { IH_COMP_LZMA, "lzma", "lzma compressed", }, + { IH_COMP_LZO, "lzo", "lzo compressed", }, + { -1, "", "", }, +}; + +uint32_t crc32 (uint32_t, const unsigned char *, uint); +uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp); +#endif + +/*****************************************************************************/ +/* Legacy format routines */ +/*****************************************************************************/ +int image_check_hcrc (const image_header_t *hdr) +{ + ulong hcrc; + ulong len = image_get_header_size (); + image_header_t header; + + /* Copy header so we can blank CRC field for re-calculation */ + memmove (&header, (char *)hdr, image_get_header_size ()); + image_set_hcrc (&header, 0); + + hcrc = crc32 (0, (unsigned char *)&header, len); + + return (hcrc == image_get_hcrc (hdr)); +} + +int image_check_dcrc (const image_header_t *hdr) +{ + ulong data = image_get_data (hdr); + ulong len = image_get_data_size (hdr); + ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32); + + return (dcrc == image_get_dcrc (hdr)); +} + +/** + * image_multi_count - get component (sub-image) count + * @hdr: pointer to the header of the multi component image + * + * image_multi_count() returns number of components in a multi + * component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * number of components + */ +ulong image_multi_count (const image_header_t *hdr) +{ + ulong i, count = 0; + uint32_t *size; + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)image_get_data (hdr); + + /* count non empty slots */ + for (i = 0; size[i]; ++i) + count++; + + return count; +} + +/** + * image_multi_getimg - get component data address and size + * @hdr: pointer to the header of the multi component image + * @idx: index of the requested component + * @data: pointer to a ulong variable, will hold component data address + * @len: pointer to a ulong variable, will hold component size + * + * image_multi_getimg() returns size and data address for the requested + * component in a multi component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * data address and size of the component, if idx is valid + * 0 in data and len, if idx is out of range + */ +void image_multi_getimg (const image_header_t *hdr, ulong idx, + ulong *data, ulong *len) +{ + int i; + uint32_t *size; + ulong offset, count, img_data; + + /* get number of component */ + count = image_multi_count (hdr); + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)image_get_data (hdr); + + /* get address of the proper component data start, which means + * skipping sizes table (add 1 for last, null entry) */ + img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t); + + if (idx < count) { + *len = uimage_to_cpu (size[idx]); + offset = 0; + + /* go over all indices preceding requested component idx */ + for (i = 0; i < idx; i++) { + /* add up i-th component size, rounding up to 4 bytes */ + offset += (uimage_to_cpu (size[i]) + 3) & ~3 ; + } + + /* calculate idx-th component data address */ + *data = img_data + offset; + } else { + *len = 0; + *data = 0; + } +} + +static void image_print_type (const image_header_t *hdr) +{ + const char *os, *arch, *type, *comp; + + os = genimg_get_os_name (image_get_os (hdr)); + arch = genimg_get_arch_name (image_get_arch (hdr)); + type = genimg_get_type_name (image_get_type (hdr)); + comp = genimg_get_comp_name (image_get_comp (hdr)); + + printf ("%s %s %s (%s)\n", arch, os, type, comp); +} + +/** + * image_print_contents - prints out the contents of the legacy format image + * @ptr: pointer to the legacy format image header + * @p: pointer to prefix string + * + * image_print_contents() formats a multi line legacy image contents description. + * The routine prints out all header fields followed by the size/offset data + * for MULTI/SCRIPT images. + * + * returns: + * no returned results + */ +void image_print_contents (const void *ptr) +{ + const image_header_t *hdr = (const image_header_t *)ptr; + const char *p; + +#ifdef USE_HOSTCC + p = ""; +#else + p = " "; +#endif + + printf ("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name (hdr)); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + printf ("%sCreated: ", p); + genimg_print_time ((time_t)image_get_time (hdr)); +#endif + printf ("%sImage Type: ", p); + image_print_type (hdr); + printf ("%sData Size: ", p); + genimg_print_size (image_get_data_size (hdr)); + printf ("%sLoad Address: %08x\n", p, image_get_load (hdr)); + printf ("%sEntry Point: %08x\n", p, image_get_ep (hdr)); + + if (image_check_type (hdr, IH_TYPE_MULTI) || + image_check_type (hdr, IH_TYPE_SCRIPT)) { + int i; + ulong data, len; + ulong count = image_multi_count (hdr); + + printf ("%sContents:\n", p); + for (i = 0; i < count; i++) { + image_multi_getimg (hdr, i, &data, &len); + + printf ("%s Image %d: ", p, i); + genimg_print_size (len); + + if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf ("%s Offset = 0x%08lx\n", p, data); + } + } + } +} + +/*****************************************************************************/ +/* Shared dual-format routines */ +/*****************************************************************************/ +#ifndef USE_HOSTCC +void memmove_wd (void *to, void *from, size_t len, ulong chunksz) +{ + if (to == from) + return; + +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + while (len > 0) { + size_t tail = (len > chunksz) ? chunksz : len; + WATCHDOG_RESET (); + memmove (to, from, tail); + to += tail; + from += tail; + len -= tail; + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove (to, from, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ +} +#endif /* !USE_HOSTCC */ + +void genimg_print_size (uint32_t size) +{ +#ifndef USE_HOSTCC + printf ("%d Bytes = ", size); + print_size (size, "\n"); +#else + printf ("%d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, + (double)size / 1.048576e6); +#endif +} + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp) +{ +#ifndef USE_HOSTCC + struct rtc_time tm; + + to_tm (timestamp, &tm); + printf ("%4d-%02d-%02d %2d:%02d:%02d UTC\n", + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#else + printf ("%s", ctime(×tamp)); +#endif +} +#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */ + +/** + * get_table_entry_name - translate entry id to long name + * @table: pointer to a translation table for entries of a specific type + * @msg: message to be returned when translation fails + * @id: entry id to be translated + * + * get_table_entry_name() will go over translation table trying to find + * entry that matches given id. If matching entry is found, its long + * name is returned to the caller. + * + * returns: + * long entry name if translation succeeds + * msg otherwise + */ +char *get_table_entry_name (table_entry_t *table, char *msg, int id) +{ + for (; table->id >= 0; ++table) { + if (table->id == id) + return table->lname; + } + return (msg); +} + +const char *genimg_get_os_name (uint8_t os) +{ + return (get_table_entry_name (uimage_os, "Unknown OS", os)); +} + +const char *genimg_get_arch_name (uint8_t arch) +{ + return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch)); +} + +const char *genimg_get_type_name (uint8_t type) +{ + return (get_table_entry_name (uimage_type, "Unknown Image", type)); +} + +const char *genimg_get_comp_name (uint8_t comp) +{ + return (get_table_entry_name (uimage_comp, "Unknown Compression", comp)); +} + +/** + * get_table_entry_id - translate short entry name to id + * @table: pointer to a translation table for entries of a specific type + * @table_name: to be used in case of error + * @name: entry short name to be translated + * + * get_table_entry_id() will go over translation table trying to find + * entry that matches given short name. If matching entry is found, + * its id returned to the caller. + * + * returns: + * entry id if translation succeeds + * -1 otherwise + */ +int get_table_entry_id (table_entry_t *table, + const char *table_name, const char *name) +{ + table_entry_t *t; +#ifdef USE_HOSTCC + int first = 1; + + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcasecmp(t->sname, name) == 0) + return (t->id); + } + + fprintf (stderr, "\nInvalid %s Type - valid names are", table_name); + for (t = table; t->id >= 0; ++t) { + if (t->sname == NULL) + continue; + fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); + first = 0; + } + fprintf (stderr, "\n"); +#else + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcmp(t->sname, name) == 0) + return (t->id); + } + debug ("Invalid %s Type: %s\n", table_name, name); +#endif /* USE_HOSTCC */ + return (-1); +} + +int genimg_get_os_id (const char *name) +{ + return (get_table_entry_id (uimage_os, "OS", name)); +} + +int genimg_get_arch_id (const char *name) +{ + return (get_table_entry_id (uimage_arch, "CPU", name)); +} + +int genimg_get_type_id (const char *name) +{ + return (get_table_entry_id (uimage_type, "Image", name)); +} + +int genimg_get_comp_id (const char *name) +{ + return (get_table_entry_id (uimage_comp, "Compression", name)); +} + +#ifndef USE_HOSTCC +/** + * genimg_get_format - get image format type + * @img_addr: image start address + * + * genimg_get_format() checks whether provided address points to a valid + * legacy or FIT image. + * + * New uImage format and FDT blob are based on a libfdt. FDT blob + * may be passed directly or embedded in a FIT image. In both situations + * genimg_get_format() must be able to dectect libfdt header. + * + * returns: + * image format type or IMAGE_FORMAT_INVALID if no image is present + */ +int genimg_get_format (void *img_addr) +{ + ulong format = IMAGE_FORMAT_INVALID; + const image_header_t *hdr; +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) + char *fit_hdr; +#endif + + hdr = (const image_header_t *)img_addr; + if (image_check_magic(hdr)) + format = IMAGE_FORMAT_LEGACY; +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) + else { + fit_hdr = (char *)img_addr; + if (fdt_check_header (fit_hdr) == 0) + format = IMAGE_FORMAT_FIT; + } +#endif + + return format; +} + +/** + * genimg_get_image - get image from special storage (if necessary) + * @img_addr: image start address + * + * genimg_get_image() checks if provided image start adddress is located + * in a dataflash storage. If so, image is moved to a system RAM memory. + * + * returns: + * image start address after possible relocation from special storage + */ +ulong genimg_get_image (ulong img_addr) +{ + ulong ram_addr = img_addr; + +#ifdef CONFIG_HAS_DATAFLASH + ulong h_size, d_size; + + if (addr_dataflash (img_addr)){ + /* ger RAM address */ + ram_addr = CONFIG_SYS_LOAD_ADDR; + + /* get header size */ + h_size = image_get_header_size (); +#if defined(CONFIG_FIT) + if (sizeof(struct fdt_header) > h_size) + h_size = sizeof(struct fdt_header); +#endif + + /* read in header */ + debug (" Reading image header from dataflash address " + "%08lx to RAM address %08lx\n", img_addr, ram_addr); + + read_dataflash (img_addr, h_size, (char *)ram_addr); + + /* get data size */ + switch (genimg_get_format ((void *)ram_addr)) { + case IMAGE_FORMAT_LEGACY: + d_size = image_get_data_size ((const image_header_t *)ram_addr); + debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + d_size = fit_get_size ((const void *)ram_addr) - h_size; + debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; +#endif + default: + printf (" No valid image found at 0x%08lx\n", img_addr); + return ram_addr; + } + + /* read in image data */ + debug (" Reading image remaining data from dataflash address " + "%08lx to RAM address %08lx\n", img_addr + h_size, + ram_addr + h_size); + + read_dataflash (img_addr + h_size, d_size, + (char *)(ram_addr + h_size)); + + } +#endif /* CONFIG_HAS_DATAFLASH */ + + return ram_addr; +} + +/** + * fit_has_config - check if there is a valid FIT configuration + * @images: pointer to the bootm command headers structure + * + * fit_has_config() checks if there is a FIT configuration in use + * (if FTI support is present). + * + * returns: + * 0, no FIT support or no configuration found + * 1, configuration found + */ +int genimg_has_config (bootm_headers_t *images) +{ +#if defined(CONFIG_FIT) + if (images->fit_uname_cfg) + return 1; +#endif + return 0; +} + +#ifdef CONFIG_OF_LIBFDT +static void fdt_error (const char *msg) +{ + puts ("ERROR: "); + puts (msg); + puts (" - must RESET the board to recover.\n"); +} + +static const image_header_t *image_get_fdt (ulong fdt_addr) +{ + const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr; + + image_print_contents (fdt_hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + return NULL; + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + return NULL; + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + return NULL; + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + return NULL; + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + return NULL; + } + return fdt_hdr; +} + +/** + * fit_check_fdt - verify FIT format FDT subimage + * @fit_hdr: pointer to the FIT header + * fdt_noffset: FDT subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_fdt() verifies integrity of the FDT subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined(CONFIG_FIT) +static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) +{ + fit_image_print (fit, fdt_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, fdt_noffset)) { + fdt_error ("Bad Data Hash"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) { + fdt_error ("Not a FDT image"); + return 0; + } + + if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) { + fdt_error ("FDT image is compressed"); + return 0; + } + + return 1; +} +#endif /* CONFIG_FIT */ + +#ifndef CONFIG_SYS_FDT_PAD +#define CONFIG_SYS_FDT_PAD 0x3000 +#endif + +/** + * boot_relocate_fdt - relocate flat device tree + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @bootmap_base: base address of the bootmap region + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_relocate_fdt() determines if the of_flat_tree address is within + * the bootmap and if not relocates it into that region + * + * of_flat_tree and of_size are set to final (after relocation) values + * + * returns: + * 0 - success + * 1 - failure + */ +#if defined(CONFIG_SYS_BOOTMAPSZ) +int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + char **of_flat_tree, ulong *of_size) +{ + char *fdt_blob = *of_flat_tree; + ulong relocate = 0; + ulong of_len = 0; + + /* nothing to do */ + if (*of_size == 0) + return 0; + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + +#ifndef CONFIG_SYS_NO_FLASH + /* move the blob if it is in flash (set relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + relocate = 1; +#endif + + /* + * The blob needs to be inside the boot mapping. + */ + if (fdt_blob < (char *)bootmap_base) + relocate = 1; + + if ((fdt_blob + *of_size + CONFIG_SYS_FDT_PAD) >= + ((char *)CONFIG_SYS_BOOTMAPSZ + bootmap_base)) + relocate = 1; + + /* move flattend device tree if needed */ + if (relocate) { + int err; + ulong of_start = 0; + + /* position on a 4K boundary before the alloc_current */ + /* Pad the FDT by a specified amount */ + of_len = *of_size + CONFIG_SYS_FDT_PAD; + of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, + (CONFIG_SYS_BOOTMAPSZ + bootmap_base)); + + if (of_start == 0) { + puts("device tree - allocation error\n"); + goto error; + } + + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + (ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1, + of_len, of_len); + + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); + if (err != 0) { + fdt_error ("fdt move failed"); + goto error; + } + puts ("OK\n"); + + *of_flat_tree = (char *)of_start; + *of_size = of_len; + } else { + *of_flat_tree = fdt_blob; + of_len = (CONFIG_SYS_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob; + lmb_reserve(lmb, (ulong)fdt_blob, of_len); + fdt_set_totalsize(*of_flat_tree, of_len); + + *of_size = of_len; + } + + set_working_fdt_addr(*of_flat_tree); + return 0; + +error: + return 1; +} +#endif /* CONFIG_SYS_BOOTMAPSZ */ + +/** + * boot_get_fdt - main fdt handling routine + * @argc: command argument count + * @argv: command argument list + * @images: pointer to the bootm images structure + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_get_fdt() is responsible for finding a valid flat device tree image. + * Curently supported are the following ramdisk sources: + * - multicomponent kernel/ramdisk image, + * - commandline provided address of decicated ramdisk image. + * + * returns: + * 0, if fdt image was found and valid, or skipped + * of_flat_tree and of_size are set to fdt start address and length if + * fdt image is found and valid + * + * 1, if fdt image is found but corrupted + * of_flat_tree and of_size are set to 0 if no fdt exists + */ +int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, + char **of_flat_tree, ulong *of_size) +{ + const image_header_t *fdt_hdr; + ulong fdt_addr; + char *fdt_blob = NULL; + ulong image_start, image_end; + ulong load_start, load_end; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_fdt = NULL; + ulong default_addr; + int cfg_noffset; + int fdt_noffset; + const void *data; + size_t size; +#endif + + *of_flat_tree = NULL; + *of_size = 0; + + if (argc > 3 || genimg_has_config (images)) { +#if defined(CONFIG_FIT) + if (argc > 3) { + /* + * If the FDT blob comes from the FIT image and the + * FIT image address is omitted in the command line + * argument, try to use ramdisk or os FIT image + * address or default load address. + */ + if (images->fit_uname_rd) + default_addr = (ulong)images->fit_hdr_rd; + else if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[3], default_addr, + &fdt_addr, &fit_uname_config)) { + debug ("* fdt: config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + } else if (fit_parse_subimage (argv[3], default_addr, + &fdt_addr, &fit_uname_fdt)) { + debug ("* fdt: subimage '%s' from image at 0x%08lx\n", + fit_uname_fdt, fdt_addr); + } else +#endif + { + fdt_addr = simple_strtoul(argv[3], NULL, 16); + debug ("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + fdt_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* fdt: using config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + + /* + * Check whether configuration has FDT blob defined, + * if not quit silently. + */ + fit_hdr = (void *)fdt_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (cfg_noffset < 0) { + debug ("* fdt: no such config\n"); + return 0; + } + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + if (fdt_noffset < 0) { + debug ("* fdt: no fdt in config\n"); + return 0; + } + } +#endif + + debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", + fdt_addr); + + /* copy from dataflash if needed */ + fdt_addr = genimg_get_image (fdt_addr); + + /* + * Check if there is an FDT image at the + * address provided in the second bootm argument + * check image type, for FIT images get a FIT node. + */ + switch (genimg_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + /* verify fdt_addr points to a valid image header */ + printf ("## Flattened Device Tree from Legacy Image at %08lx\n", + fdt_addr); + fdt_hdr = image_get_fdt (fdt_addr); + if (!fdt_hdr) + goto error; + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)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_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); + + memmove ((void *)load_start, + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); + + fdt_blob = (char *)load_start; + break; + case IMAGE_FORMAT_FIT: + /* + * This case will catch both: new uImage format + * (libfdt based) and raw FDT blob (also libfdt + * based). + */ +#if defined(CONFIG_FIT) + /* check FDT blob vs FIT blob */ + if (fit_check_format ((const void *)fdt_addr)) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + printf ("## Flattened Device Tree from FIT Image at %08lx\n", + fdt_addr); + + if (!fit_uname_fdt) { + /* + * no FDT blob image node unit name, + * try to get config node first. If + * config unit node name is NULL + * fit_conf_get_node() will try to + * find default config node + */ + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + + if (cfg_noffset < 0) { + fdt_error ("Could not find configuration node\n"); + goto error; + } + + fit_uname_config = fdt_get_name (fit_hdr, + cfg_noffset, NULL); + printf (" Using '%s' configuration\n", + fit_uname_config); + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + fit_uname_fdt = fit_get_name (fit_hdr, + fdt_noffset, NULL); + } else { + /* get FDT component image node offset */ + fdt_noffset = fit_image_get_node (fit_hdr, + fit_uname_fdt); + } + if (fdt_noffset < 0) { + fdt_error ("Could not find subimage node\n"); + goto error; + } + + printf (" Trying '%s' FDT blob subimage\n", + fit_uname_fdt); + + if (!fit_check_fdt (fit_hdr, fdt_noffset, + images->verify)) + goto error; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, fdt_noffset, + &data, &size)) { + fdt_error ("Could not find FDT subimage data"); + goto error; + } + + /* verift that image data is a proper FDT blob */ + if (fdt_check_header ((char *)data) != 0) { + fdt_error ("Subimage data is not a FTD"); + goto error; + } + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fit_hdr; + image_end = fit_get_end (fit_hdr); + + if (fit_image_get_load (fit_hdr, fdt_noffset, + &load_start) == 0) { + load_end = load_start + size; + + if ((load_start < image_end) && + (load_end > image_start)) { + fdt_error ("FDT overwritten"); + goto error; + } + + printf (" Loading FDT from 0x%08lx to 0x%08lx\n", + (ulong)data, load_start); + + memmove ((void *)load_start, + (void *)data, size); + + fdt_blob = (char *)load_start; + } else { + fdt_blob = (char *)data; + } + + images->fit_hdr_fdt = fit_hdr; + images->fit_uname_fdt = fit_uname_fdt; + images->fit_noffset_fdt = fdt_noffset; + break; + } else +#endif + { + /* + * FDT blob + */ + fdt_blob = (char *)fdt_addr; + debug ("* fdt: raw FDT blob\n"); + printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob); + } + break; + default: + puts ("ERROR: Did not find a cmdline Flattened Device Tree\n"); + goto error; + } + + printf (" Booting using the fdt blob at 0x%x\n", (int)fdt_blob); + + } else if (images->legacy_hdr_valid && + image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { + + ulong fdt_data, fdt_len; + + /* + * Now check if we have a legacy multi-component image, + * get second entry data start address and len. + */ + printf ("## Flattened Device Tree from multi " + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); + + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", (int)fdt_blob); + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + fdt_error ("fdt size != image size"); + goto error; + } + } else { + debug ("## No Flattened Device Tree\n"); + return 0; + } + } else { + debug ("## No Flattened Device Tree\n"); + return 0; + } + + *of_flat_tree = fdt_blob; + *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", + (ulong)*of_flat_tree, *of_size); + + return 0; + +error: + *of_flat_tree = 0; + *of_size = 0; + return 1; +} +#endif /* CONFIG_OF_LIBFDT */ +#endif /* !USE_HOSTCC */ + +#if defined(CONFIG_FIT) +/*****************************************************************************/ +/* New uImage format routines */ +/*****************************************************************************/ +#ifndef USE_HOSTCC +static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, + ulong *addr, const char **name) +{ + const char *sep; + + *addr = addr_curr; + *name = NULL; + + sep = strchr (spec, sepc); + if (sep) { + if (sep - spec > 0) + *addr = simple_strtoul (spec, NULL, 16); + + *name = sep + 1; + return 1; + } + + return 0; +} + +/** + * fit_parse_conf - parse FIT configuration spec + * @spec: input string, containing configuration spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * configuration + * @conf_name double pointer to a char, will hold pointer to a configuration + * unit name + * + * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, + * where <addr> is a FIT image address that contains configuration + * with a <conf> unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid configuration string, + * addr and conf_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name) +{ + return fit_parse_spec (spec, '#', addr_curr, addr, conf_name); +} + +/** + * fit_parse_subimage - parse FIT subimage spec + * @spec: input string, containing subimage spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * subimage + * @image_name: double pointer to a char, will hold pointer to a subimage name + * + * fit_parse_subimage() expects subimage spec in the for of + * [<addr>]:<subimage>, where <addr> is a FIT image address that contains + * subimage with a <subimg> unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid subimage string, + * addr and image_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name) +{ + return fit_parse_spec (spec, ':', addr_curr, addr, image_name); +} +#endif /* !USE_HOSTCC */ + +static void fit_get_debug (const void *fit, int noffset, + char *prop_name, int err) +{ + debug ("Can't get '%s' property from FIT 0x%08lx, " + "node: offset %d, name %s (%s)\n", + prop_name, (ulong)fit, noffset, + fit_get_name (fit, noffset, NULL), + fdt_strerror (err)); +} + +/** + * fit_print_contents - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * fit_print_contents() formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) follwed by + * the details of each component image. + * + * returns: + * no returned results + */ +void fit_print_contents (const void *fit) +{ + char *desc; + char *uname; + int images_noffset; + int confs_noffset; + int noffset; + int ndepth; + int count = 0; + int ret; + const char *p; +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + time_t timestamp; +#endif + +#ifdef USE_HOSTCC + p = ""; +#else + p = " "; +#endif + + /* Root node properties */ + ret = fit_get_desc (fit, 0, &desc); + printf ("%sFIT description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + ret = fit_get_timestamp (fit, 0, ×tamp); + printf ("%sCreated: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_time (timestamp); +#endif + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf ("%s Image %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_image_print (fit, noffset, p); + } + } + + /* Find configurations parent node offset */ + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't get configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return; + } + + /* get default configuration unit name from default property */ + uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL); + if (uname) + printf ("%s Default Configuration: '%s'\n", p, uname); + + /* Process its subnodes, print out configurations details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the configurations parent node, + * i.e. configuration node. + */ + printf ("%s Configuration %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_conf_print (fit, noffset, p); + } + } +} + +/** + * fit_image_print - prints out the FIT component image details + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properies for the processed component + * image. If present, hash nodes are printed out as well. Load + * address for images of type firmware is also printed out. Since the load + * address is not mandatory for firmware images, it will be output as + * "unavailable" when not present. + * + * returns: + * no returned results + */ +void fit_image_print (const void *fit, int image_noffset, const char *p) +{ + char *desc; + uint8_t type, arch, os, comp; + size_t size; + ulong load, entry; + const void *data; + int noffset; + int ndepth; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, image_noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + fit_image_get_type (fit, image_noffset, &type); + printf ("%s Type: %s\n", p, genimg_get_type_name (type)); + + fit_image_get_comp (fit, image_noffset, &comp); + printf ("%s Compression: %s\n", p, genimg_get_comp_name (comp)); + + ret = fit_image_get_data (fit, image_noffset, &data, &size); + +#ifndef USE_HOSTCC + printf ("%s Data Start: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", (ulong)data); +#endif + + printf ("%s Data Size: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_size (size); + + /* Remaining, type dependent properties */ + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || + (type == IH_TYPE_FLATDT)) { + fit_image_get_arch (fit, image_noffset, &arch); + printf ("%s Architecture: %s\n", p, genimg_get_arch_name (arch)); + } + + if (type == IH_TYPE_KERNEL) { + fit_image_get_os (fit, image_noffset, &os); + printf ("%s OS: %s\n", p, genimg_get_os_name (os)); + } + + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_FIRMWARE)) { + ret = fit_image_get_load (fit, image_noffset, &load); + printf ("%s Load Address: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", load); + } + + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) { + fit_image_get_entry (fit, image_noffset, &entry); + printf ("%s Entry Point: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", entry); + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + fit_image_print_hash (fit, noffset, p); + } + } +} + +/** + * fit_image_print_hash - prints out the hash node details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash node + * @p: pointer to prefix string + * + * fit_image_print_hash() lists properies for the processed hash node + * + * returns: + * no returned results + */ +void fit_image_print_hash (const void *fit, int noffset, const char *p) +{ + char *algo; + uint8_t *value; + int value_len; + int i, ret; + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + return; + + debug ("%s Hash node: '%s'\n", p, + fit_get_name (fit, noffset, NULL)); + + printf ("%s Hash algo: ", p); + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("invalid/unsupported\n"); + return; + } + printf ("%s\n", algo); + + ret = fit_image_hash_get_value (fit, noffset, &value, + &value_len); + printf ("%s Hash value: ", p); + if (ret) { + printf ("unavailable\n"); + } else { + for (i = 0; i < value_len; i++) + printf ("%02x", value[i]); + printf ("\n"); + } + + debug ("%s Hash len: %d\n", p, value_len); +} + +/** + * fit_get_desc - get node description property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @desc: double pointer to the char, will hold pointer to the descrption + * + * fit_get_desc() reads description property from a given node, if + * description is found pointer to it is returened in third call argument. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_get_desc (const void *fit, int noffset, char **desc) +{ + int len; + + *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len); + if (*desc == NULL) { + fit_get_debug (fit, noffset, FIT_DESC_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_get_timestamp - get node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: pointer to the time_t, will hold read timestamp + * + * fit_get_timestamp() reads timestamp poperty from given node, if timestamp + * is found and has a correct size its value is retured in third call + * argument. + * + * returns: + * 0, on success + * -1, on property read failure + * -2, on wrong timestamp size + */ +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp) +{ + int len; + const void *data; + + data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len); + return -1; + } + if (len != sizeof (uint32_t)) { + debug ("FIT timestamp with incorrect size of (%u)\n", len); + return -2; + } + + *timestamp = uimage_to_cpu (*((uint32_t *)data)); + return 0; +} + +/** + * fit_image_get_node - get node offset for component image of a given unit name + * @fit: pointer to the FIT format image header + * @image_uname: component image node unit name + * + * fit_image_get_node() finds a component image (withing the '/images' + * node) of a provided unit name. If image is found its node offset is + * returned to the caller. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_image_get_node (const void *fit, const char *image_uname) +{ + int noffset, images_noffset; + + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + debug ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + noffset = fdt_subnode_offset (fit, images_noffset, image_uname); + if (noffset < 0) { + debug ("Can't get node offset for image unit name: '%s' (%s)\n", + image_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +/** + * fit_image_get_os - get os id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: pointer to the uint8_t, will hold os numeric id + * + * fit_image_get_os() finds os property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_os (const void *fit, int noffset, uint8_t *os) +{ + int len; + const void *data; + + /* Get OS name from property data */ + data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_OS_PROP, len); + *os = -1; + return -1; + } + + /* Translate OS name to id */ + *os = genimg_get_os_id (data); + return 0; +} + +/** + * fit_image_get_arch - get arch id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: pointer to the uint8_t, will hold arch numeric id + * + * fit_image_get_arch() finds arch property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch) +{ + int len; + const void *data; + + /* Get architecture name from property data */ + data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ARCH_PROP, len); + *arch = -1; + return -1; + } + + /* Translate architecture name to id */ + *arch = genimg_get_arch_id (data); + return 0; +} + +/** + * fit_image_get_type - get type id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: pointer to the uint8_t, will hold type numeric id + * + * fit_image_get_type() finds type property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_type (const void *fit, int noffset, uint8_t *type) +{ + int len; + const void *data; + + /* Get image type name from property data */ + data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TYPE_PROP, len); + *type = -1; + return -1; + } + + /* Translate image type name to id */ + *type = genimg_get_type_id (data); + return 0; +} + +/** + * fit_image_get_comp - get comp id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: pointer to the uint8_t, will hold comp numeric id + * + * fit_image_get_comp() finds comp property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp) +{ + int len; + const void *data; + + /* Get compression name from property data */ + data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_COMP_PROP, len); + *comp = -1; + return -1; + } + + /* Translate compression name to id */ + *comp = genimg_get_comp_id (data); + return 0; +} + +/** + * fit_image_get_load - get load address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @load: pointer to the uint32_t, will hold load address + * + * fit_image_get_load() finds load address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_load (const void *fit, int noffset, ulong *load) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_LOAD_PROP, len); + return -1; + } + + *load = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_entry - get entry point address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @entry: pointer to the uint32_t, will hold entry point address + * + * fit_image_get_entry() finds entry point address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_entry (const void *fit, int noffset, ulong *entry) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len); + return -1; + } + + *entry = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_data - get data property and its size for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @data: double pointer to void, will hold data property's data address + * @size: pointer to size_t, will hold data property's data size + * + * fit_image_get_data() finds data property in a given component image node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size) +{ + int len; + + *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len); + if (*data == NULL) { + fit_get_debug (fit, noffset, FIT_DATA_PROP, len); + *size = 0; + return -1; + } + + *size = len; + return 0; +} + +/** + * fit_image_hash_get_algo - get hash algorithm name + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @algo: double pointer to char, will hold pointer to the algorithm name + * + * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. + * If the property is found its data start address is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo) +{ + int len; + + *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len); + if (*algo == NULL) { + fit_get_debug (fit, noffset, FIT_ALGO_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_image_hash_get_value - get hash value and length + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: double pointer to uint8_t, will hold address of a hash value data + * @value_len: pointer to an int, will hold hash data length + * + * fit_image_hash_get_value() finds hash value property in a given hash node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len) +{ + int len; + + *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len); + if (*value == NULL) { + fit_get_debug (fit, noffset, FIT_VALUE_PROP, len); + *value_len = 0; + return -1; + } + + *value_len = len; + return 0; +} + +/** + * fit_set_timestamp - set node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: timestamp value to be set + * + * fit_set_timestamp() attempts to set timestamp property in the requested + * node and returns operation status to the caller. + * + * returns: + * 0, on success + * -1, on property read failure + */ +int fit_set_timestamp (void *fit, int noffset, time_t timestamp) +{ + uint32_t t; + int ret; + + t = cpu_to_uimage (timestamp); + ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t, + sizeof (uint32_t)); + if (ret) { + printf ("Can't set '%s' property for '%s' node (%s)\n", + FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} + +/** + * calculate_hash - calculate and return hash for provided input data + * @data: pointer to the input data + * @data_len: data length + * @algo: requested hash algorithm + * @value: pointer to the char, will hold hash value data (caller must + * allocate enough free space) + * value_len: length of the calculated hash + * + * calculate_hash() computes input data hash according to the requested algorithm. + * Resulting hash value is placed in caller provided 'value' buffer, length + * of the calculated hash is returned via value_len pointer argument. + * + * returns: + * 0, on success + * -1, when algo is unsupported + */ +static int calculate_hash (const void *data, int data_len, const char *algo, + uint8_t *value, int *value_len) +{ + if (strcmp (algo, "crc32") == 0 ) { + *((uint32_t *)value) = crc32_wd (0, data, data_len, + CHUNKSZ_CRC32); + *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value)); + *value_len = 4; + } else if (strcmp (algo, "sha1") == 0 ) { + sha1_csum_wd ((unsigned char *) data, data_len, + (unsigned char *) value, CHUNKSZ_SHA1); + *value_len = 20; + } else if (strcmp (algo, "md5") == 0 ) { + md5_wd ((unsigned char *)data, data_len, value, CHUNKSZ_MD5); + *value_len = 16; + } else { + debug ("Unsupported hash alogrithm\n"); + return -1; + } + return 0; +} + +#ifdef USE_HOSTCC +/** + * fit_set_hashes - process FIT component image nodes and calculate hashes + * @fit: pointer to the FIT format image header + * + * fit_set_hashes() adds hash values for all component images in the FIT blob. + * Hashes are calculated for all component images which have hash subnodes + * with algorithm property set to one of the supported hash algorithms. + * + * returns + * 0, on success + * libfdt error code, on failure + */ +int fit_set_hashes (void *fit) +{ + int images_noffset; + int noffset; + int ndepth; + int ret; + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + ret = fit_image_set_hashes (fit, noffset); + if (ret) + return ret; + } + } + + return 0; +} + +/** + * fit_image_set_hashes - calculate/set hashes for given component image node + * @fit: pointer to the FIT format image header + * @image_noffset: requested component image node + * + * fit_image_set_hashes() adds hash values for an component image node. All + * existing hash subnodes are checked, if algorithm property is set to one of + * the supported hash algorithms, hash value is computed and corresponding + * hash node property is set, for example: + * + * Input component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * + * Output component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * |- value = sha1(data) + * + * returns: + * 0 on sucess + * <0 on failure + */ +int fit_image_set_hashes (void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return -1; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) { + /* Not a hash subnode, skip it */ + continue; + } + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("Can't get hash algo property for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + printf ("Unsupported hash algorithm (%s) for " + "'%s' hash node in '%s' image node\n", + algo, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (fit_image_hash_set_value (fit, noffset, value, + value_len)) { + printf ("Can't set hash value for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + } + } + + return 0; +} + +/** + * fit_image_hash_set_value - set hash value in requested has node + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: hash value to be set + * @value_len: hash value length + * + * fit_image_hash_set_value() attempts to set hash value in a node at offset + * given and returns operation status to the caller. + * + * returns + * 0, on success + * -1, on failure + */ +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len) +{ + int ret; + + ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len); + if (ret) { + printf ("Can't set hash '%s' property for '%s' node (%s)\n", + FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} +#endif /* USE_HOSTCC */ + +/** + * fit_image_check_hashes - verify data intergity + * @fit: pointer to the FIT format image header + * @image_noffset: component image node offset + * + * fit_image_check_hashes() goes over component image hash nodes, + * re-calculates each data hash and compares with the value stored in hash + * node. + * + * returns: + * 1, if all hashes are valid + * 0, otherwise (or on error) + */ +int fit_image_check_hashes (const void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t *fit_value; + int fit_value_len; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + char *err_msg = ""; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return 0; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + continue; + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + err_msg = " error!\nCan't get hash algo " + "property"; + goto error; + } + printf ("%s", algo); + + if (fit_image_hash_get_value (fit, noffset, &fit_value, + &fit_value_len)) { + err_msg = " error!\nCan't get hash value " + "property"; + goto error; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + err_msg = " error!\nUnsupported hash algorithm"; + goto error; + } + + if (value_len != fit_value_len) { + err_msg = " error !\nBad hash value len"; + goto error; + } else if (memcmp (value, fit_value, value_len) != 0) { + err_msg = " error!\nBad hash value"; + goto error; + } + printf ("+ "); + } + } + + return 1; + +error: + printf ("%s for '%s' hash node in '%s' image node\n", + err_msg, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return 0; +} + +/** + * fit_all_image_check_hashes - verify data intergity for all images + * @fit: pointer to the FIT format image header + * + * fit_all_image_check_hashes() goes over all images in the FIT and + * for every images checks if all it's hashes are valid. + * + * returns: + * 1, if all hashes of all images are valid + * 0, otherwise (or on error) + */ +int fit_all_image_check_hashes (const void *fit) +{ + int images_noffset; + int noffset; + int ndepth; + int count; + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return 0; + } + + /* Process all image subnodes, check hashes for each */ + printf ("## Checking hash(es) for FIT Image at %08lx ...\n", + (ulong)fit); + for (ndepth = 0, count = 0, + noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf (" Hash(es) for Image %u (%s): ", count++, + fit_get_name (fit, noffset, NULL)); + + if (!fit_image_check_hashes (fit, noffset)) + return 0; + printf ("\n"); + } + } + return 1; +} + +/** + * fit_image_check_os - check whether image node is of a given os type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: requested image os + * + * fit_image_check_os() reads image os property and compares its numeric + * id with the requested os. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given os type + * 0 otherwise (or on error) + */ +int fit_image_check_os (const void *fit, int noffset, uint8_t os) +{ + uint8_t image_os; + + if (fit_image_get_os (fit, noffset, &image_os)) + return 0; + return (os == image_os); +} + +/** + * fit_image_check_arch - check whether image node is of a given arch + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: requested imagearch + * + * fit_image_check_arch() reads image arch property and compares its numeric + * id with the requested arch. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given arch + * 0 otherwise (or on error) + */ +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch) +{ + uint8_t image_arch; + + if (fit_image_get_arch (fit, noffset, &image_arch)) + return 0; + return (arch == image_arch); +} + +/** + * fit_image_check_type - check whether image node is of a given type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: requested image type + * + * fit_image_check_type() reads image type property and compares its numeric + * id with the requested type. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given type + * 0 otherwise (or on error) + */ +int fit_image_check_type (const void *fit, int noffset, uint8_t type) +{ + uint8_t image_type; + + if (fit_image_get_type (fit, noffset, &image_type)) + return 0; + return (type == image_type); +} + +/** + * fit_image_check_comp - check whether image node uses given compression + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: requested image compression type + * + * fit_image_check_comp() reads image compression property and compares its + * numeric id with the requested compression type. Comparison result is + * returned to the caller. + * + * returns: + * 1 if image uses requested compression + * 0 otherwise (or on error) + */ +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp) +{ + uint8_t image_comp; + + if (fit_image_get_comp (fit, noffset, &image_comp)) + return 0; + return (comp == image_comp); +} + +/** + * fit_check_format - sanity check FIT image format + * @fit: pointer to the FIT format image header + * + * fit_check_format() runs a basic sanity FIT image verification. + * Routine checks for mandatory properties, nodes, etc. + * + * returns: + * 1, on success + * 0, on failure + */ +int fit_check_format (const void *fit) +{ + /* mandatory / node 'description' property */ + if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no description\n"); + return 0; + } + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + /* mandatory / node 'timestamp' property */ + if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no timestamp\n"); + return 0; + } +#endif + + /* mandatory subimages parent '/images' node */ + if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) { + debug ("Wrong FIT format: no images parent node\n"); + return 0; + } + + return 1; +} + +/** + * fit_conf_get_node - get node offset for configuration of a given unit name + * @fit: pointer to the FIT format image header + * @conf_uname: configuration node unit name + * + * fit_conf_get_node() finds a configuration (withing the '/configurations' + * parant node) of a provided unit name. If configuration is found its node offset + * is returned to the caller. + * + * When NULL is provided in second argument fit_conf_get_node() will search + * for a default configuration node instead. Default configuration node unit name + * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node. + * + * returns: + * configuration node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_node (const void *fit, const char *conf_uname) +{ + int noffset, confs_noffset; + int len; + + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't find configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return confs_noffset; + } + + if (conf_uname == NULL) { + /* get configuration unit name from the default property */ + debug ("No configuration specified, trying default...\n"); + conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len); + if (conf_uname == NULL) { + fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len); + return len; + } + debug ("Found default configuration: '%s'\n", conf_uname); + } + + noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname); + if (noffset < 0) { + debug ("Can't get node offset for configuration unit name: '%s' (%s)\n", + conf_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +static int __fit_conf_get_prop_node (const void *fit, int noffset, + const char *prop_name) +{ + char *uname; + int len; + + /* get kernel image unit name from configuration kernel property */ + uname = (char *)fdt_getprop (fit, noffset, prop_name, &len); + if (uname == NULL) + return len; + + return fit_image_get_node (fit, uname); +} + +/** + * fit_conf_get_kernel_node - get kernel image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_kernel_node() retrives kernel image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_kernel_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP); +} + +/** + * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_ramdisk_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP); +} + +/** + * fit_conf_get_fdt_node - get fdt image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_fdt_node() retrives fdt image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_fdt_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP); +} + +/** + * fit_conf_print - prints out the FIT configuration details + * @fit: pointer to the FIT format image header + * @noffset: offset of the configuration node + * @p: pointer to prefix string + * + * fit_conf_print() lists all mandatory properies for the processed + * configuration node. + * + * returns: + * no returned results + */ +void fit_conf_print (const void *fit, int noffset, const char *p) +{ + char *desc; + char *uname; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL); + printf ("%s Kernel: ", p); + if (uname == NULL) + printf ("unavailable\n"); + else + printf ("%s\n", uname); + + /* Optional properties */ + uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL); + if (uname) + printf ("%s Init Ramdisk: %s\n", p, uname); + + uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL); + if (uname) + printf ("%s FDT: %s\n", p, uname); +} + +/** + * fit_check_ramdisk - verify FIT format ramdisk subimage + * @fit_hdr: pointer to the FIT ramdisk header + * @rd_noffset: ramdisk subimage node offset within FIT image + * @arch: requested ramdisk image architecture type + * @verify: data CRC verification flag + * + * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#ifndef USE_HOSTCC +static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify) +{ + fit_image_print (fit, rd_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, rd_noffset)) { + puts ("Bad Data Hash\n"); + show_boot_progress (-125); + return 0; + } + puts ("OK\n"); + } + + show_boot_progress (126); + 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); + return 0; + } + + show_boot_progress (127); + return 1; +} +#endif /* USE_HOSTCC */ +#endif /* CONFIG_FIT */
diff --git a/x-loader/common/main.c b/x-loader/common/main.c new file mode 100644 index 0000000..35a788e --- /dev/null +++ b/x-loader/common/main.c
@@ -0,0 +1,35 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Add to readline cmdline-editing by + * (C) Copyright 2005 + * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.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 + */ + +/* #define DEBUG */ + +#include <common.h> +/* + * Board-specific Platform code can reimplement show_boot_progress () if needed + */ +void inline __show_boot_progress (int val) {} +void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
diff --git a/x-loader/config.mk b/x-loader/config.mk new file mode 100644 index 0000000..f580c61 --- /dev/null +++ b/x-loader/config.mk
@@ -0,0 +1,254 @@ +# +# (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 +# + +######################################################################### + +ifneq ($(OBJTREE),$(SRCTREE)) +ifeq ($(CURDIR),$(SRCTREE)) +dir := +else +dir := $(subst $(SRCTREE)/,,$(CURDIR)) +endif + +obj := $(if $(dir),$(OBJTREE)/$(dir)/,$(OBJTREE)/) +src := $(if $(dir),$(SRCTREE)/$(dir)/,$(SRCTREE)/) + +$(shell mkdir -p $(obj)) +else +obj := +src := +endif + +# clean the slate ... +PLATFORM_RELFLAGS = +PLATFORM_CPPFLAGS = +PLATFORM_LDFLAGS = + +######################################################################### + +HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \ + $(HOSTCPPFLAGS) +HOSTSTRIP = strip + +# +# Mac OS X / Darwin's C preprocessor is Apple specific. It +# generates numerous errors and warnings. We want to bypass it +# and use GNU C's cpp. To do this we pass the -traditional-cpp +# option to the compiler. Note that the -traditional-cpp flag +# DOES NOT have the same semantics as GNU C's flag, all it does +# is invoke the GNU preprocessor in stock ANSI/ISO C fashion. +# +# Apple's linker is similar, thanks to the new 2 stage linking +# multiple symbol definitions are treated as errors, hence the +# -multiply_defined suppress option to turn off this error. +# + +ifeq ($(HOSTOS),darwin) +# get major and minor product version (e.g. '10' and '6' for Snow Leopard) +DARWIN_MAJOR_VERSION = $(shell sw_vers -productVersion | cut -f 1 -d '.') +DARWIN_MINOR_VERSION = $(shell sw_vers -productVersion | cut -f 2 -d '.') + +os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \ + $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) + +# Snow Leopards build environment has no longer restrictions as described above +HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc") +HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp") +HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress") +else +HOSTCC = gcc +endif + +ifeq ($(HOSTOS),cygwin) +HOSTCFLAGS += -ansi +endif + +# We build some files with extra pedantic flags to try to minimize things +# that won't build on some weird host compiler -- though there are lots of +# exceptions for files that aren't complaint. + +HOSTCFLAGS_NOPED = $(filter-out -pedantic,$(HOSTCFLAGS)) +HOSTCFLAGS += -pedantic + +######################################################################### +# +# Option checker (courtesy linux kernel) to ensure +# only supported compiler options are used +# +cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) + +# +# Include the make variables (CC, etc...) +# +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +RANLIB = $(CROSS_COMPILE)RANLIB + +######################################################################### + +# Load generated board configuration +sinclude $(OBJTREE)/include/autoconf.mk + +# Some architecture config.mk files need to know what CPUDIR is set to, +# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files. +# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains +# CPU-specific code. +CPUDIR=cpu/$(CPU) +ifneq ($(SRCTREE)/$(CPUDIR),$(wildcard $(SRCTREE)/$(CPUDIR))) +CPUDIR=cpu +endif + +sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules +sinclude $(TOPDIR)/$(CPUDIR)/config.mk # include CPU specific rules + +ifdef SOC +sinclude $(TOPDIR)/$(CPUDIR)/$(SOC)/config.mk # include SoC specific rules +endif +ifdef VENDOR +BOARDDIR = $(VENDOR)/$(BOARD) +else +BOARDDIR = $(BOARD) +endif +ifdef BOARD +sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules +endif + +######################################################################### + +ifneq (,$(findstring s,$(MAKEFLAGS))) +ARFLAGS = cr +else +ARFLAGS = crv +endif +RELFLAGS= $(PLATFORM_RELFLAGS) +DBGFLAGS= -g # -DDEBUG +OPTFLAGS= -Os #-fomit-frame-pointer +ifndef LDSCRIPT +#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/x-load.lds.debug +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/x-load.lds +endif +OBJCFLAGS += --gap-fill=0xff + +gccincdir := $(shell $(CC) -print-file-name=include) + +CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ + -D__KERNEL__ +ifneq ($(TEXT_BASE),) +CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) +endif + +ifneq ($(STACK_BASE),) +CPPFLAGS += -DSTACK_BASE=$(STACK_BASE) +endif + +ifneq ($(RESET_VECTOR_ADDRESS),) +CPPFLAGS += -DRESET_VECTOR_ADDRESS=$(RESET_VECTOR_ADDRESS) +endif + +ifneq ($(OBJTREE),$(SRCTREE)) +CPPFLAGS += -I$(OBJTREE)/include2 -I$(OBJTREE)/include +endif + +CPPFLAGS += -I$(TOPDIR)/include +CPPFLAGS += -fno-builtin -ffreestanding -nostdinc \ + -isystem $(gccincdir) -pipe $(PLATFORM_CPPFLAGS) + +ifdef BUILD_TAG +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes \ + -DBUILD_TAG='"$(BUILD_TAG)"' +else +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes +endif + +CFLAGS += $(call cc-option,-fno-stack-protector) + +# $(CPPFLAGS) sets -g, which causes gcc to pass a suitable -g<format> +# option to the assembler. +AFLAGS_DEBUG := + +AFLAGS_DEBUG := -Wa,-gstabs +AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS) + +LDFLAGS += -Bstatic -T $(obj)x-load.lds $(PLATFORM_LDFLAGS) +ifneq ($(TEXT_BASE),) +LDFLAGS += -Ttext $(TEXT_BASE) +endif + +# Location of a usable BFD library, where we define "usable" as +# "built for ${HOST}, supports ${TARGET}". Sensible values are +# - When cross-compiling: the root of the cross-environment +# - Linux/ppc (native): /usr +# - NetBSD/ppc (native): you lose ... (must extract these from the +# binutils build directory, plus the native and U-Boot include +# files don't like each other) +# +# So far, this is used only by tools/gdb/Makefile. + +ifeq ($(HOSTOS),darwin) +BFD_ROOT_DIR = /usr/local/tools +else +ifeq ($(HOSTARCH),$(ARCH)) +# native +BFD_ROOT_DIR = /usr +else +#BFD_ROOT_DIR = /LinuxPPC/CDK # Linux/i386 +#BFD_ROOT_DIR = /usr/pkg/cross # NetBSD/i386 +BFD_ROOT_DIR = /opt/powerpc +endif +endif + +######################################################################### + +export HOSTCC HOSTCFLAGS HOSTLDFLAGS PEDCFLAGS HOSTSTRIP CROSS_COMPILE \ + AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE +export TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS + +######################################################################### + +# Allow boards to use custom optimize flags on a per dir/file basis +BCURDIR = $(subst $(SRCTREE)/,,$(CURDIR:$(obj)%=%)) +$(obj)%.s: %.S + $(CPP) $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR)) \ + -o $@ $< +$(obj)%.o: %.S + $(CC) $(AFLAGS) $(AFLAGS_$(BCURDIR)/$(@F)) $(AFLAGS_$(BCURDIR)) \ + -o $@ $< -c +$(obj)%.o: %.c + $(CC) $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR)) \ + -o $@ $< -c +$(obj)%.i: %.c + $(CPP) $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR)) \ + -o $@ $< -c +$(obj)%.s: %.c + $(CC) $(CFLAGS) $(CFLAGS_$(BCURDIR)/$(@F)) $(CFLAGS_$(BCURDIR)) \ + -o $@ $< -c -S + +#########################################################################
diff --git a/x-loader/cpu/arm1136/Makefile b/x-loader/cpu/arm1136/Makefile new file mode 100644 index 0000000..e2a34ac --- /dev/null +++ b/x-loader/cpu/arm1136/Makefile
@@ -0,0 +1,43 @@ +# +# (C) Copyright 2000-2003 +# 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$(CPU).a + +START = start.o +OBJS = cpu.o + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/cpu/arm1136/config.mk b/x-loader/cpu/arm1136/config.mk new file mode 100644 index 0000000..3106824 --- /dev/null +++ b/x-loader/cpu/arm1136/config.mk
@@ -0,0 +1,33 @@ +# +# (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 +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 + +PLATFORM_CPPFLAGS += -march=armv5 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) +#
diff --git a/x-loader/cpu/arm1136/cpu.c b/x-loader/cpu/arm1136/cpu.c new file mode 100644 index 0000000..1168fb9 --- /dev/null +++ b/x-loader/cpu/arm1136/cpu.c
@@ -0,0 +1,65 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * + * 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 + */ + +/* + * udelay() is CPU specific code + */ + +#include <common.h> + +/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ +#define C1_WB (1<<3) /* merging write buffer on/off */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ + +int cpu_init (void) +{ + int i; + + /* turn off I/D-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~(C1_DC | C1_IC); + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I/D-cache */ + i = 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); // invalidate both caches and flush btb + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); // mem barrier to sync things + + return 0; +} + + + + + + + +
diff --git a/x-loader/cpu/arm1136/start.S b/x-loader/cpu/arm1136/start.S new file mode 100644 index 0000000..16108d0 --- /dev/null +++ b/x-loader/cpu/arm1136/start.S
@@ -0,0 +1,218 @@ +/* + * armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + * Copyright (c) 2004 Texas Instruments + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2004 Jian Zhang <jzhang@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> + +.globl _start +_start: + b reset + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + +_hang: + .word do_hang + + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 /* now 16*4=64 */ + +.global _end_vect +_end_vect: + + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start /* r0 <- current position of code */ + add r0, r0, #4 /* skip reset vector */ + mov r2, #64 /* r2 <- size to copy */ + add r2, r0, r2 /* r2 <- source end address */ + mov r1, #0x40000000 /* build vect addr */ + mov r3, #0x00200000 + add r1, r1, r3 + mov r3, #0xf800 + add r1, r1, r3 +next: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next /* loop until equal */ + + bl cpy_clk_code /* put dpll adjust code behind vectors */ + + /* the mask ROM code should have PLL and others stable */ + bl cpu_init_crit + +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + /* beq stack_setup */ + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub sp, r0, #128 /* leave 32 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +//clbss_l:str r2, [r0] /* clear loop... */ +// add r0, r0, #4 +// cmp r0, r1 +// bne clbss_l + + ldr pc, _start_armboot + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align +#ifndef CONFIG_ICACHE_OFF + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache +#endif + mcr p15, 0, r0, c1, c0, 0 + + /* + * Jump to board specific initialization... The Mask ROM will have already initialized + * basic memory. Go here to bump up clock rate and handle wake up conditions. + */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* pass on info about skipping some init portions */ + moveq r0,#0x1 /* flag to skip prcm and sdrc setup */ + movne r0,#0x0 + +//mov r0, #1 /* this skip memory init */ + + mov ip, lr /* persevere link reg across call */ + bl platformsetup /* go setup pll,mux,memory */ + + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ + + +/* + * exception handler + */ + .align 5 +do_hang: + ldr sp, _TEXT_BASE /* use 32 words abort stack */ + bl hang /* hang and never return */ +
diff --git a/x-loader/cpu/arm926ejs/Makefile b/x-loader/cpu/arm926ejs/Makefile new file mode 100644 index 0000000..883c3d0 --- /dev/null +++ b/x-loader/cpu/arm926ejs/Makefile
@@ -0,0 +1,43 @@ +# +# (C) Copyright 2000-2003 +# 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$(CPU).a + +START = start.o +OBJS = cpu.o + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/cpu/arm926ejs/config.mk b/x-loader/cpu/arm926ejs/config.mk new file mode 100644 index 0000000..f9adb10 --- /dev/null +++ b/x-loader/cpu/arm926ejs/config.mk
@@ -0,0 +1,32 @@ +# +# (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 +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 + +PLATFORM_CPPFLAGS += -march=armv5 +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) +#
diff --git a/x-loader/cpu/arm926ejs/cpu.c b/x-loader/cpu/arm926ejs/cpu.c new file mode 100644 index 0000000..972fa8a --- /dev/null +++ b/x-loader/cpu/arm926ejs/cpu.c
@@ -0,0 +1,126 @@ +/* + * (C) Copyright 2004 + * Texas Instruments <www.ti.com> + * Jian Zhang <jzhang@ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.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 + */ + +#include <common.h> + +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8)) + +static ulong timestamp; +static ulong lastdec; + +static void reset_timer_masked (void); + +/* nothing really to do with cpu, just starts up a counter. */ +int cpu_init (void) +{ + int32_t val; + + /* Start the decrementer ticking down from 0xffffffff */ + *((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; + val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT); + *((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return (0); +} + +static void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +#ifdef CFG_UDELAY + +static ulong get_timer_masked (void); +static ulong get_timer (ulong base); + +/* delay x useconds AND perserve advance timstamp value */ +void udelay (unsigned long usec) +{ + ulong tmo, tmp; + + if(usec >= 1000){ /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */ + tmo /= 1000; /* finish normalize. */ + }else{ /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CFG_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp) < tmp ) /* if setting this fordward will roll time stamp */ + reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */ + else + tmo += tmp; /* else, set advancing stamp wake up time */ + + while (get_timer_masked () < tmo)/* loop till event */ + /*NOP*/; +} + +static ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastdec >= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */ + } else { /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"...it could also roll and cause problems. + */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +static ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +#endif /* CFG_UDELAY */ +
diff --git a/x-loader/cpu/arm926ejs/start.S b/x-loader/cpu/arm926ejs/start.S new file mode 100644 index 0000000..2211dae --- /dev/null +++ b/x-loader/cpu/arm926ejs/start.S
@@ -0,0 +1,239 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2004 Jian Zhang <jzhang@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include <config.h> +#if defined(CONFIG_OMAP1610) +#include <./configs/omap1510.h> +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.globl _start +_start: + b reset + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + +_hang: + .word do_hang + + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * turn off the watchdog, unlock/diable sequence + */ + mov r1, #0xF5 + ldr r0, =WDTIM_MODE + strh r1, [r0] + mov r1, #0xA0 + strh r1, [r0] + + + /* + * 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] + + /* + * we do sys-critical inits at reboot, + */ + bl cpu_init_crit + + /* + * relocate exception vectors to SRAM where ROM code expects + */ +#ifdef CFG_BOOT_CS0 + + adr r0, _start /* r0 <- current position of code */ + add r0, r0, #4 /* skip reset vector */ + mov r2, #36 /* r2 <- size of data (8+1 words) */ + add r2, r0, r2 /* r2 <- source end address */ + mov r1, #0x20000000 +next: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + ble next + +#endif + +relocate: /* relocate X-Loader to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* don't reloc during debug */ + /*beq stack_setup*/ + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + ble copy_loop + + /* Set up the stack */ +stack_setup: + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated X-Loader */ + sub sp, r0, #128 /* leave 32 words for abort-stack */ + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + add r0, r0, #4 /* start at first byte of bss */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear */ + +clbss_l:str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + bne clbss_l + + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + mov ip, lr /* perserve link reg across call */ + bl platformsetup /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ + +/* + * exception handler + */ + .align 5 +do_hang: + ldr sp, _TEXT_BASE /* use 32 words abort stack */ + bl hang /* hang and never return */ + +
diff --git a/x-loader/cpu/omap3/Makefile b/x-loader/cpu/omap3/Makefile new file mode 100644 index 0000000..951e769 --- /dev/null +++ b/x-loader/cpu/omap3/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2003 +# 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$(CPU).a + +START := start.o +COBJS := cpu.o mmc.o + +SRCS := $(START:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/cpu/omap3/config.mk b/x-loader/cpu/omap3/config.mk new file mode 100644 index 0000000..e2f90cb --- /dev/null +++ b/x-loader/cpu/omap3/config.mk
@@ -0,0 +1,33 @@ +# +# (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 +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float + +PLATFORM_CPPFLAGS += -march=armv7-a +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/x-loader/cpu/omap3/cpu.c b/x-loader/cpu/omap3/cpu.c new file mode 100644 index 0000000..1cf422a --- /dev/null +++ b/x-loader/cpu/omap3/cpu.c
@@ -0,0 +1,51 @@ +/* + * (C) Copyright 2004-2006 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.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 + */ + +/* + * CPU specific code + */ +#include <common.h> + +/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ +#define C1_WB (1<<3) /* merging write buffer on/off */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ + +int cpu_init (void) +{ + return 0; +} +
diff --git a/x-loader/cpu/omap3/mmc.c b/x-loader/cpu/omap3/mmc.c new file mode 100755 index 0000000..365df49 --- /dev/null +++ b/x-loader/cpu/omap3/mmc.c
@@ -0,0 +1,562 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Syed Mohammed Khasim <khasim@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's version 2 of + * the License. + * + * 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 <common.h> +#include <mmc.h> +#include <part.h> + +#ifdef CFG_CMD_MMC + +#include "mmc_host_def.h" +#include "mmc_protocol.h" + +#define OMAP_MMC_MASTER_CLOCK 96000000 +extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no); + +mmc_card_data cur_card_data; +static block_dev_desc_t mmc_blk_dev; + +block_dev_desc_t *mmc_get_dev(int dev) +{ + return ((block_dev_desc_t *) &mmc_blk_dev); +} + +unsigned char mmc_board_init(void) +{ +#if defined (CONFIG_OMAP34XX) && !defined (CONFIG_AM3517EVM) + unsigned int value = 0; + + value = CONTROL_PBIAS_LITE; + CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9); + + value = CONTROL_DEV_CONF0; + CONTROL_DEV_CONF0 = value | (1 << 24); +#endif + return 1; +} + +void mmc_init_stream(void) +{ + volatile unsigned int mmc_stat; + + OMAP_HSMMC_CON |= INIT_INITSTREAM; + + OMAP_HSMMC_CMD = MMC_CMD0; + do { + mmc_stat = OMAP_HSMMC_STAT; + } while (!(mmc_stat & CC_MASK)); + + OMAP_HSMMC_STAT = CC_MASK; + + OMAP_HSMMC_CMD = MMC_CMD0; + do { + mmc_stat = OMAP_HSMMC_STAT; + } while (!(mmc_stat & CC_MASK)); + + OMAP_HSMMC_STAT = OMAP_HSMMC_STAT; + OMAP_HSMMC_CON &= ~INIT_INITSTREAM; +} + +unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div) +{ + unsigned int val; + + mmc_reg_out(OMAP_HSMMC_SYSCTL, (ICE_MASK | DTO_MASK | CEN_MASK), + (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); + + switch (iclk) { + case CLK_INITSEQ: + val = MMC_INIT_SEQ_CLK / 2; + break; + case CLK_400KHZ: + val = MMC_400kHz_CLK; + break; + case CLK_MISC: + val = clk_div; + break; + default: + return 0; + } + mmc_reg_out(OMAP_HSMMC_SYSCTL, + ICE_MASK | CLKD_MASK, (val << CLKD_OFFSET) | ICE_OSCILLATE); + + while ((OMAP_HSMMC_SYSCTL & ICS_MASK) == ICS_NOTREADY); + + + OMAP_HSMMC_SYSCTL |= CEN_ENABLE; + return 1; +} + +unsigned char mmc_init_setup(void) +{ + unsigned int reg_val; + + mmc_board_init(); + + OMAP_HSMMC_SYSCONFIG |= MMC_SOFTRESET; + while ((OMAP_HSMMC_SYSSTATUS & RESETDONE) == 0) ; + + OMAP_HSMMC_SYSCTL |= SOFTRESETALL; + while ((OMAP_HSMMC_SYSCTL & SOFTRESETALL) != 0x0) ; + + OMAP_HSMMC_HCTL = DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0; + OMAP_HSMMC_CAPA |= VS30_3V0SUP | VS18_1V8SUP; + + reg_val = OMAP_HSMMC_CON & RESERVED_MASK; + + OMAP_HSMMC_CON = CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | + CDP_ACTIVEHIGH | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | + STR_BLOCK | HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN; + + mmc_clock_config(CLK_INITSEQ, 0); + OMAP_HSMMC_HCTL |= SDBP_PWRON; + + OMAP_HSMMC_IE = 0x307f0033; + + mmc_init_stream(); + return 1; +} + +unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg, + unsigned int *response) +{ + unsigned int mmc_stat; + + while ((OMAP_HSMMC_PSTATE & DATI_MASK) == DATI_CMDDIS); + + + OMAP_HSMMC_BLK = BLEN_512BYTESLEN | NBLK_STPCNT; + OMAP_HSMMC_STAT = 0xFFFFFFFF; + OMAP_HSMMC_ARG = arg; + OMAP_HSMMC_CMD = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | + CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | + DE_DISABLE; + + while (1) { + do { + mmc_stat = OMAP_HSMMC_STAT; + } while (mmc_stat == 0); + + if ((mmc_stat & ERRI_MASK) != 0) + return (unsigned char)mmc_stat; + + + if (mmc_stat & CC_MASK) { + OMAP_HSMMC_STAT = CC_MASK; + response[0] = OMAP_HSMMC_RSP10; + if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) { + response[1] = OMAP_HSMMC_RSP32; + response[2] = OMAP_HSMMC_RSP54; + response[3] = OMAP_HSMMC_RSP76; + } + break; + } + } + return 1; +} + +unsigned char mmc_read_data(unsigned int *output_buf) +{ + unsigned int mmc_stat; + unsigned int read_count = 0; + + /* + * Start Polled Read + */ + while (1) { + do { + mmc_stat = OMAP_HSMMC_STAT; + } while (mmc_stat == 0); + + if ((mmc_stat & ERRI_MASK) != 0) + return (unsigned char)mmc_stat; + + if (mmc_stat & BRR_MASK) { + unsigned int k; + + OMAP_HSMMC_STAT |= BRR_MASK; + for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) { + *output_buf = OMAP_HSMMC_DATA; + output_buf++; + read_count += 4; + } + } + + if (mmc_stat & BWR_MASK) + OMAP_HSMMC_STAT |= BWR_MASK; + + if (mmc_stat & TC_MASK) { + OMAP_HSMMC_STAT |= TC_MASK; + break; + } + } + return 1; +} + +unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur) +{ + unsigned char err; + unsigned int argument = 0; + unsigned int ocr_value, ocr_recvd, ret_cmd41, hcs_val; + unsigned int resp[4]; + unsigned short retry_cnt = 2000; + + /* Set to Initialization Clock */ + err = mmc_clock_config(CLK_400KHZ, 0); + if (err != 1) + return err; + + mmc_card_cur->RCA = MMC_RELATIVE_CARD_ADDRESS; + argument = 0x00000000; + + ocr_value = (0x1FF << 15); + err = mmc_send_cmd(MMC_CMD0, argument, resp); + if (err != 1) + return err; + + argument = SD_CMD8_CHECK_PATTERN | SD_CMD8_2_7_3_6_V_RANGE; + err = mmc_send_cmd(MMC_SDCMD8, argument, resp); + hcs_val = (err == 1) ? + MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR : + MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE; + + argument = 0x0000 << 16; + err = mmc_send_cmd(MMC_CMD55, argument, resp); + if (err == 1) { + mmc_card_cur->card_type = SD_CARD; + ocr_value |= hcs_val; + ret_cmd41 = MMC_ACMD41; + } else { + mmc_card_cur->card_type = MMC_CARD; + ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR; + ret_cmd41 = MMC_CMD1; + OMAP_HSMMC_CON &= ~OD; + OMAP_HSMMC_CON |= OPENDRAIN; + } + + argument = ocr_value; + err = mmc_send_cmd(ret_cmd41, argument, resp); + if (err != 1) + return err; + + ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; + + while (!(ocr_recvd & (0x1 << 31)) && (retry_cnt > 0)) { + retry_cnt--; + if (mmc_card_cur->card_type == SD_CARD) { + argument = 0x0000 << 16; + err = mmc_send_cmd(MMC_CMD55, argument, resp); + } + + argument = ocr_value; + err = mmc_send_cmd(ret_cmd41, argument, resp); + if (err != 1) + return err; + ocr_recvd = ((mmc_resp_r3 *) resp)->ocr; + } + + if (!(ocr_recvd & (0x1 << 31))) + return 0; + + if (mmc_card_cur->card_type == MMC_CARD) { + if ((ocr_recvd & MMC_OCR_REG_ACCESS_MODE_MASK) == + MMC_OCR_REG_ACCESS_MODE_SECTOR) { + mmc_card_cur->mode = SECTOR_MODE; + } else { + mmc_card_cur->mode = BYTE_MODE; + } + + ocr_recvd &= ~MMC_OCR_REG_ACCESS_MODE_MASK; + } else { + if ((ocr_recvd & MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK) + == MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR) { + mmc_card_cur->mode = SECTOR_MODE; + } else { + mmc_card_cur->mode = BYTE_MODE; + } + ocr_recvd &= ~MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK; + } + + ocr_recvd &= ~(0x1 << 31); + if (!(ocr_recvd & ocr_value)) + return 0; + + err = mmc_send_cmd(MMC_CMD2, argument, resp); + if (err != 1) + return err; + + if (mmc_card_cur->card_type == MMC_CARD) { + argument = mmc_card_cur->RCA << 16; + err = mmc_send_cmd(MMC_CMD3, argument, resp); + if (err != 1) + return err; + } else { + argument = 0x00000000; + err = mmc_send_cmd(MMC_SDCMD3, argument, resp); + if (err != 1) + return err; + + mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca; + } + + OMAP_HSMMC_CON &= ~OD; + OMAP_HSMMC_CON |= NOOPENDRAIN; + return 1; +} + +unsigned char mmc_read_cardsize(mmc_card_data *mmc_dev_data, + mmc_csd_reg_t *cur_csd) +{ + mmc_extended_csd_reg_t ext_csd; + unsigned int size, count, blk_len, blk_no, card_size, argument; + unsigned char err; + unsigned int resp[4]; + + if (mmc_dev_data->mode == SECTOR_MODE) { + if (mmc_dev_data->card_type == SD_CARD) { + card_size = + (((mmc_sd2_csd_reg_t *) cur_csd)-> + c_size_lsb & MMC_SD2_CSD_C_SIZE_LSB_MASK) | + ((((mmc_sd2_csd_reg_t *) cur_csd)-> + c_size_msb & MMC_SD2_CSD_C_SIZE_MSB_MASK) + << MMC_SD2_CSD_C_SIZE_MSB_OFFSET); + mmc_dev_data->size = card_size * 1024; + if (mmc_dev_data->size == 0) + return 0; + } else { + argument = 0x00000000; + err = mmc_send_cmd(MMC_CMD8, argument, resp); + if (err != 1) + return err; + err = mmc_read_data((unsigned int *)&ext_csd); + if (err != 1) + return err; + mmc_dev_data->size = ext_csd.sectorcount; + + if (mmc_dev_data->size == 0) + mmc_dev_data->size = 8388608; + } + } else { + if (cur_csd->c_size_mult >= 8) + return 0; + + if (cur_csd->read_bl_len >= 12) + return 0; + + /* Compute size */ + count = 1 << (cur_csd->c_size_mult + 2); + card_size = (cur_csd->c_size_lsb & MMC_CSD_C_SIZE_LSB_MASK) | + ((cur_csd->c_size_msb & MMC_CSD_C_SIZE_MSB_MASK) + << MMC_CSD_C_SIZE_MSB_OFFSET); + + blk_no = (card_size + 1) * count; + blk_len = 1 << cur_csd->read_bl_len; + size = blk_no * blk_len; + + mmc_dev_data->size = size / MMCSD_SECTOR_SIZE; + if (mmc_dev_data->size == 0) + return 0; + } + return 1; +} + +unsigned char omap_mmc_read_sect(unsigned int start_sec, unsigned int num_bytes, + mmc_card_data *mmc_c, + unsigned int *output_buf) +{ + unsigned char err; + unsigned int argument; + unsigned int resp[4]; + unsigned int num_sec_val = + (num_bytes + (MMCSD_SECTOR_SIZE - 1)) / MMCSD_SECTOR_SIZE; + unsigned int sec_inc_val; + + if (num_sec_val == 0) + return 1; + + if (mmc_c->mode == SECTOR_MODE) { + argument = start_sec; + sec_inc_val = 1; + } else { + argument = start_sec * MMCSD_SECTOR_SIZE; + sec_inc_val = MMCSD_SECTOR_SIZE; + } + + while (num_sec_val) { + err = mmc_send_cmd(MMC_CMD17, argument, resp); + if (err != 1) + return err; + + + err = mmc_read_data(output_buf); + if (err != 1) + return err; + + output_buf += (MMCSD_SECTOR_SIZE / 4); + argument += sec_inc_val; + num_sec_val--; + } + return 1; +} + +unsigned char configure_mmc(mmc_card_data *mmc_card_cur) +{ + unsigned char ret_val; + unsigned int argument; + unsigned int resp[4]; + unsigned int trans_fact, trans_unit, retries = 2; + unsigned int max_dtr; + int dsor; + volatile mmc_csd_reg_t Card_CSD; + unsigned char trans_speed; + + mmc_init_setup(); + + do { + ret_val = mmc_detect_card(mmc_card_cur); + retries--; + } while ((retries > 0) && (ret_val != 1)); + + argument = mmc_card_cur->RCA << 16; + ret_val = mmc_send_cmd(MMC_CMD9, argument, resp); + if (ret_val != 1) + return ret_val; + + ((unsigned int *)&Card_CSD)[3] = resp[3]; + ((unsigned int *)&Card_CSD)[2] = resp[2]; + ((unsigned int *)&Card_CSD)[1] = resp[1]; + ((unsigned int *)&Card_CSD)[0] = resp[0]; + + if (mmc_card_cur->card_type == MMC_CARD) + mmc_card_cur->version = Card_CSD.spec_vers; + + trans_speed = Card_CSD.tran_speed; + + ret_val = mmc_send_cmd(MMC_CMD4, MMC_DSR_DEFAULT << 16, resp); + if (ret_val != 1) + return ret_val; + + trans_unit = trans_speed & MMC_CSD_TRAN_SPEED_UNIT_MASK; + trans_fact = trans_speed & MMC_CSD_TRAN_SPEED_FACTOR_MASK; + + if (trans_unit > MMC_CSD_TRAN_SPEED_UNIT_100MHZ) + return 0; + + if ((trans_fact < MMC_CSD_TRAN_SPEED_FACTOR_1_0) || + (trans_fact > MMC_CSD_TRAN_SPEED_FACTOR_8_0)) + return 0; + + trans_unit >>= 0; + trans_fact >>= 3; + + max_dtr = tran_exp[trans_unit] * tran_mant[trans_fact]; + dsor = OMAP_MMC_MASTER_CLOCK / max_dtr; + + if (dsor == 4) + dsor = 5; + if (dsor == 3) + dsor = 4; + + ret_val = mmc_clock_config(CLK_MISC, dsor); + if (ret_val != 1) + return ret_val; + + argument = mmc_card_cur->RCA << 16; + ret_val = mmc_send_cmd(MMC_CMD7_SELECT, argument, resp); + if (ret_val != 1) + return ret_val; + + /* Configure the block length to 512 bytes */ + argument = MMCSD_SECTOR_SIZE; + ret_val = mmc_send_cmd(MMC_CMD16, argument, resp); + if (ret_val != 1) + return ret_val; + + /* get the card size in sectors */ + ret_val = mmc_read_cardsize(mmc_card_cur, (mmc_csd_reg_t *)&Card_CSD); + if (ret_val != 1) + return ret_val; + + return 1; +} + +unsigned long mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst) +{ + unsigned long ret; + ret = omap_mmc_read_sect(blknr, (blkcnt * MMCSD_SECTOR_SIZE), + &cur_card_data, (unsigned int *)dst); + return ret; +} + +int mmc_init(int verbose) +{ + unsigned char ret = 0; + + ret = configure_mmc(&cur_card_data); + if (ret == 0) + return 0; + + mmc_blk_dev.if_type = IF_TYPE_MMC; + mmc_blk_dev.part_type = PART_TYPE_DOS; + mmc_blk_dev.dev = 0; + mmc_blk_dev.lun = 0; + mmc_blk_dev.type = 0; + + /* FIXME fill in the correct size (is set to 32MByte) */ + mmc_blk_dev.blksz = MMCSD_SECTOR_SIZE; + mmc_blk_dev.lba = 0x10000; + mmc_blk_dev.removable = 0; + mmc_blk_dev.block_read = mmc_bread; + + fat_register_device(&mmc_blk_dev, 1); + + return 1; +} + +int mmc_read(unsigned int src, unsigned char *dst, int size) +{ + /* + * NOT Implemented + */ + return 0; +} +int mmc_write(unsigned char *src, unsigned long dst, int size) +{ + /* + * NOT Implemented + */ + return 0; +} + +int mmc2info(unsigned int addr) +{ + /* + * NOT Implemented + */ + return 0; +} +#endif +
diff --git a/x-loader/cpu/omap3/mmc_host_def.h b/x-loader/cpu/omap3/mmc_host_def.h new file mode 100755 index 0000000..1526f91 --- /dev/null +++ b/x-loader/cpu/omap3/mmc_host_def.h
@@ -0,0 +1,164 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Syed Mohammed Khasim <khasim@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's version 2 of + * the License. + * + * 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 MMC_HOST_DEFINITIONS_H +#define MMC_HOST_DEFINITIONS_H + +/* + * OMAP HSMMC register definitions + */ +#define OMAP_HSMMC_SYSCONFIG (*(volatile unsigned int *) 0x4809C010) +#define OMAP_HSMMC_SYSSTATUS (*(volatile unsigned int *) 0x4809C014) +#define OMAP_HSMMC_CON (*(volatile unsigned int *) 0x4809C02C) +#define OMAP_HSMMC_BLK (*(volatile unsigned int *) 0x4809C104) +#define OMAP_HSMMC_ARG (*(volatile unsigned int *) 0x4809C108) +#define OMAP_HSMMC_CMD (*(volatile unsigned int *) 0x4809C10C) +#define OMAP_HSMMC_RSP10 (*(volatile unsigned int *) 0x4809C110) +#define OMAP_HSMMC_RSP32 (*(volatile unsigned int *) 0x4809C114) +#define OMAP_HSMMC_RSP54 (*(volatile unsigned int *) 0x4809C118) +#define OMAP_HSMMC_RSP76 (*(volatile unsigned int *) 0x4809C11C) +#define OMAP_HSMMC_DATA (*(volatile unsigned int *) 0x4809C120) +#define OMAP_HSMMC_PSTATE (*(volatile unsigned int *) 0x4809C124) +#define OMAP_HSMMC_HCTL (*(volatile unsigned int *) 0x4809C128) +#define OMAP_HSMMC_SYSCTL (*(volatile unsigned int *) 0x4809C12C) +#define OMAP_HSMMC_STAT (*(volatile unsigned int *) 0x4809C130) +#define OMAP_HSMMC_IE (*(volatile unsigned int *) 0x4809C134) +#define OMAP_HSMMC_CAPA (*(volatile unsigned int *) 0x4809C140) + +/* T2 Register definitions */ +#define CONTROL_DEV_CONF0 (*(volatile unsigned int *) 0x48002274) +#define CONTROL_PBIAS_LITE (*(volatile unsigned int *) 0x48002520) + +/* + * OMAP HS MMC Bit definitions + */ +#define MMC_SOFTRESET (0x1 << 1) +#define RESETDONE (0x1 << 0) +#define NOOPENDRAIN (0x0 << 0) +#define OPENDRAIN (0x1 << 0) +#define OD (0x1 << 0) +#define INIT_NOINIT (0x0 << 1) +#define INIT_INITSTREAM (0x1 << 1) +#define HR_NOHOSTRESP (0x0 << 2) +#define STR_BLOCK (0x0 << 3) +#define MODE_FUNC (0x0 << 4) +#define DW8_1_4BITMODE (0x0 << 5) +#define MIT_CTO (0x0 << 6) +#define CDP_ACTIVEHIGH (0x0 << 7) +#define WPP_ACTIVEHIGH (0x0 << 8) +#define RESERVED_MASK (0x3 << 9) +#define CTPL_MMC_SD (0x0 << 11) +#define BLEN_512BYTESLEN (0x200 << 0) +#define NBLK_STPCNT (0x0 << 16) +#define DE_DISABLE (0x0 << 0) +#define BCE_DISABLE (0x0 << 1) +#define ACEN_DISABLE (0x0 << 2) +#define DDIR_OFFSET (4) +#define DDIR_MASK (0x1 << 4) +#define DDIR_WRITE (0x0 << 4) +#define DDIR_READ (0x1 << 4) +#define MSBS_SGLEBLK (0x0 << 5) +#define RSP_TYPE_OFFSET (16) +#define RSP_TYPE_MASK (0x3 << 16) +#define RSP_TYPE_NORSP (0x0 << 16) +#define RSP_TYPE_LGHT136 (0x1 << 16) +#define RSP_TYPE_LGHT48 (0x2 << 16) +#define RSP_TYPE_LGHT48B (0x3 << 16) +#define CCCE_NOCHECK (0x0 << 19) +#define CCCE_CHECK (0x1 << 19) +#define CICE_NOCHECK (0x0 << 20) +#define CICE_CHECK (0x1 << 20) +#define DP_OFFSET (21) +#define DP_MASK (0x1 << 21) +#define DP_NO_DATA (0x0 << 21) +#define DP_DATA (0x1 << 21) +#define CMD_TYPE_NORMAL (0x0 << 22) +#define INDEX_OFFSET (24) +#define INDEX_MASK (0x3f << 24) +#define INDEX(i) (i << 24) +#define DATI_MASK (0x1 << 1) +#define DATI_CMDDIS (0x1 << 1) +#define DTW_1_BITMODE (0x0 << 1) +#define DTW_4_BITMODE (0x1 << 1) +#define SDBP_PWROFF (0x0 << 8) +#define SDBP_PWRON (0x1 << 8) +#define SDVS_1V8 (0x5 << 9) +#define SDVS_3V0 (0x6 << 9) +#define ICE_MASK (0x1 << 0) +#define ICE_STOP (0x0 << 0) +#define ICS_MASK (0x1 << 1) +#define ICS_NOTREADY (0x0 << 1) +#define ICE_OSCILLATE (0x1 << 0) +#define CEN_MASK (0x1 << 2) +#define CEN_DISABLE (0x0 << 2) +#define CEN_ENABLE (0x1 << 2) +#define CLKD_OFFSET (6) +#define CLKD_MASK (0x3FF << 6) +#define DTO_MASK (0xF << 16) +#define DTO_15THDTO (0xE << 16) +#define SOFTRESETALL (0x1 << 24) +#define CC_MASK (0x1 << 0) +#define TC_MASK (0x1 << 1) +#define BWR_MASK (0x1 << 4) +#define BRR_MASK (0x1 << 5) +#define ERRI_MASK (0x1 << 15) +#define IE_CC (0x01 << 0) +#define IE_TC (0x01 << 1) +#define IE_BWR (0x01 << 4) +#define IE_BRR (0x01 << 5) +#define IE_CTO (0x01 << 16) +#define IE_CCRC (0x01 << 17) +#define IE_CEB (0x01 << 18) +#define IE_CIE (0x01 << 19) +#define IE_DTO (0x01 << 20) +#define IE_DCRC (0x01 << 21) +#define IE_DEB (0x01 << 22) +#define IE_CERR (0x01 << 28) +#define IE_BADA (0x01 << 29) + +#define VS30_3V0SUP (1 << 25) +#define VS18_1V8SUP (1 << 26) + +/* Driver definitions */ +#define MMCSD_SECTOR_SIZE (512) +#define MMC_CARD 0 +#define SD_CARD 1 +#define BYTE_MODE 0 +#define SECTOR_MODE 1 +#define CLK_INITSEQ 0 +#define CLK_400KHZ 1 +#define CLK_MISC 2 + +typedef struct { + unsigned int card_type; + unsigned int version; + unsigned int mode; + unsigned int size; + unsigned int RCA; +} mmc_card_data; + +#define mmc_reg_out(addr, mask, val) \ + (addr) = (((addr)) & (~(mask)) ) | ( (val) & (mask)); + +#endif /* MMC_HOST_DEFINITIONS_H */
diff --git a/x-loader/cpu/omap3/mmc_protocol.h b/x-loader/cpu/omap3/mmc_protocol.h new file mode 100755 index 0000000..107eb2a --- /dev/null +++ b/x-loader/cpu/omap3/mmc_protocol.h
@@ -0,0 +1,246 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * Syed Mohammed Khasim <khasim@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's version 2 of + * the License. + * + * 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 MMC_PROTOCOL_H +#define MMC_PROTOCOL_H + +#include "mmc_host_def.h" + +/* Responses */ +#define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK) +#define RSP_TYPE_R1 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK) +#define RSP_TYPE_R1B (RSP_TYPE_LGHT48B | CCCE_CHECK | CICE_CHECK) +#define RSP_TYPE_R2 (RSP_TYPE_LGHT136 | CCCE_CHECK | CICE_NOCHECK) +#define RSP_TYPE_R3 (RSP_TYPE_LGHT48 | CCCE_NOCHECK | CICE_NOCHECK) +#define RSP_TYPE_R4 (RSP_TYPE_LGHT48 | CCCE_NOCHECK | CICE_NOCHECK) +#define RSP_TYPE_R5 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK) +#define RSP_TYPE_R6 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK) +#define RSP_TYPE_R7 (RSP_TYPE_LGHT48 | CCCE_CHECK | CICE_CHECK) + +/* All supported commands */ +#define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD1 (INDEX(1) | RSP_TYPE_R3 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD2 (INDEX(2) | RSP_TYPE_R2 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD3 (INDEX(3) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE) +#define MMC_SDCMD3 (INDEX(3) | RSP_TYPE_R6 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD4 (INDEX(4) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD6 (INDEX(6) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD7_SELECT (INDEX(7) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD7_DESELECT \ + (INDEX(7) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD8 (INDEX(8) | RSP_TYPE_R1 | DP_DATA | DDIR_READ) +#define MMC_SDCMD8 (INDEX(8) | RSP_TYPE_R7 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD9 (INDEX(9) | RSP_TYPE_R2 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD12 (INDEX(12) | RSP_TYPE_R1B | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD13 (INDEX(13) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD15 (INDEX(15) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD16 (INDEX(16) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE) +#define MMC_CMD17 (INDEX(17) | RSP_TYPE_R1 | DP_DATA | DDIR_READ) +#define MMC_CMD24 (INDEX(24) | RSP_TYPE_R1 | DP_DATA | DDIR_WRITE) +#define MMC_ACMD6 (INDEX(6) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE) +#define MMC_ACMD41 (INDEX(41) | RSP_TYPE_R3 | DP_NO_DATA | DDIR_WRITE) +#define MMC_ACMD51 (INDEX(51) | RSP_TYPE_R1 | DP_DATA | DDIR_READ) +#define MMC_CMD55 (INDEX(55) | RSP_TYPE_R1 | DP_NO_DATA | DDIR_WRITE) + +#define MMC_AC_CMD_RCA_MASK (unsigned int)(0xFFFF << 16) +#define MMC_BC_CMD_DSR_MASK (unsigned int)(0xFFFF << 16) +#define MMC_DSR_DEFAULT (0x0404) +#define SD_CMD8_CHECK_PATTERN (0xAA) +#define SD_CMD8_2_7_3_6_V_RANGE (0x01 << 8) + +/* Clock Configurations and Macros */ + +#define MMC_CLOCK_REFERENCE (96) +#define MMC_RELATIVE_CARD_ADDRESS (0x1234) +#define MMC_INIT_SEQ_CLK (MMC_CLOCK_REFERENCE * 1000 / 80) +#define MMC_400kHz_CLK (MMC_CLOCK_REFERENCE * 1000 / 400) +#define CLKDR(r, f, u) ((((r)*100) / ((f)*(u))) + 1) +#define CLKD(f, u) (CLKDR(MMC_CLOCK_REFERENCE, f, u)) + +#define MMC_OCR_REG_ACCESS_MODE_MASK (0x3 << 29) +#define MMC_OCR_REG_ACCESS_MODE_BYTE (0x0 << 29) +#define MMC_OCR_REG_ACCESS_MODE_SECTOR (0x2 << 29) + +#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_MASK (0x1 << 30) +#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE (0x0 << 30) +#define MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR (0x1 << 30) + +#define MMC_SD2_CSD_C_SIZE_LSB_MASK (0xFFFF) +#define MMC_SD2_CSD_C_SIZE_MSB_MASK (0x003F) +#define MMC_SD2_CSD_C_SIZE_MSB_OFFSET (16) +#define MMC_CSD_C_SIZE_LSB_MASK (0x0003) +#define MMC_CSD_C_SIZE_MSB_MASK (0x03FF) +#define MMC_CSD_C_SIZE_MSB_OFFSET (2) + +#define MMC_CSD_TRAN_SPEED_UNIT_MASK (0x07 << 0) +#define MMC_CSD_TRAN_SPEED_FACTOR_MASK (0x0F << 3) +#define MMC_CSD_TRAN_SPEED_UNIT_100MHZ (0x3 << 0) +#define MMC_CSD_TRAN_SPEED_FACTOR_1_0 (0x01 << 3) +#define MMC_CSD_TRAN_SPEED_FACTOR_8_0 (0x0F << 3) + +static const unsigned int tran_exp[] = { + 10000, 100000, 1000000, 10000000, + 0, 0, 0, 0 +}; + +static const unsigned char tran_mant[] = { + 0, 10, 12, 13, 15, 20, 25, 30, + 35, 40, 45, 50, 55, 60, 70, 80, +}; + +typedef struct { + unsigned not_used:1; + unsigned crc:7; + unsigned ecc:2; + unsigned file_format:2; + unsigned tmp_write_protect:1; + unsigned perm_write_protect:1; + unsigned copy:1; + unsigned file_format_grp:1; + unsigned content_prot_app:1; + unsigned reserved_1:4; + unsigned write_bl_partial:1; + unsigned write_bl_len:4; + unsigned r2w_factor:3; + unsigned default_ecc:2; + unsigned wp_grp_enable:1; + unsigned wp_grp_size:5; + unsigned erase_grp_mult:5; + unsigned erase_grp_size:5; + unsigned c_size_mult:3; + unsigned vdd_w_curr_max:3; + unsigned vdd_w_curr_min:3; + unsigned vdd_r_curr_max:3; + unsigned vdd_r_curr_min:3; + unsigned c_size_lsb:2; + unsigned c_size_msb:10; + unsigned reserved_2:2; + unsigned dsr_imp:1; + unsigned read_blk_misalign:1; + unsigned write_blk_misalign:1; + unsigned read_bl_partial:1; + unsigned read_bl_len:4; + unsigned ccc:12; + unsigned tran_speed:8; + unsigned nsac:8; + unsigned taac:8; + unsigned reserved_3:2; + unsigned spec_vers:4; + unsigned csd_structure:2; +} mmc_csd_reg_t; + +/* csd for sd2.0 */ +typedef struct { + unsigned not_used:1; + unsigned crc:7; + unsigned reserved_1:2; + unsigned file_format:2; + unsigned tmp_write_protect:1; + unsigned perm_write_protect:1; + unsigned copy:1; + unsigned file_format_grp:1; + unsigned reserved_2:5; + unsigned write_bl_partial:1; + unsigned write_bl_len:4; + unsigned r2w_factor:3; + unsigned reserved_3:2; + unsigned wp_grp_enable:1; + unsigned wp_grp_size:7; + unsigned sector_size:7; + unsigned erase_blk_len:1; + unsigned reserved_4:1; + unsigned c_size_lsb:16; + unsigned c_size_msb:6; + unsigned reserved_5:6; + unsigned dsr_imp:1; + unsigned read_blk_misalign:1; + unsigned write_blk_misalign:1; + unsigned read_bl_partial:1; + unsigned read_bl_len:4; + unsigned ccc:12; + unsigned tran_speed:8; + unsigned nsac:8; + unsigned taac:8; + unsigned reserved_6:6; + unsigned csd_structure:2; +} mmc_sd2_csd_reg_t; + +/* extended csd - 512 bytes long */ +typedef struct { + unsigned char reserved_1[181]; + unsigned char erasedmemorycontent; + unsigned char reserved_2; + unsigned char buswidthmode; + unsigned char reserved_3; + unsigned char highspeedinterfacetiming; + unsigned char reserved_4; + unsigned char powerclass; + unsigned char reserved_5; + unsigned char commandsetrevision; + unsigned char reserved_6; + unsigned char commandset; + unsigned char extendedcsdrevision; + unsigned char reserved_7; + unsigned char csdstructureversion; + unsigned char reserved_8; + unsigned char cardtype; + unsigned char reserved_9[3]; + unsigned char powerclass_52mhz_1_95v; + unsigned char powerclass_26mhz_1_95v; + unsigned char powerclass_52mhz_3_6v; + unsigned char powerclass_26mhz_3_6v; + unsigned char reserved_10; + unsigned char minreadperf_4b_26mhz; + unsigned char minwriteperf_4b_26mhz; + unsigned char minreadperf_8b_26mhz_4b_52mhz; + unsigned char minwriteperf_8b_26mhz_4b_52mhz; + unsigned char minreadperf_8b_52mhz; + unsigned char minwriteperf_8b_52mhz; + unsigned char reserved_11; + unsigned int sectorcount; + unsigned char reserved_12[288]; + unsigned char supportedcommandsets; + unsigned char reserved_13[7]; +} mmc_extended_csd_reg_t; + +/* mmc sd responce */ +typedef struct { + unsigned int ocr; +} mmc_resp_r3; + +typedef struct { + unsigned short cardstatus; + unsigned short newpublishedrca; +} mmc_resp_r6; + +extern mmc_card_data mmc_dev; + +unsigned char mmc_lowlevel_init(void); +unsigned char mmc_send_command(unsigned int cmd, unsigned int arg, + unsigned int *response); +unsigned char mmc_setup_clock(unsigned int iclk, unsigned short clkd); +unsigned char mmc_set_opendrain(unsigned char state); +unsigned char mmc_read_data(unsigned int *output_buf); + +#endif /*MMC_PROTOCOL_H */
diff --git a/x-loader/cpu/omap3/start.S b/x-loader/cpu/omap3/start.S new file mode 100644 index 0000000..1188935 --- /dev/null +++ b/x-loader/cpu/omap3/start.S
@@ -0,0 +1,235 @@ +/* + * armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + * Copyright (c) 2004-2006 Texas Instruments + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2004 Jian Zhang <jzhang@ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <asm/arch/cpu.h> + +.globl _start +_start: + b reset + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + ldr pc, _hang + +_hang: + .word do_hang + + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 + .word 0x12345678 /* now 16*4=64 */ + +.global _end_vect +_end_vect: + + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +#ifndef STACK_BASE +#define STACK_BASE TEXT_BASE +#endif + +_STACK_BASE: + .word STACK_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* Copy vectors to mask ROM indirect addr */ + adr r0, _start /* r0 <- current position of code */ + add r0, r0, #4 /* skip reset vector */ + mov r2, #64 /* r2 <- size to copy */ + add r2, r0, r2 /* r2 <- source end address */ + mov r1, #SRAM_OFFSET0 /* build vect addr */ + mov r3, #SRAM_OFFSET1 + add r1, r1, r3 + mov r3, #SRAM_OFFSET2 + add r1, r1, r3 +next: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end address [r2] */ + bne next /* loop until equal */ + + bl cpy_clk_code /* put dpll adjust code behind vectors */ + + /* the mask ROM code should have PLL and others stable */ + bl cpu_init_crit + +relocate: /* relocate U-Boot to RAM */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* no need to relocate if XIP */ + beq stack_setup /* skip txt cpy if XIP(SRAM, SDRAM) */ + + ldr r2, _armboot_start + ldr r3, _bss_start + sub r2, r3, r2 /* r2 <- size of armboot */ + add r2, r0, r2 /* r2 <- source end address */ + +copy_loop: + ldmia r0!, {r3-r10} /* copy from source address [r0] */ + stmia r1!, {r3-r10} /* copy to target address [r1] */ + cmp r0, r2 /* until source end addreee [r2] */ + ble copy_loop + + /* Set up the stack */ +stack_setup: + ldr r0, _STACK_BASE /* upper 128 KiB: relocated uboot */ + sub sp, r0, #128 /* leave 32 words for abort-stack */ + and sp, sp, #~7 /* 8 byte alinged for (ldr/str)d */ + + /* Clear BSS (if any). Is below tx (watch load addr - need space) */ +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0x00000000 /* clear value */ +clbss_l: + str r2, [r0] /* clear BSS location */ + cmp r0, r1 /* are we at the end yet */ + add r0, r0, #4 /* increment clear index pointer */ + bne clbss_l /* keep clearing till at end */ + + ldr pc, _start_armboot /* jump to C code */ + +_start_armboot: .word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +cpu_init_crit: + /* + * Invalidate L1 I/D + */ + mov r0, #0 /* set up for MCR */ + mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */ + mcr p15, 0, r0, c7, c5, 1 /* invalidate icache */ + + /* Invalide L2 cache (gp device call point) + * - warning, this may have issues on EMU/HS devices + * this call can corrupt r0-r5 + */ + mov r12, #0x1 @ set up to invalide L2 +/* + * TODO: Need to revert back on GP device. + */ +/* +smi: .word 0xE1600070 @ Call SMI monitor +*/ + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align +#ifndef CONFIG_ICACHE_OFF + orr r0, r0, #0x00001800 @ set bit 11,12 (---I Z---) BTB,I-Cache +#endif + mcr p15, 0, r0, c1, c0, 0 + + /* + * Jump to board specific initialization... The Mask ROM will have already initialized + * basic memory. Go here to bump up clock rate and handle wake up conditions. + */ + adr r0, _start /* r0 <- current position of code */ + ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ + cmp r0, r1 /* pass on info about skipping some init portions */ + moveq r0,#0x1 /* flag to skip prcm and sdrc setup */ + movne r0,#0x0 + + mov ip, lr /* persevere link reg across call */ + bl lowlevel_init /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ + +/* + * exception handler + */ + .align 5 +do_hang: + ldr sp, _TEXT_BASE /* use 32 words abort stack */ + bl hang /* hang and never return */ +
diff --git a/x-loader/disk/Makefile b/x-loader/disk/Makefile new file mode 100755 index 0000000..ef409d8 --- /dev/null +++ b/x-loader/disk/Makefile
@@ -0,0 +1,47 @@ +# +# (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 + +#CFLAGS += -DET_DEBUG -DDEBUG + +LIB = $(obj)libdisk.a + +COBJS = part.o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/disk/part.c b/x-loader/disk/part.c new file mode 100755 index 0000000..a367f13 --- /dev/null +++ b/x-loader/disk/part.c
@@ -0,0 +1,273 @@ +/* + * (C) Copyright 2001 + * 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 <common.h> +#include <command.h> +#include <ide.h> +#include <part.h> + +#undef PART_DEBUG + +#ifdef PART_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ + (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ + (CONFIG_COMMANDS & CFG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) ) + +/* ------------------------------------------------------------------------- */ +/* + * reports device info to the user + */ +void dev_print (block_dev_desc_t *dev_desc) +{ +#ifdef CONFIG_LBA48 + uint64_t lba512; /* number of blocks if 512bytes block size */ +#else + lbaint_t lba512; +#endif + + if (dev_desc->type==DEV_TYPE_UNKNOWN) { + return; + } + if (dev_desc->if_type==IF_TYPE_SCSI) { + printf ("(%d:%d) ", dev_desc->target,dev_desc->lun); + } + if (dev_desc->if_type==IF_TYPE_IDE) { + printf ("Model: %s Firm: %s Ser#: %s\n", + dev_desc->vendor, + dev_desc->revision, + dev_desc->product); + } else { + printf ("Vendor: %s Prod.: %s Rev: %s\n", + dev_desc->vendor, + dev_desc->product, + dev_desc->revision); + } + printf (" Type: "); + switch (dev_desc->type & 0x1F) { + case DEV_TYPE_HARDDISK: printf ("Hard Disk"); + break; + case DEV_TYPE_CDROM: printf ("CD ROM"); + break; + case DEV_TYPE_OPDISK: printf ("Optical Device"); + break; + case DEV_TYPE_TAPE: printf ("Tape"); + break; + default: printf ("# %02X #", dev_desc->type & 0x1F); + break; + } + if ((dev_desc->lba * dev_desc->blksz)>0L) { + ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem; + lbaint_t lba; + + lba = dev_desc->lba; + + lba512 = (lba * (dev_desc->blksz/512)); + mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */ + /* round to 1 digit */ + mb_quot = mb / 10; + mb_rem = mb - (10 * mb_quot); + + gb = mb / 1024; + gb_quot = gb / 10; + gb_rem = gb - (10 * gb_quot); +#ifdef CONFIG_LBA48 + if (dev_desc->lba48) + printf (" Supports 48-bit addressing\n"); +#endif +#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) + printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%qd x %ld)\n", + mb_quot, mb_rem, + gb_quot, gb_rem, + lba, + dev_desc->blksz); +#else + printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n", + mb_quot, mb_rem, + gb_quot, gb_rem, + (ulong)lba, + dev_desc->blksz); +#endif + } else { + printf (" Capacity: not available\n"); + } +} +#endif /* CFG_CMD_IDE || CFG_CMD_SCSI || CFG_CMD_USB || CONFIG_MMC */ + +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ + (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ + (CONFIG_COMMANDS & CFG_CMD_USB) || \ + (CONFIG_COMMANDS & CFG_CMD_MMC) || \ + defined(CONFIG_SYSTEMACE) ) + +#if defined(CONFIG_MAC_PARTITION) || \ + defined(CONFIG_DOS_PARTITION) || \ + defined(CONFIG_ISO_PARTITION) || \ + defined(CONFIG_AMIGA_PARTITION) + +void init_part (block_dev_desc_t * dev_desc) +{ +#ifdef CONFIG_ISO_PARTITION + if (test_part_iso(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_ISO; + return; + } +#endif + +#ifdef CONFIG_MAC_PARTITION + if (test_part_mac(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_MAC; + return; + } +#endif + +#ifdef CONFIG_DOS_PARTITION + if (test_part_dos(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_DOS; + return; + } +#endif + +#ifdef CONFIG_AMIGA_PARTITION + if (test_part_amiga(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_AMIGA; + return; + } +#endif +} + + +int get_partition_info (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) +{ + switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION + case PART_TYPE_MAC: + if (get_partition_info_mac(dev_desc,part,info) == 0) { + PRINTF ("## Valid MAC partition found ##\n"); + return (0); + } + break; +#endif + +#ifdef CONFIG_DOS_PARTITION + case PART_TYPE_DOS: + if (get_partition_info_dos(dev_desc,part,info) == 0) { + PRINTF ("## Valid DOS partition found ##\n"); + return (0); + } + break; +#endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + if (get_partition_info_iso(dev_desc,part,info) == 0) { + PRINTF ("## Valid ISO boot partition found ##\n"); + return (0); + } + break; +#endif + +#ifdef CONFIG_AMIGA_PARTITION + case PART_TYPE_AMIGA: + if (get_partition_info_amiga(dev_desc, part, info) == 0) + { + PRINTF ("## Valid Amiga partition found ##\n"); + return (0); + } + break; +#endif + default: + break; + } + return (-1); +} + +static void print_part_header (const char *type, block_dev_desc_t * dev_desc) +{ + switch (dev_desc->if_type) { + case IF_TYPE_IDE: printf ("IDE"); + break; + case IF_TYPE_SCSI: printf ("SCSI"); + break; + case IF_TYPE_ATAPI: printf ("ATAPI"); + break; + case IF_TYPE_USB: printf ("USB"); + break; + case IF_TYPE_DOC: printf ("DOC"); + break; + default: printf ("UNKNOWN"); + break; + } + printf (" device %d -- Partition Type: %s\n\n", + dev_desc->dev, type); +} + +void print_part (block_dev_desc_t * dev_desc) +{ + + switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION + case PART_TYPE_MAC: + PRINTF ("## Testing for valid MAC partition ##\n"); + print_part_header ("MAC", dev_desc); + print_part_mac (dev_desc); + return; +#endif +#ifdef CONFIG_DOS_PARTITION + case PART_TYPE_DOS: + PRINTF ("## Testing for valid DOS partition ##\n"); + print_part_header ("DOS", dev_desc); + print_part_dos (dev_desc); + return; +#endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + PRINTF ("## Testing for valid ISO Boot partition ##\n"); + print_part_header ("ISO", dev_desc); + print_part_iso (dev_desc); + return; +#endif + +#ifdef CONFIG_AMIGA_PARTITION + case PART_TYPE_AMIGA: + PRINTF ("## Testing for a valid Amiga partition ##\n"); + print_part_header ("AMIGA", dev_desc); + print_part_amiga (dev_desc); + return; +#endif + } +} + + +#else /* neither MAC nor DOS nor ISO partition configured */ +# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION nor CONFIG_ISO_PARTITION configured! +#endif + +#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) || CONFIG_COMMANDS & CFG_CMD_SCSI) */
diff --git a/x-loader/drivers/mtd/nand/Makefile b/x-loader/drivers/mtd/nand/Makefile new file mode 100644 index 0000000..8811257 --- /dev/null +++ b/x-loader/drivers/mtd/nand/Makefile
@@ -0,0 +1,94 @@ +# +# (C) Copyright 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)libnand.a + +ifeq ($(BOARD), omap3430sdp) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), omap3430labrador) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), omap3evm) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), am3517evm) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), omap2420h4) +COBJS-y += k9k1216.o +endif + +ifeq ($(BOARD), omap2430sdp) +COBJS-y += k9k1216.o +endif + +ifeq ($(BOARD), omap1710h3) +COBJS-y += k9f5616.o +endif + +ifeq ($(BOARD), diamond) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), diamond-usb-loader) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), j49) +COBJS-y += k9f1g08r0a.o +endif + +ifeq ($(BOARD), j49-usb-loader) +COBJS-y += k9f1g08r0a.o +endif + +## Disabled for now: +## cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \ +## lan91c96.o mw_eeprom.o natsemi.o \ +## smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \ +## + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/drivers/mtd/nand/k9f1g08r0a.c b/x-loader/drivers/mtd/nand/k9f1g08r0a.c new file mode 100644 index 0000000..84ff06f --- /dev/null +++ b/x-loader/drivers/mtd/nand/k9f1g08r0a.c
@@ -0,0 +1,425 @@ +/* + * (C) Copyright 2004 Texas Instruments + * Jian Zhang <jzhang@ti.com> + * + * Samsung K9F1G08R0AQ0C NAND chip driver for an OMAP2420 board + * + * This file is based on the following u-boot file: + * common/cmd_nand.c + * + * 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/arch/sys_proto.h> +#include <asm/arch/sys_info.h> + +#if defined(CFG_NAND_K9F1G08R0A) || \ + defined(CFG_NAND_K9F4G08U0C) || \ + defined(CFG_NAND_MT29F2G16) + +#define K9F1G08R0A_MFR 0xec /* Samsung */ +#define K9F1G08R0A_ID 0xa1 /* part # */ + +#define S34MS01G1_MFR 0x01 /* Spansion */ +#define S34MS01G1_ID 0xba /* part # - 16bit, 2GB */ + +/* Since Micron and Samsung parts are similar in geometry and bus width + * we can use the same driver. Need to revisit to make this file independent + * of part/manufacturer + */ +#define MT29F1G_MFR 0x2c /* Micron */ +#define MT29F1G_ID 0xa1 /* x8, 1GiB */ +#define MT29F2G_ID 0xba /* x16, 2GiB */ + +#define HYNIX4GiB_MFR 0xAD /* Hynix */ +#define HYNIX4GiB_ID 0xBC /* x16, 4GiB */ + +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE (ADDR_COLUMN | ADDR_PAGE) + +#define ADDR_OOB (0x4 | ADDR_COLUMN_PAGE) + +#define PAGE_SIZE 2048 +#define OOB_SIZE 64 +#define MAX_NUM_PAGES 64 + +#define ECC_CHECK_ENABLE + +#if CFG_NAND_ECC_1BIT +#define ECC_SIZE 24 +#define ECC_STEPS 3 +#define omap_enable_hwecc +#define omap_correct_data +#define omap_calculate_ecc +#elif CFG_NAND_ECC_4BIT +#define ECC_SIZE 28 +#define ECC_STEPS 28 + +extern enable_hwecc_bch4(uint32_t bus_width, int32_t mode); +extern int omap_correct_data_bch4(uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc); +extern int omap_calculate_ecc_bch4(const uint8_t *dat, uint8_t *ecc_code); + +#define omap_enable_hwecc omap_enable_hwecc_bch4 +#define omap_correct_data omap_correct_data_bch4 +#define omap_calculate_ecc omap_calculate_ecc_bch4 +#elif CFG_NAND_ECC_8BIT +#define ECC_SIZE 52 +#define ECC_STEPS 52 + +extern void omap_enable_hwecc_bch8(uint32_t bus_width, int32_t mode); +extern int omap_correct_data_bch8(uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc); +extern int omap_calculate_ecc_bch8(const uint8_t *dat, uint8_t *ecc_code); + +#define omap_enable_hwecc omap_enable_hwecc_bch8 +#define omap_correct_data omap_correct_data_bch8 +#define omap_calculate_ecc omap_calculate_ecc_bch8 +#else +#error "None of CFG_NAND_ECC_{1,4,8}BIT is defined." +#endif /* CFG_NAND_ECC_1BIT */ + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %0, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +static int nand_read_page(u_char *buf, ulong page_addr); +static int nand_read_oob(u_char * buf, ulong page_addr); + +#ifdef CFG_NAND_ECC_1BIT +static u_char ecc_pos[] = + {40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}; +#elif CFG_NAND_ECC_4BIT +static u_char ecc_pos[] = + {36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63}; +#elif CFG_NAND_ECC_8BIT +static u_char ecc_pos[] = + {12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63}; +#endif + +static unsigned long chipsize = (256 << 20); + +#ifdef NAND_16BIT +static int bus_width = 16; +#else +static int bus_width = 8; +#endif + +/* NanD_Command: Send a flash command to the flash chip */ +static int NanD_Command(unsigned char command) +{ + NAND_CTL_SETCLE(NAND_ADDR); + + WRITE_NAND_COMMAND(command, NAND_ADDR); + NAND_CTL_CLRCLE(NAND_ADDR); + + if(command == NAND_CMD_RESET){ + unsigned char ret_val; + NanD_Command(NAND_CMD_STATUS); + do{ + ret_val = READ_NAND(NAND_ADDR);/* wait till ready */ + } while((ret_val & 0x40) != 0x40); + } + + NAND_WAIT_READY(); + return 0; +} + + +/* NanD_Address: Set the current address for the flash chip */ +static int NanD_Address(unsigned int numbytes, unsigned long ofs) +{ + uchar u; + + NAND_CTL_SETALE(NAND_ADDR); + + if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE + || numbytes == ADDR_OOB) + { + ushort col = ofs; + + u = col & 0xff; + WRITE_NAND_ADDRESS(u, NAND_ADDR); + + u = (col >> 8) & 0x07; + if (numbytes == ADDR_OOB) + u = u | ((bus_width == 16) ? (1 << 2) : (1 << 3)); + WRITE_NAND_ADDRESS(u, NAND_ADDR); + } + + if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE + || numbytes == ADDR_OOB) + { + u = (ofs >> 11) & 0xff; + WRITE_NAND_ADDRESS(u, NAND_ADDR); + u = (ofs >> 19) & 0xff; + WRITE_NAND_ADDRESS(u, NAND_ADDR); + + /* One more address cycle for devices > 128MiB */ + if (chipsize > (128 << 20)) { + u = (ofs >> 27) & 0xff; + WRITE_NAND_ADDRESS(u, NAND_ADDR); + } + } + + NAND_CTL_CLRALE(NAND_ADDR); + + NAND_WAIT_READY(); + return 0; +} + +/* read chip mfr and id + * return 0 if they match board config + * return 1 if not + */ +int nand_chip() +{ + const int supported = 0; + int mfr, id; + + NAND_ENABLE_CE(); + + if (NanD_Command(NAND_CMD_RESET)) { + printf("Err: RESET\n"); + NAND_DISABLE_CE(); + return (!supported); + } + + if (NanD_Command(NAND_CMD_READID)) { + printf("Err: READID\n"); + NAND_DISABLE_CE(); + return (!supported); + } + + NanD_Address(ADDR_COLUMN, 0); + + mfr = READ_NAND(NAND_ADDR); + id = READ_NAND(NAND_ADDR); + + debug("NAND: %x:%x\n", mfr, id); + + NAND_DISABLE_CE(); + + switch (mfr) { + + case K9F1G08R0A_MFR: + switch (id) { + + case K9F1G08R0A_ID: return (supported); + default: return (!supported); + + } + break; + + case MT29F1G_MFR: + switch (id) { + + case MT29F1G_ID: + case MT29F2G_ID: return (supported); + default: return (!supported); + + } + break; + + case HYNIX4GiB_MFR: + switch (id) { + + case HYNIX4GiB_ID: return (supported); + default: return (!supported); + + } + break; + case S34MS01G1_MFR: + switch (id) { + + case S34MS01G1_ID: return (supported); + default: return (!supported); + + } + break; + + default: return (!supported); + + } + + return (!supported); +} + +/* read a block data to buf + * return 1 if the block is bad or ECC error can't be corrected for any page + * return 0 on sucess + */ +int nand_read_block(unsigned char *buf, ulong block_addr) +{ + int i, offset = 0; + +#ifdef ECC_CHECK_ENABLE + u16 oob_buf[OOB_SIZE >> 1]; + + /* check bad block */ + /* 0th word in spare area needs be 0xff */ + if (nand_read_oob((unsigned char *)oob_buf, block_addr) + || (oob_buf[0] & 0xff) != 0xff) { + printf("Skipped bad block at 0x%x\n", block_addr); + return NAND_READ_SKIPPED_BAD_BLOCK; /* skip bad block */ + } +#endif + /* read the block page by page*/ + for (i=0; i<MAX_NUM_PAGES; i++){ + if (nand_read_page(buf+offset, block_addr + offset)) + return NAND_READ_ECC_FAILURE; + offset += PAGE_SIZE; + } + + return NAND_READ_SUCCESS; +} +static int count; +/* read a page with ECC */ +static int nand_read_page(u_char *buf, ulong page_addr) +{ +#ifdef ECC_CHECK_ENABLE + /* increased size of ecc_code and ecc_calc to match the OOB size, + as is done in the kernel */ + u_char ecc_code[OOB_SIZE]; + u_char ecc_calc[OOB_SIZE]; + u_char oob_buf[OOB_SIZE]; +#endif + u16 val; + int cntr; + int len; + +#ifdef NAND_16BIT + u16 *p; +#else + u_char *p; +#endif + + NAND_ENABLE_CE(); + NanD_Command(NAND_CMD_READ0); + NanD_Address(ADDR_COLUMN_PAGE, page_addr); + NanD_Command(NAND_CMD_READSTART); + NAND_WAIT_READY(); + + /* A delay seems to be helping here. needs more investigation */ + delay(10000); + + omap_enable_hwecc(bus_width, 0); + + /* read the page */ + len = (bus_width == 16) ? PAGE_SIZE >> 1 : PAGE_SIZE; + p = (u16 *)buf; + for (cntr = 0; cntr < len; cntr++){ + *p++ = READ_NAND(NAND_ADDR); + delay(10); + } + +#ifdef ECC_CHECK_ENABLE + omap_calculate_ecc(buf, &ecc_calc[0]); + + /* read the OOB area */ + p = (u16 *)oob_buf; + len = (bus_width == 16) ? OOB_SIZE >> 1 : OOB_SIZE; + for (cntr = 0; cntr < len; cntr++){ + *p++ = READ_NAND(NAND_ADDR); + delay(10); + } + count = 0; + NAND_DISABLE_CE(); /* set pin high */ + + /* Need to enable HWECC for READING */ + + /* Pick the ECC bytes out of the oob data */ + for (cntr = 0; cntr < ECC_SIZE; cntr++) + ecc_code[cntr] = oob_buf[ecc_pos[cntr]]; + + for(count = 0; count < ECC_SIZE; count += ECC_STEPS) { +#if CFG_NAND_ECC_1BIT + nand_calculate_ecc (buf, &ecc_calc[0]); + if (nand_correct_data (buf, &ecc_code[count], &ecc_calc[0]) == -1) { +#else + if (omap_correct_data(buf, &ecc_code[count], &ecc_calc[0]) == -1) { +#endif + printf ("ECC Failed, page 0x%08x\n", page_addr); + for (val=0; val <256; val++) + printf("%x ", buf[val]); + printf("\n"); + return 1; + } + buf += 256; + page_addr += 256; + } +#endif + return 0; +} + +/* read from the 16 bytes of oob data that correspond to a 512 / 2048 byte page. + */ +static int nand_read_oob(u_char *buf, ulong page_addr) +{ + int cntr; + int len; + +#ifdef NAND_16BIT + u16 *p; +#else + u_char *p; +#endif + p = (u16 *)buf; + len = (bus_width == 16) ? OOB_SIZE >> 1 : OOB_SIZE; + + NAND_ENABLE_CE(); /* set pin low */ + NanD_Command(NAND_CMD_READ0); + NanD_Address(ADDR_OOB, page_addr); + NanD_Command(NAND_CMD_READSTART); + NAND_WAIT_READY(); + + /* A delay seems to be helping here. needs more investigation */ + delay(10000); + for (cntr = 0; cntr < len; cntr++) + *p++ = READ_NAND(NAND_ADDR); + + NAND_WAIT_READY(); + NAND_DISABLE_CE(); /* set pin high */ + + return 0; +} +#endif /* defined(CFG_NAND_K9F1G08R0A) || + * defined(CFG_NAND_K9F4G08U0C) || + * defined(CFG_NAND_MT29F2G16) + */
diff --git a/x-loader/drivers/mtd/nand/k9f5616.c b/x-loader/drivers/mtd/nand/k9f5616.c new file mode 100644 index 0000000..90b142b --- /dev/null +++ b/x-loader/drivers/mtd/nand/k9f5616.c
@@ -0,0 +1,229 @@ +/* + * (C) Copyright 2004 Texas Instruments + * Jian Zhang <jzhang@ti.com> + * + * Samsung K9F5616Q0C NAND chip driver for an OMAP16xx board + * + * This file is based on the following u-boot file: + * common/cmd_nand.c + * + * 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> + +#ifdef CFG_NAND_K9F5616 + +#define K9F5616_MFR 0xec +#define K9F5616_ID 0x45 + +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE 3 + +#define PAGE_SIZE 512 + +static int nand_read_page(u_char *buf, ulong page_addr); +static int nand_read_oob(u_char * buf, ulong page_addr); + +/* JFFS2 512-byte-page ECC layout */ +static u_char ecc_pos[] = {0,1,2,3,6,7}; +static u_char eccvalid_pos = 4; + +/* NanD_Command: Send a flash command to the flash chip */ +static int NanD_Command(unsigned char command) +{ + NAND_CTL_SETCLE(NAND_ADDR); + WRITE_NAND_COMMAND(command, NAND_ADDR); + NAND_CTL_CLRCLE(NAND_ADDR); + + if(command == NAND_CMD_RESET){ + unsigned char ret_val; + NanD_Command(NAND_CMD_STATUS); + do{ + ret_val = READ_NAND(NAND_ADDR);/* wait till ready */ + } while((ret_val & 0x40) != 0x40); + } + + NAND_WAIT_READY(); + return 0; +} + +/* NanD_Address: Set the current address for the flash chip */ +static int NanD_Address(int numbytes, unsigned long ofs) +{ + int i; + + NAND_CTL_SETALE(NAND_ADDR); + + if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) + WRITE_NAND_ADDRESS(ofs, NAND_ADDR); + + ofs = ofs >> 8; + + if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) + for (i = 0; i < 2; i++, ofs = ofs >> 8) + WRITE_NAND_ADDRESS(ofs, NAND_ADDR); + + NAND_CTL_CLRALE(NAND_ADDR); + + NAND_WAIT_READY(); + return 0; +} + +/* read chip mfr and id + * return 0 if they match board config + * return 1 if not + */ +int nand_chip() +{ + int mfr, id; + + NAND_ENABLE_CE(); + + if (NanD_Command(NAND_CMD_RESET)) { + printf("Err: RESET\n"); + NAND_DISABLE_CE(); + return 1; + } + + if (NanD_Command(NAND_CMD_READID)) { + printf("Err: READID\n"); + NAND_DISABLE_CE(); + return 1; + } + + NanD_Address(ADDR_COLUMN, 0); + + mfr = READ_NAND(NAND_ADDR); + id = READ_NAND(NAND_ADDR); + + NAND_DISABLE_CE(); + + return (mfr != K9F5616_MFR || id != K9F5616_ID); +} + +/* read a block data to buf + * return 1 if the block is bad or ECC error can't be corrected for any page + * return 0 on sucess + */ +int nand_read_block(unsigned char *buf, ulong block_addr) +{ + int i, offset = 0; + uchar oob_buf[16]; + + /* check bad block */ + /* 0th and 5th words need be 0xffff */ + if (nand_read_oob(oob_buf, block_addr) || +// oob_buf[0] != 0xff || oob_buf[1] != 0xff || +// oob_buf[10] != 0xff || oob_buf[11] != 0xff ){ + oob_buf[5] != 0xff){ + printf("Skipped bad block at 0x%x\n", block_addr); + return NAND_READ_SKIPPED_BAD_BLOCK; /* skip bad block */ + } + + /* read the block page by page*/ + for (i=0; i<32; i++){ + if (nand_read_page(buf+offset, block_addr + offset)) + return NAND_READ_ECC_FAILURE; + offset += PAGE_SIZE; + } + + return NAND_READ_SUCCESS; +} + +/* read a page with ECC */ +static int nand_read_page(u_char *buf, ulong page_addr) +{ + u_char ecc_code[6]; + u_char ecc_calc[3]; + u_char oob_buf[16]; + u_char *p; + u16 val; + int cntr; + + NAND_ENABLE_CE(); + NanD_Command(NAND_CMD_READ0); + NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1); + + NAND_WAIT_READY(); + p = buf; + for (cntr = 0; cntr < 256; cntr++){ + val = READ_NAND(NAND_ADDR); + *p++ = val & 0xff; + *p++ = val >> 8; + } + + p = oob_buf; + for (cntr = 0; cntr < 8; cntr++){ + val = READ_NAND(NAND_ADDR); + *p++ = val & 0xff; + *p++ = val >> 8; + } + NAND_DISABLE_CE(); /* set pin high */ + + /* Pick the ECC bytes out of the oob data */ + for (cntr = 0; cntr < 6; cntr++) + ecc_code[cntr] = oob_buf[ecc_pos[cntr]]; + + + if ((oob_buf[eccvalid_pos] & 0x0f) != 0x0f) { + nand_calculate_ecc (buf, &ecc_calc[0]); + if (nand_correct_data (buf, &ecc_code[0], &ecc_calc[0]) == -1) { + printf ("ECC Failed, page 0x%08x\n", page_addr); + return 1; + } + } + + if ((oob_buf[eccvalid_pos] & 0xf0) != 0xf0) { + nand_calculate_ecc (buf + 256, &ecc_calc[0]); + if (nand_correct_data (buf + 256, &ecc_code[3], &ecc_calc[0]) == -1) { + printf ("ECC Failed, page 0x%08x\n", page_addr+0x100); + return 1; + } + } + + return 0; +} + +/* read from the 16 bytes of oob data that correspond to a 512 byte page. + */ +static int nand_read_oob(u_char *buf, ulong page_addr) +{ + u16 val; + int cntr; + + NAND_ENABLE_CE(); /* set pin low */ + NanD_Command(NAND_CMD_READOOB); + NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1); + NAND_WAIT_READY(); + + for (cntr = 0; cntr < 8; cntr++){ + val = READ_NAND(NAND_ADDR); + *buf++ = val & 0xff; + *buf++ = val >> 8; + } + + NAND_WAIT_READY(); + NAND_DISABLE_CE(); /* set pin high */ + + return 0; +} + +#endif
diff --git a/x-loader/drivers/mtd/nand/k9k1216.c b/x-loader/drivers/mtd/nand/k9k1216.c new file mode 100644 index 0000000..3ee305d --- /dev/null +++ b/x-loader/drivers/mtd/nand/k9k1216.c
@@ -0,0 +1,256 @@ +/* + * (C) Copyright 2004 Texas Instruments + * Jian Zhang <jzhang@ti.com> + * + * Samsung K9K1216Q0C NAND chip driver for an OMAP2420 board + * + * This file is based on the following u-boot file: + * common/cmd_nand.c + * + * 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> + +#ifdef CFG_NAND_K9K1216 + +#define K9K1216_MFR 0xec +#define K9K1216_ID 0x46 + +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE 3 + +#define PAGE_SIZE 512 +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); +} + +static int nand_read_page(u_char *buf, ulong page_addr); +static int nand_read_oob(u_char * buf, ulong page_addr); + +/* JFFS2 512-byte-page ECC layout */ +static u_char ecc_pos[] = {0,1,2,3,6,7}; +static u_char eccvalid_pos = 4; + +/* NanD_Command: Send a flash command to the flash chip */ +static int NanD_Command(unsigned char command) +{ + NAND_CTL_SETCLE(NAND_ADDR); + WRITE_NAND_COMMAND(command, NAND_ADDR); + NAND_CTL_CLRCLE(NAND_ADDR); + + if(command == NAND_CMD_RESET){ + unsigned char ret_val; + NanD_Command(NAND_CMD_STATUS); + do{ + ret_val = READ_NAND(NAND_ADDR);/* wait till ready */ + } while((ret_val & 0x40) != 0x40); + } + + NAND_WAIT_READY(); + return 0; +} + +/* NanD_Address: Set the current address for the flash chip */ +static int NanD_Address(int numbytes, unsigned long ofs) +{ + int i; + + NAND_CTL_SETALE(NAND_ADDR); + + if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) + WRITE_NAND_ADDRESS(ofs, NAND_ADDR); + + ofs = ofs >> 9; + + if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) + for (i = 0; i < 3; i++, ofs = ofs >> 8) + WRITE_NAND_ADDRESS(ofs, NAND_ADDR); + + NAND_CTL_CLRALE(NAND_ADDR); + + NAND_WAIT_READY(); + return 0; +} + +/* read chip mfr and id + * return 0 if they match board config + * return 1 if not + */ +int nand_chip() +{ + int mfr, id; + + NAND_ENABLE_CE(); + + if (NanD_Command(NAND_CMD_RESET)) { + printf("Err: RESET\n"); + NAND_DISABLE_CE(); + return 1; + } + + if (NanD_Command(NAND_CMD_READID)) { + printf("Err: READID\n"); + NAND_DISABLE_CE(); + return 1; + } + + NanD_Address(ADDR_COLUMN, 0); + + mfr = READ_NAND(NAND_ADDR); + id = READ_NAND(NAND_ADDR); + + NAND_DISABLE_CE(); + + return (mfr != K9K1216_MFR || id != K9K1216_ID); +} + +/* read a block data to buf + * return 1 if the block is bad or ECC error can't be corrected for any page + * return 0 on sucess + */ +int nand_read_block(unsigned char *buf, ulong block_addr) +{ + int i, offset = 0; + uchar oob_buf[16]; + + /* check bad block */ + /* 0th and 5th words need be 0xffff */ + if (nand_read_oob(oob_buf, block_addr) || +// oob_buf[0] != 0xff || oob_buf[1] != 0xff || +// oob_buf[10] != 0xff || oob_buf[11] != 0xff ){ + oob_buf[5] != 0xff){ + printf("Skipped bad block at 0x%x\n", block_addr); + return NAND_READ_SKIPPED_BAD_BLOCK; /* skip bad block */ + } + + /* read the block page by page*/ + for (i=0; i<32; i++){ + if (nand_read_page(buf+offset, block_addr + offset)) + return NAND_READ_ECC_FAILURE; + offset += PAGE_SIZE; + } + + return NAND_READ_SUCCESS; +} +static count = 0; +/* read a page with ECC */ +static int nand_read_page(u_char *buf, ulong page_addr) +{ + u_char ecc_code[6]; + u_char ecc_calc[3]; + u_char oob_buf[16]; + u_char *p; + u16 val; + int cntr; + + NAND_ENABLE_CE(); + NanD_Command(NAND_CMD_READ0); + NanD_Address(ADDR_COLUMN_PAGE, page_addr); + NAND_WAIT_READY(); + + delay(500); /* we go through NFC need a bigger delay. 200 is not enough */ + + p = buf; + for (cntr = 0; cntr < 256; cntr++){ + val = READ_NAND(NAND_ADDR); + *p++ = val & 0xff; + *p++ = val >> 8; + } + + p = oob_buf; + for (cntr = 0; cntr < 8; cntr++){ + val = READ_NAND(NAND_ADDR); + *p++ = val & 0xff; + *p++ = val >> 8; + } + count = 1; + NAND_DISABLE_CE(); /* set pin high */ + + /* Pick the ECC bytes out of the oob data */ + for (cntr = 0; cntr < 6; cntr++) + ecc_code[cntr] = oob_buf[ecc_pos[cntr]]; + + if ((oob_buf[eccvalid_pos] & 0x0f) != 0x0f) { + nand_calculate_ecc (buf, &ecc_calc[0]); + if (nand_correct_data (buf, &ecc_code[0], &ecc_calc[0]) == -1) { + printf ("ECC Failed, page 0x%08x\n", page_addr); + for (val=0; val <256; val++) + printf("%x ", buf[val]); + printf("\n"); + return 1; + } + } + + if ((oob_buf[eccvalid_pos] & 0xf0) != 0xf0) { + nand_calculate_ecc (buf + 256, &ecc_calc[0]); + if (nand_correct_data (buf + 256, &ecc_code[3], &ecc_calc[0]) == -1) { + printf ("ECC Failed, page 0x%08x\n", page_addr+0x100); + for (val=0; val <256; val++) + printf("%x ", buf[val+256]); + printf("\n"); + return 1; + } + } + + return 0; +} + +/* read from the 16 bytes of oob data that correspond to a 512 byte page. + */ +static int nand_read_oob(u_char *buf, ulong page_addr) +{ + u16 val; + int cntr; + + NAND_ENABLE_CE(); /* set pin low */ + NanD_Command(NAND_CMD_READOOB); + NanD_Address(ADDR_COLUMN_PAGE, page_addr); + NAND_WAIT_READY(); + +/* do { + *(volatile u32 *)(0x6800A07c) = NAND_CMD_STATUS; + val = *(volatile u32 *)(0x6800A084); + printf("val = %x\n", val); + } while ((val & 0x40) != 0x40); +*/ + /* the above code from OSTBoot doesn't work, we use delay */ + delay(500); /* we go through NFC need a bigger delay. 200 is not enough */ + + for (cntr = 0; cntr < 8; cntr++){ + val = READ_NAND(NAND_ADDR); + *buf++ = val & 0xff; + *buf++ = val >> 8; + } + + NAND_WAIT_READY(); + NAND_DISABLE_CE(); /* set pin high */ + + return 0; +} + +#endif
diff --git a/x-loader/drivers/mtd/onenand/Makefile b/x-loader/drivers/mtd/onenand/Makefile new file mode 100644 index 0000000..3c6195c --- /dev/null +++ b/x-loader/drivers/mtd/onenand/Makefile
@@ -0,0 +1,45 @@ +# +# Copyright (C) 2005-2007 Samsung Electronics. +# Kyungmin Park <kyungmin.park@samsung.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 $(TOPDIR)/config.mk + +LIB := $(obj)libonenand.a + +COBJS-y := onenand.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/drivers/mtd/onenand/onenand.c b/x-loader/drivers/mtd/onenand/onenand.c new file mode 100644 index 0000000..b13f706 --- /dev/null +++ b/x-loader/drivers/mtd/onenand/onenand.c
@@ -0,0 +1,239 @@ +/* + * (C) Copyright 2005 Samsung Electronis + * Kyungmin Park <kyungmin.park@samsung.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/string.h> + +#include "onenand_regs.h" + +#if defined(CFG_MMC_ONENAND) || defined(CFG_GPMC_ONENAND) +#define onenand_readw(a) (*(volatile unsigned short *)(a)) +#define onenand_writew(v, a) ((*(volatile unsigned short *)(a)) = (u16) (v)) + +#define SAMSUNG_MFR_ID 0xEC +#define KFM1G16Q2A_DEV_ID 0x30 +#define KFN2G16Q2A_DEV_ID 0x40 + + +#define THIS_ONENAND(a) (ONENAND_ADDR + (a)) + +#define READ_INTERRUPT() \ + onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT)) + +#define READ_CTRL_STATUS() \ + onenand_readw(THIS_ONENAND(ONENAND_REG_CTRL_STATUS)) + +#define READ_ECC_STATUS() \ + onenand_readw(THIS_ONENAND(ONENAND_REG_ECC_STATUS)) + +#define SET_EMIFS_CS_CONFIG(v) \ + (*(volatile unsigned long *)(OMAP_EMIFS_CS_CONFIG) = (v)) + +#define onenand_block_address(block) (block) +#define onenand_sector_address(page) (page << 2) +#define onenand_buffer_address() ((1 << 3) << 8) +#define onenand_bufferram_address(block) (0) + +#if defined(CFG_SYNC_BURST_READ) && defined(CONFIG_OMAP1610) +static inline void set_sync_burst_read(void) +{ + unsigned int value; + value = 0 + | (0x1 << 15) /* Read Mode: Synchronous */ + | (0x4 << 12) /* Burst Read Latency: 4 cycles */ + | (0x4 << 9) /* Burst Length: 8 word */ + | (0x1 << 7) /* RDY signal plarity */ + | (0x1 << 6) /* INT signal plarity */ + | (0x1 << 5) /* I/O buffer enable */ + ; + onenand_writew(value, THIS_ONENAND(ONENAND_REG_SYS_CFG1)); + + value = 0 + | (4 << 16) /* Synchronous Burst Read */ + | (1 << 12) /* PGWST/WELEN */ + | (1 << 8) /* WRWST */ + | (4 << 4) /* RDWST */ + | (1 << 0) /* FCLKDIV => 48MHz */ + ; + SET_EMIFS_CS_CONFIG(value); +} + +static inline void set_async_read(void) +{ + unsigned int value; + value = 0 + | (0x0 << 15) /* Read Mode: Asynchronous */ + | (0x4 << 12) /* Burst Read Latency: 4 cycles */ + | (0x0 << 9) /* Burst Length: continuous */ + | (0x1 << 7) /* RDY signal plarity */ + | (0x1 << 6) /* INT signal plarity */ + | (0x0 << 5) /* I/O buffer disable */ + ; + onenand_writew(value, THIS_ONENAND(ONENAND_REG_SYS_CFG1)); + + value = 0 + | (0 << 16) /* Asynchronous Read */ + | (1 << 12) /* PGWST/WELEN */ + | (1 << 8) /* WRWST */ + | (3 << 4) /* RDWST */ + | (1 << 0) /* FCLKDIV => 48MHz */ + ; + SET_EMIFS_CS_CONFIG(value); +} +#else +#define set_sync_burst_read(...) do { } while (0) +#define set_async_read(...) do { } while (0) +#endif + +int +onenand_chip() +{ + unsigned short mf_id, dev_id; + mf_id = (*(volatile unsigned short *)(THIS_ONENAND(ONENAND_REG_MANUFACTURER_ID))); + dev_id = (*(volatile unsigned short *)(THIS_ONENAND(ONENAND_REG_DEVICE_ID))); + + if(mf_id == SAMSUNG_MFR_ID) { + if (dev_id == KFM1G16Q2A_DEV_ID) { + printf("Detected Samsung MuxOneNAND1G Flash \r\n"); + return 0; + } else if (dev_id == KFN2G16Q2A_DEV_ID) { + printf("Detected Samsung MuxOneNAND2G Flash \r\n"); + return 0; + } else { + printf(" ONENAND Flash unsupported\r\n"); + return 1; + } + } else { + printf("ONENAND Flash Unsupported\r\n"); + return 1; + } +} + +/* read a page with ECC */ +static inline int onenand_read_page(ulong block, ulong page, u_char *buf) +{ + unsigned long *base; + +#ifndef __HAVE_ARCH_MEMCPY32 + unsigned int offset, value; + unsigned long *p; + unsigned int ctrl, ecc; + unsigned short bbmarker; +#endif + + onenand_writew(onenand_block_address(block), + THIS_ONENAND(ONENAND_REG_START_ADDRESS1)); + + onenand_writew(onenand_sector_address(page), + THIS_ONENAND(ONENAND_REG_START_ADDRESS8)); + + onenand_writew(onenand_buffer_address(), + THIS_ONENAND(ONENAND_REG_START_BUFFER)); + + onenand_writew(onenand_bufferram_address(block), + THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); + + onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT)); + + onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND)); + +#ifndef __HAVE_ARCH_MEMCPY32 + p = (unsigned long *) buf; +#endif + base = (unsigned long *) (ONENAND_ADDR + ONENAND_DATARAM); + + while (!(READ_INTERRUPT() & ONENAND_INT_MASTER)) + continue; + /* Check if the block is bad. Bad block markers */ + /* are stored in spare area of 1st or 2nd page */ + if ((page == 0) || (page == 1)) + { + unsigned long *spareArea = (unsigned long *) (ONENAND_ADDR + ONENAND_SPARERAM); + bbmarker = *spareArea; + /* for bad block markers */ + if (bbmarker != 0xFFFF){ + return 1; + } + } + + ctrl = READ_CTRL_STATUS(); + + if (ctrl & ONENAND_CTRL_ERROR) { + hang(); + } + + if (READ_INTERRUPT() & ONENAND_INT_READ) { + + ecc = READ_ECC_STATUS(); + if (ecc & ONENAND_ECC_2BIT_ALL) { + hang(); + } + } + +#ifdef __HAVE_ARCH_MEMCPY32 + /* 32 bytes boundary memory copy */ + memcpy32(buf, base, ONENAND_PAGE_SIZE); +#else + for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) { + value = *(base + offset); + *p++ = value; + } +#endif + + return 0; +} + +#define ONENAND_START_PAGE 0 +#define ONENAND_PAGES_PER_BLOCK 64 + +/** + * onenand_read_block - Read a block data to buf + * @return 0 on sucess + */ + +int onenand_read_block(unsigned char *buf, ulong block) +{ + int page, offset = 0; + + set_sync_burst_read(); + + /* NOTE: you must read page from page 1 of block 0 */ + /* read the block page by page*/ + for (page = ONENAND_START_PAGE; + page < ONENAND_PAGES_PER_BLOCK; page++) { + + if (onenand_read_page(block, page, buf + offset)){ + set_async_read(); + return 1; + } + + offset += ONENAND_PAGE_SIZE; + } + + set_async_read(); + + return 0; +} + +#endif /* defined(CFG_MMC_ONENAND) || defined(CFG_GPMC_ONENAND) */
diff --git a/x-loader/drivers/mtd/onenand/onenand_regs.h b/x-loader/drivers/mtd/onenand/onenand_regs.h new file mode 100644 index 0000000..d8acc8c --- /dev/null +++ b/x-loader/drivers/mtd/onenand/onenand_regs.h
@@ -0,0 +1,167 @@ +/* + * linux/include/linux/mtd/onenand_regs.h + * + * OneNAND Register header file + * + * Copyright (C) 2005 Samsung Electronics + * + * 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. + */ + +#ifndef __ONENAND_REG_H +#define __ONENAND_REG_H + +/* Memory Address Map Translation (Word order) */ +#define ONENAND_MEMORY_MAP(x) ((x) << 1) + +/* + * External BufferRAM area + */ +#define ONENAND_BOOTRAM ONENAND_MEMORY_MAP(0x0000) +#define ONENAND_DATARAM ONENAND_MEMORY_MAP(0x0200) +#define ONENAND_SPARERAM ONENAND_MEMORY_MAP(0x8010) + +/* + * OneNAND Registers + */ +#define ONENAND_REG_MANUFACTURER_ID ONENAND_MEMORY_MAP(0xF000) +#define ONENAND_REG_DEVICE_ID ONENAND_MEMORY_MAP(0xF001) +#define ONENAND_REG_VERSION_ID ONENAND_MEMORY_MAP(0xF002) +#define ONENAND_REG_DATA_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF003) +#define ONENAND_REG_BOOT_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF004) +#define ONENAND_REG_NUM_BUFFERS ONENAND_MEMORY_MAP(0xF005) +#define ONENAND_REG_TECHNOLOGY ONENAND_MEMORY_MAP(0xF006) + +#define ONENAND_REG_START_ADDRESS1 ONENAND_MEMORY_MAP(0xF100) +#define ONENAND_REG_START_ADDRESS2 ONENAND_MEMORY_MAP(0xF101) +#define ONENAND_REG_START_ADDRESS3 ONENAND_MEMORY_MAP(0xF102) +#define ONENAND_REG_START_ADDRESS4 ONENAND_MEMORY_MAP(0xF103) +#define ONENAND_REG_START_ADDRESS5 ONENAND_MEMORY_MAP(0xF104) +#define ONENAND_REG_START_ADDRESS6 ONENAND_MEMORY_MAP(0xF105) +#define ONENAND_REG_START_ADDRESS7 ONENAND_MEMORY_MAP(0xF106) +#define ONENAND_REG_START_ADDRESS8 ONENAND_MEMORY_MAP(0xF107) + +#define ONENAND_REG_START_BUFFER ONENAND_MEMORY_MAP(0xF200) +#define ONENAND_REG_COMMAND ONENAND_MEMORY_MAP(0xF220) +#define ONENAND_REG_SYS_CFG1 ONENAND_MEMORY_MAP(0xF221) +#define ONENAND_REG_SYS_CFG2 ONENAND_MEMORY_MAP(0xF222) +#define ONENAND_REG_CTRL_STATUS ONENAND_MEMORY_MAP(0xF240) +#define ONENAND_REG_INTERRUPT ONENAND_MEMORY_MAP(0xF241) +#define ONENAND_REG_START_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24C) +#define ONENAND_REG_END_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24D) +#define ONENAND_REG_WP_STATUS ONENAND_MEMORY_MAP(0xF24E) + +#define ONENAND_REG_ECC_STATUS ONENAND_MEMORY_MAP(0xFF00) +#define ONENAND_REG_ECC_M0 ONENAND_MEMORY_MAP(0xFF01) +#define ONENAND_REG_ECC_S0 ONENAND_MEMORY_MAP(0xFF02) +#define ONENAND_REG_ECC_M1 ONENAND_MEMORY_MAP(0xFF03) +#define ONENAND_REG_ECC_S1 ONENAND_MEMORY_MAP(0xFF04) +#define ONENAND_REG_ECC_M2 ONENAND_MEMORY_MAP(0xFF05) +#define ONENAND_REG_ECC_S2 ONENAND_MEMORY_MAP(0xFF06) +#define ONENAND_REG_ECC_M3 ONENAND_MEMORY_MAP(0xFF07) +#define ONENAND_REG_ECC_S3 ONENAND_MEMORY_MAP(0xFF08) + +/* + * Device ID Register F001h (R) + */ +#define ONENAND_DEVICE_DENSITY_SHIFT (4) +#define ONENAND_DEVICE_IS_DDP (1 << 3) +#define ONENAND_DEVICE_IS_DEMUX (1 << 2) +#define ONENAND_DEVICE_VCC_MASK (0x3) + +#define ONENAND_DEVICE_DENSITY_512Mb (0x002) + +/* + * Version ID Register F002h (R) + */ +#define ONENAND_VERSION_PROCESS_SHIFT (8) + +/* + * Start Address 1 F100h (R/W) + */ +#define ONENAND_DDP_SHIFT (15) + +/* + * Start Address 8 F107h (R/W) + */ +#define ONENAND_FPA_MASK (0x3f) +#define ONENAND_FPA_SHIFT (2) +#define ONENAND_FSA_MASK (0x03) + +/* + * Start Buffer Register F200h (R/W) + */ +#define ONENAND_BSA_MASK (0x03) +#define ONENAND_BSA_SHIFT (8) +#define ONENAND_BSA_BOOTRAM (0 << 2) +#define ONENAND_BSA_DATARAM0 (2 << 2) +#define ONENAND_BSA_DATARAM1 (3 << 2) +#define ONENAND_BSC_MASK (0x03) + +/* + * Command Register F220h (R/W) + */ +#define ONENAND_CMD_READ (0x00) +#define ONENAND_CMD_READOOB (0x13) +#define ONENAND_CMD_PROG (0x80) +#define ONENAND_CMD_PROGOOB (0x1A) +#define ONENAND_CMD_UNLOCK (0x23) +#define ONENAND_CMD_LOCK (0x2A) +#define ONENAND_CMD_LOCK_TIGHT (0x2C) +#define ONENAND_CMD_ERASE (0x94) +#define ONENAND_CMD_RESET (0xF0) +#define ONENAND_CMD_READID (0x90) + +/* NOTE: Those are not *REAL* commands */ +#define ONENAND_CMD_BUFFERRAM (0x1978) + +/* + * System Configuration 1 Register F221h (R, R/W) + */ +#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15) +#define ONENAND_SYS_CFG1_BRL (12) +#define ONENAND_SYS_CFG1_BL (9) +#define ONENAND_SYS_CFG1_NO_ECC (1 << 8) +#define ONENAND_SYS_CFG1_RDY (1 << 7) +#define ONENAND_SYS_CFG1_INT (1 << 6) +#define ONENAND_SYS_CFG1_IOBE (1 << 5) +#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) + +/* + * Controller Status Register F240h (R) + */ +#define ONENAND_CTRL_ONGO (1 << 15) +#define ONENAND_CTRL_LOCK (1 << 14) +#define ONENAND_CTRL_LOAD (1 << 13) +#define ONENAND_CTRL_PROGRAM (1 << 12) +#define ONENAND_CTRL_ERASE (1 << 11) +#define ONENAND_CTRL_ERROR (1 << 10) +#define ONENAND_CTRL_RSTB (1 << 7) + +/* + * Interrupt Status Register F241h (R) + */ +#define ONENAND_INT_MASTER (1 << 15) +#define ONENAND_INT_READ (1 << 7) +#define ONENAND_INT_WRITE (1 << 6) +#define ONENAND_INT_ERASE (1 << 5) +#define ONENAND_INT_RESET (1 << 4) +#define ONENAND_INT_CLEAR (0 << 0) + +/* + * NAND Flash Write Protection Status Register F24Eh (R) + */ +#define ONENAND_WP_US (1 << 2) +#define ONENAND_WP_LS (1 << 1) +#define ONENAND_WP_LTS (1 << 0) + +/* + * ECC Status Reigser FF00h (R) + */ +#define ONENAND_ECC_1BIT (1 << 0) +#define ONENAND_ECC_2BIT (1 << 1) +#define ONENAND_ECC_2BIT_ALL (0xAAAA) + +#endif /* __ONENAND_REG_H */
diff --git a/x-loader/drivers/rtc/Makefile b/x-loader/drivers/rtc/Makefile new file mode 100644 index 0000000..cb3144f --- /dev/null +++ b/x-loader/drivers/rtc/Makefile
@@ -0,0 +1,46 @@ +# +# (C) Copyright 2001-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)librtc.a + +COBJS-y += date.o + +COBJS := $(sort $(COBJS-y)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/drivers/rtc/date.c b/x-loader/drivers/rtc/date.c new file mode 100644 index 0000000..d30ad92 --- /dev/null +++ b/x-loader/drivers/rtc/date.c
@@ -0,0 +1,156 @@ +/* + * (C) Copyright 2001 + * 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 + */ + +/* + * Date & Time support for Philips PCF8563 RTC + */ + +#include <common.h> +#include <command.h> +#include <rtc.h> + +#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP) + +#define FEBRUARY 2 +#define STARTOFTIME 1970 +#define SECDAY 86400L +#define SECYR (SECDAY * 365) +#define leapyear(year) ((year) % 4 == 0) +#define days_in_year(a) (leapyear(a) ? 366 : 365) +#define days_in_month(a) (month_days[(a) - 1]) + +static int month_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +/* + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) + */ +void GregorianDay(struct rtc_time * tm) +{ + int leapsToDate; + int lastYear; + int day; + int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 }; + + lastYear=tm->tm_year-1; + + /* + * Number of leap corrections to apply up to end of last year + */ + leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; + + /* + * This year is a leap year if it is divisible by 4 except when it is + * divisible by 100 unless it is divisible by 400 + * + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be + */ + if((tm->tm_year%4==0) && + ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && + (tm->tm_mon>2)) { + /* + * We are past Feb. 29 in a leap year + */ + day=1; + } else { + day=0; + } + + day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; + + tm->tm_wday=day%7; +} + +void to_tm(int tim, struct rtc_time * tm) +{ + register int i; + register long hms, day; + + day = tim / SECDAY; + hms = tim % SECDAY; + + /* Hours, minutes, seconds are easy */ + tm->tm_hour = hms / 3600; + tm->tm_min = (hms % 3600) / 60; + tm->tm_sec = (hms % 3600) % 60; + + /* Number of years in days */ + for (i = STARTOFTIME; day >= days_in_year(i); i++) { + day -= days_in_year(i); + } + tm->tm_year = i; + + /* Number of months in days left */ + if (leapyear(tm->tm_year)) { + days_in_month(FEBRUARY) = 29; + } + for (i = 1; day >= days_in_month(i); i++) { + day -= days_in_month(i); + } + days_in_month(FEBRUARY) = 28; + tm->tm_mon = i; + + /* Days are what is left over (+1) from all that. */ + tm->tm_mday = day + 1; + + /* + * Determine the day of week + */ + GregorianDay(tm); +} + +/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * WARNING: this function will overflow on 2106-02-07 06:28:16 on + * machines were long is 32-bit! (However, as time_t is signed, we + * will already get problems at other places on 2038-01-19 03:14:08) + */ +unsigned long +mktime (unsigned int year, unsigned int mon, + unsigned int day, unsigned int hour, + unsigned int min, unsigned int sec) +{ + if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + + return ((( + (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + + year*365 - 719499 + )*24 + hour /* now have hours */ + )*60 + min /* now have minutes */ + )*60 + sec; /* finally seconds */ +} + +#endif
diff --git a/x-loader/drivers/serial/Makefile b/x-loader/drivers/serial/Makefile new file mode 100644 index 0000000..2884be4 --- /dev/null +++ b/x-loader/drivers/serial/Makefile
@@ -0,0 +1,47 @@ +# +# (C) Copyright 2006-2009 +# 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)libserial.a + +COBJS-y += ns16550.o +COBJS-y += serial.o + +COBJS := $(sort $(COBJS-y)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/drivers/serial/ns16550.c b/x-loader/drivers/serial/ns16550.c new file mode 100644 index 0000000..b5a5c12 --- /dev/null +++ b/x-loader/drivers/serial/ns16550.c
@@ -0,0 +1,69 @@ +/* + * This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * COM1 NS16550 support + * originally from linux source (arch/ppc/boot/ns16550.c) + * modified to use CFG_ISA_MEM and new defines + */ + +#include <config.h> + +#ifdef CFG_PRINTF +#ifdef CFG_NS16550 + +#include <ns16550.h> + +#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */ +#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */ +#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */ + +void NS16550_init (NS16550_t com_port, int baud_divisor) +{ + com_port->ier = 0x00; +#ifdef CONFIG_OMAP + com_port->mdr1 = 0x7; /* mode select reset TL16C750*/ +#endif + com_port->lcr = LCR_BKSE | LCRVAL; + com_port->dll = baud_divisor & 0xff; + com_port->dlm = (baud_divisor >> 8) & 0xff; + com_port->lcr = LCRVAL; + com_port->mcr = MCRVAL; + com_port->fcr = FCRVAL; +#if defined(CONFIG_OMAP) + com_port->mdr1 = 0; /* select uart mode */ +#endif +} + +void NS16550_reinit (NS16550_t com_port, int baud_divisor) +{ + com_port->ier = 0x00; + com_port->lcr = LCR_BKSE; + com_port->dll = baud_divisor & 0xff; + com_port->dlm = (baud_divisor >> 8) & 0xff; + com_port->lcr = LCRVAL; + com_port->mcr = MCRVAL; + com_port->fcr = FCRVAL; +} + +void NS16550_putc (NS16550_t com_port, char c) +{ + while ((com_port->lsr & LSR_THRE) == 0); + com_port->thr = c; +} + +char NS16550_getc (NS16550_t com_port) +{ + while ((com_port->lsr & LSR_DR) == 0); + return (com_port->rbr); +} + +int NS16550_tstc (NS16550_t com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} + +#endif +#endif
diff --git a/x-loader/drivers/serial/serial.c b/x-loader/drivers/serial/serial.c new file mode 100644 index 0000000..b9ecf2a --- /dev/null +++ b/x-loader/drivers/serial/serial.c
@@ -0,0 +1,119 @@ +/* + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems. robt@flyingpig.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> + +#ifdef CFG_PRINTF +#ifdef CFG_NS16550_SERIAL + +#include <ns16550.h> +#ifdef CFG_NS87308 +#include <ns87308.h> +#endif + +#if CONFIG_CONS_INDEX == 1 +static NS16550_t console = (NS16550_t) CFG_NS16550_COM1; +#elif CONFIG_CONS_INDEX == 2 +static NS16550_t console = (NS16550_t) CFG_NS16550_COM2; +#elif CONFIG_CONS_INDEX == 3 +static NS16550_t console = (NS16550_t) CFG_NS16550_COM3; +#elif CONFIG_CONS_INDEX == 4 +static NS16550_t console = (NS16550_t) CFG_NS16550_COM4; +#else +#error no valid console defined +#endif + +static int calc_divisor (void) +{ +// DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_OMAP1510 + /* If can't cleanly clock 115200 set div to 1 */ + if ((CFG_NS16550_CLK == 12000000) && (CONFIG_BAUDRATE == 115200)) { + console->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */ + return (1); /* return 1 for base divisor */ + } + console->osc_12m_sel = 0; /* clear if previsouly set */ +#endif +#if defined(CONFIG_OMAP1610) || defined(CONFIG_OMAP1710) + /* If can't cleanly clock 115200 set div to 1 */ + if ((CFG_NS16550_CLK == 48000000) && (CONFIG_BAUDRATE == 115200)) { + return (26); /* return 26 for base divisor */ + } +#endif + return (CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE); +} + +int serial_init (void) +{ + int clock_divisor = calc_divisor(); + +#ifdef CFG_NS87308 + initialise_ns87308(); +#endif + + NS16550_init(console, clock_divisor); + + return (0); +} + +void +serial_putc(const char c) +{ + if (c == '\n') + NS16550_putc(console, '\r'); + + NS16550_putc(console, c); +} + +void +serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } +} + + +int +serial_getc(void) +{ + return NS16550_getc(console); +} + +int +serial_tstc(void) +{ + return NS16550_tstc(console); +} + +void +serial_setbrg (void) +{ + int clock_divisor; + + clock_divisor = calc_divisor(); + NS16550_reinit(console, clock_divisor); +} + +#endif +#endif
diff --git a/x-loader/drivers/usb/Makefile b/x-loader/drivers/usb/Makefile new file mode 100644 index 0000000..549d101 --- /dev/null +++ b/x-loader/drivers/usb/Makefile
@@ -0,0 +1,46 @@ +# +# (C) Copyright 2006-2009 +# 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)libusb.a + +COBJS-y += usb.o + +COBJS := $(sort $(COBJS-y)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/drivers/usb/usb.c b/x-loader/drivers/usb/usb.c new file mode 100644 index 0000000..99f467f --- /dev/null +++ b/x-loader/drivers/usb/usb.c
@@ -0,0 +1,168 @@ +/* + * USB bootloader + * + * Copyright (C) 2011 Rick Bronson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include <common.h> +#include <malloc.h> +#include <asm/arch/cpu.h> /* get chip and board defs */ +#include "usb.h" + +extern void udelay (unsigned long usecs); + +typedef int boot_os_fn (void); + +/* send a packet via USB */ +int usb_send_packet(unsigned char *buffer, unsigned int packet_size) + { + int ret = 0; + + if (!(*peri_txcsr & MUSB_TXCSR_TXPKTRDY)) + { + unsigned int cntr; + + for (cntr = 0; cntr < packet_size; cntr++) + *bulk_fifo = buffer[cntr]; + + *peri_txcsr |= MUSB_TXCSR_TXPKTRDY; + + ret = packet_size; + } + return ret; + } + +//////////////////// + +static int usb_recv (u8 *buffer, int size) +{ + int cntr; + u16 count = 0; + + if (*peri_rxcsr & MUSB_RXCSR_RXPKTRDY) + { + count = *rxcount; + for (cntr = 0; cntr < count; cntr++) + { + *buffer++ = *bulk_fifo; + } + /* Clear the RXPKTRDY bit */ + *peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY; + } + return count; /* FIXME */ +} + +static unsigned char usb_outbuffer[RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0]; + +int usb_send_buffer(unsigned char *buffer, unsigned int buffer_size) +{ + int buffer_index = 0, + packet_size, + retval = 0; + + while ((buffer_index < buffer_size) && + (retval == 0)) { + packet_size = RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0; + if ((buffer_index + packet_size) > buffer_size) + packet_size = buffer_size - buffer_index; + + retval = usb_send_packet(&buffer[buffer_index], packet_size); + if (retval == packet_size) { + buffer_index += packet_size; + retval = 0; + } + } + + return buffer_index; +} + +static void usb_msg (unsigned int cmd, const char *msg) + { + unsigned char *p_char = usb_outbuffer; + + * (int *) p_char = cmd; + p_char += sizeof (cmd); + if (msg) + { + while (*msg) + *p_char++= *msg++; + *p_char++= 0; + } + usb_send_packet (usb_outbuffer, p_char - usb_outbuffer); + } + +static void usb_code (unsigned int cmd, u32 code1, u32 code2) + { + unsigned int *p_int = (unsigned int *) usb_outbuffer; + + *p_int++ = cmd; + *p_int++ = code1; + *p_int++ = code2; + usb_send_packet (usb_outbuffer, ((unsigned char *) p_int) - usb_outbuffer); + } + +void do_usb (void) + { + boot_os_fn *boot_fn; + int res; + u32 usb_inbuffer[RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0]; + u32 total; + u8 *addr; + u32 bytes; + int cntr = 0; + + usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); + while(++cntr < 200000) /* try for 1 second then bail out */ + { + res = usb_recv ((u8 *) usb_inbuffer, sizeof (usb_inbuffer)); + if ((res == USBLOAD_CMD_RESPONSE_LEN) && (usb_inbuffer[0] == USBLOAD_CMD_FILE)) + { + total = usb_inbuffer[1]; /* get size and address */ + addr = (u8 *) usb_inbuffer[2]; + printf ("USBLOAD_CMD_FILE: %8uB @ 0x%x\n", + total, + addr); + usb_code (USBLOAD_CMD_ECHO_SZ, total, 0); + + bytes = 0; + while (bytes < total) + { + bytes += usb_recv(&((u8 *)addr)[bytes], (total - bytes)); + } + usb_code (USBLOAD_CMD_REPORT_SZ, total, 0); /* tell him we got this many bytes */ + printf ("Received file OK\n"); + usb_msg (USBLOAD_CMD_FILE_REQ, "file req"); /* see if they have another file for us */ + cntr = 0; + } + else if ((res == USBLOAD_CMD_RESPONSE_LEN) && (usb_inbuffer[0] == USBLOAD_CMD_JUMP)) + { + printf ("USBLOAD_CMD_JUMP: addr = 0x%x\n", usb_inbuffer[1]); + boot_fn = (boot_os_fn *) usb_inbuffer[1]; + boot_fn(); /* go to u-boot and maybe kernel */ + } + else if (res > 0) + { + printf ("Unrecognized %dB command: %c%c%c%c\n", res, + ((char*)usb_inbuffer)[0], ((char*)usb_inbuffer)[1], ((char*)usb_inbuffer)[2], ((char*)usb_inbuffer)[3]); + } + + udelay(1000); /* delay 1 ms -- suspect clocks aren't configured as expected, resulting in a significantly shorter delay */ + } + printf("USB done\n"); + hang(); + }
diff --git a/x-loader/drivers/usb/usb.h b/x-loader/drivers/usb/usb.h new file mode 100644 index 0000000..1a64ea3 --- /dev/null +++ b/x-loader/drivers/usb/usb.h
@@ -0,0 +1,69 @@ +/* + * USB bootloader + * + * Copyright (C) 2011 Rick Bronson + * + * 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 _USB_H_ +#define _USB_H_ + +#define OMAP34XX_USB_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000) + +#define OMAP34XX_USB_EP(n) (OMAP34XX_USB_BASE + 0x100 + 0x10*(n)) + +#define MUSB_RXCSR 0x06 +#define MUSB_RXCOUNT 0x08 +#define MUSB_TXCSR 0x02 +#define MUSB_FIFOSIZE 0x0F +#define OMAP34XX_USB_RXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_RXCSR) +#define OMAP34XX_USB_RXCOUNT(n) (OMAP34XX_USB_EP(n) + MUSB_RXCOUNT) +#define OMAP34XX_USB_TXCSR(n) (OMAP34XX_USB_EP(n) + MUSB_TXCSR) +#define OMAP34XX_USB_FIFOSIZE(n) (OMAP34XX_USB_EP(n) + MUSB_FIFOSIZE) +#define OMAP34XX_USB_FIFO(n) (OMAP34XX_USB_BASE + 0x20 + ((n) * 4)) + +/* memory mapped registers */ +#define BULK_ENDPOINT 1 +static volatile u16 *peri_rxcsr = (volatile u16 *) OMAP34XX_USB_RXCSR(BULK_ENDPOINT); +#define MUSB_RXCSR_RXPKTRDY 0x0001 +static volatile u16 *rxcount = (volatile u16 *) OMAP34XX_USB_RXCOUNT(BULK_ENDPOINT); +static volatile u16 *peri_txcsr = (volatile u16 *) OMAP34XX_USB_TXCSR(BULK_ENDPOINT); +#define MUSB_TXCSR_TXPKTRDY 0x0001 +static volatile u8 *bulk_fifo = (volatile u8 *) OMAP34XX_USB_FIFO(BULK_ENDPOINT); + +/* In high speed mode packets are 512 + In full speed mode packets are 64 */ +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0 (0x0200) +#define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1 (0x0040) + +#define MIN(a,b) ( ((a) < (b)) ? (a) : (b)) + +#define PACK4(a,b,c,d) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) +#define USBLOAD_CMD_FILE PACK4('U', 'S', 'B', 's') /* send file size */ +#define USBLOAD_CMD_JUMP PACK4('U', 'S', 'B', 'j') /* go where I tell you */ +#define USBLOAD_CMD_FILE_REQ PACK4('U', 'S', 'B', 'f') /* file request */ +#define USBLOAD_CMD_ECHO_SZ PACK4('U', 'S', 'B', 'n') /* echo file size */ +#define USBLOAD_CMD_REPORT_SZ PACK4('U', 'S', 'B', 'o') /* report file size */ +#define USBLOAD_CMD_MESSAGE PACK4('U', 'S', 'B', 'm') /* message for debug */ +#define USBLOAD_CMD_NAND_DUMP PACK4('U', 'S', 'B', 'd') /* dump NAND */ +#define USBLOAD_CMD_NAND_OOB_DUMP PACK4('U', 'S', 'B', 'b') /* dump NAND OOB */ +#define USBLOAD_CMD_NAND_DUMP_SZ PACK4('U', 'S', 'B', 'r') /* dump size */ + +#define USBLOAD_CMD_RESPONSE_LEN 12 + +#endif +
diff --git a/x-loader/fs/Makefile b/x-loader/fs/Makefile new file mode 100755 index 0000000..f419b99 --- /dev/null +++ b/x-loader/fs/Makefile
@@ -0,0 +1,29 @@ +# +# (C) Copyright 2000, 2001 +# 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 +# +# + +SUBDIRS := fat + +.depend all: + @for dir in $(SUBDIRS) ; do \ + $(MAKE) -C $$dir $@ ; done
diff --git a/x-loader/fs/fat/Makefile b/x-loader/fs/fat/Makefile new file mode 100755 index 0000000..87af73b --- /dev/null +++ b/x-loader/fs/fat/Makefile
@@ -0,0 +1,45 @@ +# +# +# 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)libfat.a + +AOBJS = +COBJS = fat.o file.o + +SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS)) + +all: $(LIB) $(AOBJS) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/fs/fat/fat.c b/x-loader/fs/fat/fat.c new file mode 100755 index 0000000..5363881 --- /dev/null +++ b/x-loader/fs/fat/fat.c
@@ -0,0 +1,928 @@ +/* + * fat.c + * + * R/O (V)FAT 12/16/32 filesystem implementation by Marcus Sundberg + * + * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 + * 2003-03-10 - kharris@nexus-tech.net - ported to uboot + * + * 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 <config.h> +#include <part.h> +#include <fat.h> +#include <asm/byteorder.h> + +#ifdef CFG_CMD_FAT + +/* + * Convert a string to lowercase. + */ +static void +downcase(char *str) +{ + while (*str != '\0') { + TOLOWER(*str); + str++; + } +} + +static block_dev_desc_t *cur_dev = NULL; +static unsigned long part_offset = 0; +static int cur_part = 1; + +#define DOS_PART_TBL_OFFSET 0x1be +#define DOS_PART_MAGIC_OFFSET 0x1fe +#define DOS_FS_TYPE_OFFSET 0x52 + +int strncmp(const char * cs,const char * ct,size_t count) +{ + register signed char __res = 0; + + while (count) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + + return __res; +} + +char * strcpy(char * dest,const char *src) +{ + char *tmp = dest; + + while ((*dest++ = *src++) != '\0') + /* nothing */; + return tmp; +} + +int strcmp(const char * cs,const char * ct) +{ + register signed char __res; + + while (1) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + } + + return __res; +} +void * memcpy(void * dest,const void *src,size_t count) +{ + char *tmp = (char *) dest, *s = (char *) src; + + while (count--) + *tmp++ = *s++; + + return dest; +} + + +int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr) +{ + startblock += part_offset; + if (cur_dev == NULL) + return -1; + if (cur_dev->block_read) { + return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr); + } + return -1; +} + + +int +fat_register_device(block_dev_desc_t *dev_desc, int part_no) +{ + unsigned char buffer[SECTOR_SIZE]; + + if (!dev_desc->block_read) + return -1; + cur_dev=dev_desc; + /* check if we have a MBR (on floppies we have only a PBR) */ + if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { + printf ("** Can't read from device %d **\n", dev_desc->dev); + return -1; + } + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { + /* no signature found */ + return -1; + } + if(!strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) { + /* ok, we assume we are on a PBR only */ + cur_part = 1; + part_offset=0; + } + else { +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ + (CONFIG_COMMANDS & CFG_CMD_USB) || (CONFIG_COMMANDS & CFG_CMD_MMC) || defined(CONFIG_SYSTEMACE) + disk_partition_t info; + if(!get_partition_info(dev_desc, part_no, &info)) { + part_offset = info.start; + cur_part = part_no; + } + else { + printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev); + return -1; + } +#else + /* FIXME we need to determine the start block of the + * partition where the DOS FS resides. This can be done + * by using the get_partition_info routine. For this + * purpose the libpart must be included. + */ + part_offset=63; + //part_offset=0; + cur_part = 1; +#endif + } + return 0; +} + + +/* + * Get the first occurence of a directory delimiter ('/' or '\') in a string. + * Return index into string if found, -1 otherwise. + */ +static int +dirdelim(char *str) +{ + char *start = str; + + while (*str != '\0') { + if (ISDIRDELIM(*str)) return str - start; + str++; + } + return -1; +} + + +/* + * Match volume_info fs_type strings. + * Return 0 on match, -1 otherwise. + */ +static int +compare_sign(char *str1, char *str2) +{ + char *end = str1+SIGNLEN; + + while (str1 != end) { + if (*str1 != *str2) { + return -1; + } + str1++; + str2++; + } + + return 0; +} + + +/* + * Extract zero terminated short name from a directory entry. + */ +static void get_name (dir_entry *dirent, char *s_name) +{ + char *ptr; + + memcpy (s_name, dirent->name, 8); + s_name[8] = '\0'; + ptr = s_name; + while (*ptr && *ptr != ' ') + ptr++; + if (dirent->ext[0] && dirent->ext[0] != ' ') { + *ptr = '.'; + ptr++; + memcpy (ptr, dirent->ext, 3); + ptr[3] = '\0'; + while (*ptr && *ptr != ' ') + ptr++; + } + *ptr = '\0'; + if (*s_name == DELETED_FLAG) + *s_name = '\0'; + else if (*s_name == aRING) + *s_name = 'å'; + downcase (s_name); +} + +/* + * Get the entry at index 'entry' in a FAT (12/16/32) table. + * On failure 0x00 is returned. + */ +static __u32 +get_fatent(fsdata *mydata, __u32 entry) +{ + __u32 bufnum; + __u32 offset; + __u32 ret = 0x00; + + switch (mydata->fatsize) { + case 32: + bufnum = entry / FAT32BUFSIZE; + offset = entry - bufnum * FAT32BUFSIZE; + break; + case 16: + bufnum = entry / FAT16BUFSIZE; + offset = entry - bufnum * FAT16BUFSIZE; + break; + case 12: + bufnum = entry / FAT12BUFSIZE; + offset = entry - bufnum * FAT12BUFSIZE; + break; + + default: + /* Unsupported FAT size */ + return ret; + } + /* Read a new block of FAT entries into the cache. */ + if (bufnum != mydata->fatbufnum) { + int getsize = FATBUFSIZE/FS_BLOCK_SIZE; + __u8 *bufptr = (__u8 *)mydata->fatbuf; + __u32 fatlength = mydata->fatlength; + __u32 startblock = bufnum * FATBUFBLOCKS; + + fatlength *= SECTOR_SIZE; /* We want it in bytes now */ + startblock += mydata->fat_sect; /* Offset from start of disk */ + + if (getsize > fatlength) getsize = fatlength; + if (disk_read(startblock, getsize, bufptr) < 0) { + FAT_DPRINT("Error reading FAT blocks\n"); + return ret; + } + mydata->fatbufnum = bufnum; + } + + /* Get the actual entry from the table */ + switch (mydata->fatsize) { + case 32: + ret = FAT2CPU32(((__u32*)mydata->fatbuf)[offset]); + break; + case 16: + ret = FAT2CPU16(((__u16*)mydata->fatbuf)[offset]); + break; + case 12: { + __u32 off16 = (offset*3)/4; + __u16 val1, val2; + + switch (offset & 0x3) { + case 0: + ret = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); + ret &= 0xfff; + break; + case 1: + val1 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); + val1 &= 0xf000; + val2 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16+1]); + val2 &= 0x00ff; + ret = (val2 << 4) | (val1 >> 12); + break; + case 2: + val1 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]); + val1 &= 0xff00; + val2 = FAT2CPU16(((__u16*)mydata->fatbuf)[off16+1]); + val2 &= 0x000f; + ret = (val2 << 8) | (val1 >> 8); + break; + case 3: + ret = FAT2CPU16(((__u16*)mydata->fatbuf)[off16]);; + ret = (ret & 0xfff0) >> 4; + break; + default: + break; + } + } + break; + } + FAT_DPRINT("ret: %d, offset: %d\n", ret, offset); + + return ret; +} + + +/* + * Read at most 'size' bytes from the specified cluster into 'buffer'. + * Return 0 on success, -1 otherwise. + */ +static int +get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) +{ + int idx = 0; + __u32 startsect; + + if (clustnum > 0) { + startsect = mydata->data_begin + clustnum*mydata->clust_size; + } else { + startsect = mydata->rootdir_sect; + } + + if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) { + FAT_DPRINT("Error reading data\n"); + return -1; + } + if(size % FS_BLOCK_SIZE) { + __u8 tmpbuf[FS_BLOCK_SIZE]; + idx= size/FS_BLOCK_SIZE; + if (disk_read(startsect + idx, 1, tmpbuf) < 0) { + FAT_DPRINT("Error reading data\n"); + return -1; + } + buffer += idx*FS_BLOCK_SIZE; + + memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE); + return 0; + } + + return 0; +} + + +/* + * Read at most 'maxsize' bytes from the file associated with 'dentptr' + * into 'buffer'. + * Return the number of bytes read or -1 on fatal errors. + */ +static long +get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, + unsigned long maxsize) +{ + unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; + unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE; + __u32 curclust = START(dentptr); + __u32 endclust, newclust; + unsigned long actsize; + + FAT_DPRINT("Filesize: %ld bytes\n", filesize); + + if (maxsize > 0 && filesize > maxsize) filesize = maxsize; + + FAT_DPRINT("Reading: %ld bytes\n", filesize); + + actsize=bytesperclust; + endclust=curclust; + do { + /* search for consecutive clusters */ + while(actsize < filesize) { + newclust = get_fatent(mydata, endclust); + if((newclust -1)!=endclust) + goto getit; + if (newclust <= 0x0001 || newclust >= 0xfff0) { + FAT_DPRINT("curclust: 0x%x\n", newclust); + FAT_DPRINT("Invalid FAT entry\n"); + return gotsize; + } + endclust=newclust; + actsize+= bytesperclust; + } + /* actsize >= file size */ + actsize -= bytesperclust; + /* get remaining clusters */ + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { + FAT_ERROR("Error reading cluster\n"); + return -1; + } + /* get remaining bytes */ + gotsize += (int)actsize; + filesize -= actsize; + buffer += actsize; + actsize= filesize; + if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { + FAT_ERROR("Error reading cluster\n"); + return -1; + } + gotsize+=actsize; + return gotsize; +getit: + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { + FAT_ERROR("Error reading cluster\n"); + return -1; + } + gotsize += (int)actsize; + filesize -= actsize; + buffer += actsize; + curclust = get_fatent(mydata, endclust); + if (curclust <= 0x0001 || curclust >= 0xfff0) { + FAT_DPRINT("curclust: 0x%x\n", curclust); + FAT_ERROR("Invalid FAT entry\n"); + return gotsize; + } + actsize=bytesperclust; + endclust=curclust; + } while (1); +} + + +#ifdef CONFIG_SUPPORT_VFAT +#if 0 +/* + * Extract the file name information from 'slotptr' into 'l_name', + * starting at l_name[*idx]. + * Return 1 if terminator (zero byte) is found, 0 otherwise. + */ +static int +slot2str(dir_slot *slotptr, char *l_name, int *idx) +{ + int j; + + for (j = 0; j <= 8; j += 2) { + l_name[*idx] = slotptr->name0_4[j]; + if (l_name[*idx] == 0x00) return 1; + (*idx)++; + } + for (j = 0; j <= 10; j += 2) { + l_name[*idx] = slotptr->name5_10[j]; + if (l_name[*idx] == 0x00) return 1; + (*idx)++; + } + for (j = 0; j <= 2; j += 2) { + l_name[*idx] = slotptr->name11_12[j]; + if (l_name[*idx] == 0x00) return 1; + (*idx)++; + } + + return 0; +} +#endif +/* Calculate short name checksum */ +static __u8 +mkcksum(const char *str) +{ + int i; + __u8 ret = 0; + + for (i = 0; i < 11; i++) { + ret = (((ret&1)<<7)|((ret&0xfe)>>1)) + str[i]; + } + + return ret; +} +#endif + + +/* + * Get the directory entry associated with 'filename' from the directory + * starting at 'startsect' + */ + + +static dir_entry *get_dentfromdir (fsdata * mydata, int startsect, + char *filename, dir_entry * retdent, + int dols) +{ + return NULL; +} + +#if 0 +__u8 get_dentfromdir_block[MAX_CLUSTSIZE]; +static dir_entry *get_dentfromdir (fsdata * mydata, int startsect, + char *filename, dir_entry * retdent, + int dols) +{ + __u16 prevcksum = 0xffff; + __u32 curclust = START (retdent); + int files = 0, dirs = 0; + + while (1) { + dir_entry *dentptr; + int i; + + if (get_cluster (mydata, curclust, get_dentfromdir_block, + mydata->clust_size * SECTOR_SIZE) != 0) { + FAT_DPRINT ("Error: reading directory block\n"); + return NULL; + } + dentptr = (dir_entry *) get_dentfromdir_block; + for (i = 0; i < DIRENTSPERCLUST; i++) { + char s_name[14], l_name[256]; + + l_name[0] = '\0'; + if (dentptr->name[0] == DELETED_FLAG) { + dentptr++; + continue; + } + if ((dentptr->attr & ATTR_VOLUME)) { + /* Volume label or VFAT entry */ + dentptr++; + continue; + } + if (dentptr->name[0] == 0) { + if (dols) { + printf ("\n%d file(s), %d dir(s)\n\n", files, dirs); + } + FAT_DPRINT ("Dentname == NULL - %d\n", i); + return NULL; + } +#ifdef CONFIG_SUPPORT_VFAT + if (dols && mkcksum (dentptr->name) == prevcksum) { + dentptr++; + continue; + } +#endif + get_name (dentptr, s_name); + if (dols) { + int isdir = (dentptr->attr & ATTR_DIR); + char dirc; + int doit = 0; + + if (isdir) { + dirs++; + dirc = '/'; + doit = 1; + } else { + dirc = ' '; + if (s_name[0] != 0) { + files++; + doit = 1; + } + } + if (doit) { + if (dirc == ' ') { + printf (" %8ld %s%c\n", + (long) FAT2CPU32 (dentptr->size), s_name, + dirc); + } else { + printf (" %s%c\n", s_name, dirc); + } + } + dentptr++; + continue; + } + if (strcmp (filename, s_name) && strcmp (filename, l_name)) { + FAT_DPRINT ("Mismatch: |%s|%s|\n", s_name, l_name); + dentptr++; + continue; + } + memcpy (retdent, dentptr, sizeof (dir_entry)); + + FAT_DPRINT ("DentName: %s", s_name); + FAT_DPRINT (", start: 0x%x", START (dentptr)); + FAT_DPRINT (", size: 0x%x %s\n", + FAT2CPU32 (dentptr->size), + (dentptr->attr & ATTR_DIR) ? "(DIR)" : ""); + + return retdent; + } + curclust = get_fatent (mydata, curclust); + if (curclust <= 0x0001 || curclust >= 0xfff0) { + FAT_DPRINT ("curclust: 0x%x\n", curclust); + FAT_ERROR ("Invalid FAT entry\n"); + return NULL; + } + } + + return NULL; +} +#endif + + +/* + * Read boot sector and volume info from a FAT filesystem + */ +static int +read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) +{ + __u8 block[FS_BLOCK_SIZE]; + volume_info *vistart; + + printf("Reading boot sector\n"); + + if (disk_read(0, 1, block) < 0) { + FAT_DPRINT("Error: reading block\n"); + return -1; + } + + memcpy(bs, block, sizeof(boot_sector)); + bs->reserved = FAT2CPU16(bs->reserved); + bs->fat_length = FAT2CPU16(bs->fat_length); + bs->secs_track = FAT2CPU16(bs->secs_track); + bs->heads = FAT2CPU16(bs->heads); +#if 0 /* UNUSED */ + bs->hidden = FAT2CPU32(bs->hidden); +#endif + bs->total_sect = FAT2CPU32(bs->total_sect); + + /* FAT32 entries */ + if (bs->fat_length == 0) { + /* Assume FAT32 */ + bs->fat32_length = FAT2CPU32(bs->fat32_length); + bs->flags = FAT2CPU16(bs->flags); + bs->root_cluster = FAT2CPU32(bs->root_cluster); + bs->info_sector = FAT2CPU16(bs->info_sector); + bs->backup_boot = FAT2CPU16(bs->backup_boot); + vistart = (volume_info*) (block + sizeof(boot_sector)); + *fatsize = 32; + } else { + vistart = (volume_info*) &(bs->fat32_length); + *fatsize = 0; + } + memcpy(volinfo, vistart, sizeof(volume_info)); + + /* Terminate fs_type string. Writing past the end of vistart + is ok - it's just the buffer. */ + vistart->fs_type[7] = '\0'; + + if (*fatsize == 32) { + if (compare_sign(FAT32_SIGN, vistart->fs_type) == 0) { + return 0; + } + } else { + if (compare_sign(FAT12_SIGN, vistart->fs_type) == 0) { + *fatsize = 12; + return 0; + } + if (compare_sign(FAT16_SIGN, vistart->fs_type) == 0) { + *fatsize = 16; + return 0; + } + } + + FAT_DPRINT("Error: broken fs_type sign\n"); + return -1; +} + +#if 0 +__u8 do_fat_read_block[MAX_CLUSTSIZE]; /* Block buffer */ +#endif + +__u8 *fnamecopy = (__u8 *)0x80500000; +__u8 *do_fat_read_block = (__u8 *)0x80500880; + +boot_sector bs; +volume_info volinfo; +fsdata datablock; + +long +do_fat_read(const char *filename, void *buffer, unsigned long maxsize, + int dols) +{ +#if CONFIG_NIOS /* NIOS CPU cannot access big automatic arrays */ + static +#endif + fsdata *mydata = &datablock; + dir_entry *dentptr; + __u16 prevcksum = 0xffff; + char *subname = ""; + int rootdir_size, cursect; + int idx, isdir = 0; + int files = 0, dirs = 0; + long ret = 0; + int firsttime; + + if (read_bootsectandvi (&bs, &volinfo, &mydata->fatsize)) { + printf ("Error: reading boot sector\n"); + return -1; + } + if (mydata->fatsize == 32) { + mydata->fatlength = bs.fat32_length; + } else { + mydata->fatlength = bs.fat_length; + } + mydata->fat_sect = bs.reserved; + cursect = mydata->rootdir_sect + = mydata->fat_sect + mydata->fatlength * bs.fats; + mydata->clust_size = bs.cluster_size; + if (mydata->fatsize == 32) { + rootdir_size = mydata->clust_size; + mydata->data_begin = mydata->rootdir_sect /* + rootdir_size */ + - (mydata->clust_size * 2); + } else { + rootdir_size = ((bs.dir_entries[1] * (int) 256 + bs.dir_entries[0]) + * sizeof (dir_entry)) / SECTOR_SIZE; + mydata->data_begin = mydata->rootdir_sect + rootdir_size + - (mydata->clust_size * 2); + } + mydata->fatbufnum = -1; + + FAT_DPRINT ("FAT%d, fatlength: %d\n", mydata->fatsize, + mydata->fatlength); + FAT_DPRINT ("Rootdir begins at sector: %d, offset: %x, size: %d\n" + "Data begins at: %d\n", + mydata->rootdir_sect, mydata->rootdir_sect * SECTOR_SIZE, + rootdir_size, mydata->data_begin); + FAT_DPRINT ("Cluster size: %d\n", mydata->clust_size); + + /* "cwd" is always the root... */ + while (ISDIRDELIM (*filename)) + filename++; + /* Make a copy of the filename and convert it to lowercase */ + strcpy((char *)fnamecopy, filename); + downcase((char *)fnamecopy); + if (*fnamecopy == '\0') { + if (!dols){ + printf("\n not there\n"); + return -1; + } + dols = LS_ROOT; + } else if((idx = dirdelim((char *)fnamecopy)) >= 0) { + isdir = 1; + fnamecopy[idx] = '\0'; + subname = (char *)fnamecopy + idx + 1; + /* Handle multiple delimiters */ + while (ISDIRDELIM (*subname)) + subname++; + } else if (dols) { + isdir = 1; + } + + while (1) { + int i; + + if (disk_read (cursect, mydata->clust_size, do_fat_read_block) < 0) { + printf ("Error: reading rootdir block\n"); + return -1; + } + dentptr = (dir_entry *) do_fat_read_block; + for (i = 0; i < DIRENTSPERBLOCK; i++) { + char s_name[14], l_name[256]; + + l_name[0] = '\0'; + if ((dentptr->attr & ATTR_VOLUME)) { + /* Volume label or VFAT entry */ + dentptr++; + continue; + } else if (dentptr->name[0] == 0) { + FAT_DPRINT ("RootDentname == NULL - %d\n", i); + if (dols == LS_ROOT) { + printf ("\n%d file(s), %d dir(s)\n\n", files, dirs); + return 0; + } + return -1; + } +#ifdef CONFIG_SUPPORT_VFAT + else if (dols == LS_ROOT + && mkcksum (dentptr->name) == prevcksum) { + dentptr++; + continue; + } +#endif + get_name (dentptr, s_name); + if (dols == LS_ROOT) { + int isdir = (dentptr->attr & ATTR_DIR); + char dirc; + int doit = 0; + + if (isdir) { + dirc = '/'; + if (s_name[0] != 0) { + dirs++; + doit = 1; + } + } else { + dirc = ' '; + if (s_name[0] != 0) { + files++; + doit = 1; + } + } + if (doit) { + if (dirc == ' ') { + printf (" %8ld %s%c\n", + (long) FAT2CPU32 (dentptr->size), s_name, + dirc); + } else { + printf (" %s%c\n", s_name, dirc); + } + } + dentptr++; + continue; + } + if (strcmp((char *)fnamecopy, s_name) && + strcmp((char *)fnamecopy, l_name)) { + FAT_DPRINT ("RootMismatch: |%s|%s|\n", s_name, l_name); + dentptr++; + continue; + } + if (isdir && !(dentptr->attr & ATTR_DIR)) + return -1; + + FAT_DPRINT ("RootName: %s", s_name); + FAT_DPRINT (", start: 0x%x", START (dentptr)); + FAT_DPRINT (", size: 0x%x %s\n", + FAT2CPU32 (dentptr->size), isdir ? "(DIR)" : ""); + + goto rootdir_done; /* We got a match */ + } + cursect++; + } + rootdir_done: + + firsttime = 1; + while (isdir) { + int startsect = mydata->data_begin + + START (dentptr) * mydata->clust_size; + dir_entry dent; + char *nextname = NULL; + + dent = *dentptr; + dentptr = &dent; + idx = dirdelim (subname); + if (idx >= 0) { + subname[idx] = '\0'; + nextname = subname + idx + 1; + /* Handle multiple delimiters */ + while (ISDIRDELIM (*nextname)) + nextname++; + if (dols && *nextname == '\0') + firsttime = 0; + } else { + if (dols && firsttime) { + firsttime = 0; + } else { + isdir = 0; + } + } + + if (get_dentfromdir (mydata, startsect, subname, dentptr, + isdir ? 0 : dols) == NULL) { + if (dols && !isdir) + return 0; + return -1; + } + + if (idx >= 0) { + if (!(dentptr->attr & ATTR_DIR)) + return -1; + subname = nextname; + } + } + ret = get_contents (mydata, dentptr, buffer, maxsize); + FAT_DPRINT ("Size: %d, got: %ld\n", FAT2CPU32 (dentptr->size), ret); + + return ret; +} + + +int +file_fat_detectfs(void) +{ + boot_sector bs; + volume_info volinfo; + int fatsize; + char vol_label[12]; + + if(cur_dev==NULL) { + printf("No current device\n"); + return 1; + } +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ + (CONFIG_COMMANDS & CFG_CMD_USB) || (CONFIG_MMC) + printf("Interface: "); + switch(cur_dev->if_type) { + case IF_TYPE_IDE : printf("IDE"); break; + case IF_TYPE_SCSI : printf("SCSI"); break; + case IF_TYPE_ATAPI : printf("ATAPI"); break; + case IF_TYPE_USB : printf("USB"); break; + case IF_TYPE_DOC : printf("DOC"); break; + case IF_TYPE_MMC : printf("MMC"); break; + default : printf("Unknown"); + } + printf("\n Device %d: ",cur_dev->dev); + dev_print(cur_dev); +#endif + if(read_bootsectandvi(&bs, &volinfo, &fatsize)) { + printf("\nNo valid FAT fs found\n"); + return 1; + } + memcpy (vol_label, volinfo.volume_label, 11); + vol_label[11] = '\0'; + volinfo.fs_type[5]='\0'; + printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label); + return 0; +} + + +int +file_fat_ls(const char *dir) +{ + return do_fat_read(dir, NULL, 0, LS_YES); +} + + +long +file_fat_read(const char *filename, void *buffer, unsigned long maxsize) +{ + long ret; + ret = do_fat_read(filename, buffer, maxsize, LS_NO); + return ret; +} + +#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FAT) */
diff --git a/x-loader/fs/fat/file.c b/x-loader/fs/fat/file.c new file mode 100755 index 0000000..5994271 --- /dev/null +++ b/x-loader/fs/fat/file.c
@@ -0,0 +1,209 @@ +/* + * file.c + * + * Mini "VFS" by Marcus Sundberg + * + * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 + * 2003-03-10 - kharris@nexus-tech.net - ported to uboot + * + * 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 <config.h> +#include <malloc.h> +#include <part.h> +#include <fat.h> +#include <linux/stat.h> +#include <linux/time.h> + +#if (CONFIG_COMMANDS & CFG_CMD_FAT) + +/* Supported filesystems */ +static const struct filesystem filesystems[] = { + { file_fat_detectfs, file_fat_ls, file_fat_read, "FAT" }, +}; +#define NUM_FILESYS (sizeof(filesystems)/sizeof(struct filesystem)) + +/* The filesystem which was last detected */ +static int current_filesystem = FSTYPE_NONE; + +/* The current working directory */ +#define CWD_LEN 511 +char file_cwd[CWD_LEN+1] = "/"; + +const char * +file_getfsname(int idx) +{ + if (idx < 0 || idx >= NUM_FILESYS) return NULL; + + return filesystems[idx].name; +} + + +static void +pathcpy(char *dest, const char *src) +{ + char *origdest = dest; + + do { + if (dest-file_cwd >= CWD_LEN) { + *dest = '\0'; + return; + } + *(dest) = *(src); + if (*src == '\0') { + if (dest-- != origdest && ISDIRDELIM(*dest)) { + *dest = '\0'; + } + return; + } + ++dest; + if (ISDIRDELIM(*src)) { + while (ISDIRDELIM(*src)) src++; + } else { + src++; + } + } while (1); +} + + +int +file_cd(const char *path) +{ + if (ISDIRDELIM(*path)) { + while (ISDIRDELIM(*path)) path++; + strncpy(file_cwd+1, path, CWD_LEN-1); + } else { + const char *origpath = path; + char *tmpstr = file_cwd; + int back = 0; + + while (*tmpstr != '\0') tmpstr++; + do { + tmpstr--; + } while (ISDIRDELIM(*tmpstr)); + + while (*path == '.') { + path++; + while (*path == '.') { + path++; + back++; + } + if (*path != '\0' && !ISDIRDELIM(*path)) { + path = origpath; + back = 0; + break; + } + while (ISDIRDELIM(*path)) path++; + origpath = path; + } + + while (back--) { + /* Strip off path component */ + while (!ISDIRDELIM(*tmpstr)) { + tmpstr--; + } + if (tmpstr == file_cwd) { + /* Incremented again right after the loop. */ + tmpstr--; + break; + } + /* Skip delimiters */ + while (ISDIRDELIM(*tmpstr)) tmpstr--; + } + tmpstr++; + if (*path == '\0') { + if (tmpstr == file_cwd) { + *tmpstr = '/'; + tmpstr++; + } + *tmpstr = '\0'; + return 0; + } + *tmpstr = '/'; + pathcpy(tmpstr+1, path); + } + + return 0; +} + + +int +file_detectfs(void) +{ + int i; + + current_filesystem = FSTYPE_NONE; + + for (i = 0; i < NUM_FILESYS; i++) { + if (filesystems[i].detect() == 0) { + strcpy(file_cwd, "/"); + current_filesystem = i; + break; + } + } + + return current_filesystem; +} + + +int +file_ls(const char *dir) +{ + char fullpath[1024]; + const char *arg; + + if (current_filesystem == FSTYPE_NONE) { + printf("Can't list files without a filesystem!\n"); + return -1; + } + + if (ISDIRDELIM(*dir)) { + arg = dir; + } else { + sprintf(fullpath, "%s/%s", file_cwd, dir); + arg = fullpath; + } + return filesystems[current_filesystem].ls(arg); +} + + +long +file_read(const char *filename, void *buffer, unsigned long maxsize) +{ + char fullpath[1024]; + const char *arg; + + if (current_filesystem == FSTYPE_NONE) { + printf("Can't load file without a filesystem!\n"); + return -1; + } + + if (ISDIRDELIM(*filename)) { + arg = filename; + } else { + sprintf(fullpath, "%s/%s", file_cwd, filename); + arg = fullpath; + } + + return filesystems[current_filesystem].read(arg, buffer, maxsize); +} + +#endif /* #if (CONFIG_COMMANDS & CFG_CMD_FAT) */
diff --git a/x-loader/include/asm/arch-arm1136/bits.h b/x-loader/include/asm/arch-arm1136/bits.h new file mode 100644 index 0000000..dc3273e --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/bits.h
@@ -0,0 +1,49 @@ +/* bits.h + * Copyright (c) 2004 Texas Instruments + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the license found in the file + * named COPYING that should have accompanied this file. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef __bits_h +#define __bits_h 1 + +#define BIT0 (1<<0) +#define BIT1 (1<<1) +#define BIT2 (1<<2) +#define BIT3 (1<<3) +#define BIT4 (1<<4) +#define BIT5 (1<<5) +#define BIT6 (1<<6) +#define BIT7 (1<<7) +#define BIT8 (1<<8) +#define BIT9 (1<<9) +#define BIT10 (1<<10) +#define BIT11 (1<<11) +#define BIT12 (1<<12) +#define BIT13 (1<<13) +#define BIT14 (1<<14) +#define BIT15 (1<<15) +#define BIT16 (1<<16) +#define BIT17 (1<<17) +#define BIT18 (1<<18) +#define BIT19 (1<<19) +#define BIT20 (1<<20) +#define BIT21 (1<<21) +#define BIT22 (1<<22) +#define BIT23 (1<<23) +#define BIT24 (1<<24) +#define BIT25 (1<<25) +#define BIT26 (1<<26) +#define BIT27 (1<<27) +#define BIT28 (1<<28) +#define BIT29 (1<<29) +#define BIT30 (1<<30) +#define BIT31 (1<<31) + +#endif +
diff --git a/x-loader/include/asm/arch-arm1136/clocks.h b/x-loader/include/asm/arch-arm1136/clocks.h new file mode 100644 index 0000000..8e00d2e --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/clocks.h
@@ -0,0 +1,51 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP24XX_CLOCKS_H_ +#define _OMAP24XX_CLOCKS_H_ + +#define COMMIT_DIVIDERS 0x1 +#define MODE_BYPASS_FAST 0x2 +#define APLL_LOCK 0xc +#define DPLL_LOCK 0x3 /* DPLL lock */ +#define LDELAY 12000000 + +#if defined(CONFIG_OMAP242X) +#include <asm/arch/clocks242x.h> +#elif defined(CONFIG_OMAP243X) +#include <asm/arch/clocks243x.h> +#endif + +#define S12M 12000000 +#define S13M 13000000 +#define S19_2M 19200000 +#define S24M 24000000 +#define S26M 26000000 +#define S38_4M 38400000 + +#endif + + + + + + + +
diff --git a/x-loader/include/asm/arch-arm1136/clocks242x.h b/x-loader/include/asm/arch-arm1136/clocks242x.h new file mode 100644 index 0000000..0ae1c4e --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/clocks242x.h
@@ -0,0 +1,147 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP242X_CLOCKS_H_ +#define _OMAP242X_CLOCKS_H_ + +/****************************************************************************; +; PRCM Scheme I +; +; Enable clocks and DPLL for: +; DPLL=330, DPLLout=660 M=1,N=55 CM_CLKSEL1_PLL[21:8] 12/2*55 +; Core=660 (core domain) DPLLx2 CM_CLKSEL2_PLL[1:0] +; MPUF=330 (mpu domain) 2 CM_CLKSEL_MPU[4:0] +; DSPF=220 (dsp domain) 3 CM_CLKSEL_DSP[4:0] +; DSPI=110 6 CM_CLKSEL_DSP[6:5] +; DSP_S activated CM_CLKSEL_DSP[7] +; IVAF=165 (dsp domain) 4 CM_CLKSEL_DSP[12:8] +; IVAF=82.5 auto +; IVAI auto +; IVA_MPU auto +; IVA_S bypass CM_CLKSEL_DSP[13] +; GFXF=82.5 (gfx domain) 8 CM_CLKSEL_FGX[2:0] +; SSI_SSRF=220 3 CM_CLKSEL1_CORE[24:20] +; SSI_SSTF=110 auto +; L3=165Mhz (sdram) 4 CM_CLKSEL1_CORE[4:0] +; L4=82.5Mhz 8 +; C_L4_USB=41.25 16 CM_CLKSEL1_CORE[6:5] +***************************************************************************/ +#define I_DPLL_OUT_X2 0x2 /* x2 core out */ +#define I_MPU_DIV 0x2 /* mpu = core/2 */ +#define I_DSP_DIV 0x3c3 /* dsp & iva divider */ +#define I_GFX_DIV 0x2 +#define I_BUS_DIV 0x04601044 +#ifdef INPUT_CLK_13MHZ +#define I_DPLL_330 0x0114AC00 /* 13MHz */ +#else +#define I_DPLL_330 0x01837100 /* 12MHz */ +#endif + +/****************************************************************************; +; PRCM Scheme II <tested> +; +; Enable clocks and DPLL for: +; DPLL=300, DPLLout=600 M=1,N=50 CM_CLKSEL1_PLL[21:8] 12/2*50 +; Core=600 (core domain) DPLLx2 CM_CLKSEL2_PLL[1:0] +; MPUF=300 (mpu domain) 2 CM_CLKSEL_MPU[4:0] +; DSPF=200 (dsp domain) 3 CM_CLKSEL_DSP[4:0] +; DSPI=100 6 CM_CLKSEL_DSP[6:5] +; DSP_S bypass CM_CLKSEL_DSP[7] +; IVAF=200 (dsp domain) 3 CM_CLKSEL_DSP[12:8] +; IVAF=100 auto +; IVAI auto +; IVA_MPU auto +; IVA_S bypass CM_CLKSEL_DSP[13] +; GFXF=50 (gfx domain) 12 CM_CLKSEL_FGX[2:0] +; SSI_SSRF=200 3 CM_CLKSEL1_CORE[24:20] +; SSI_SSTF=100 auto +; L3=100Mhz (sdram) 6 CM_CLKSEL1_CORE[4:0] +; L4=100Mhz 6 +; C_L4_USB=50 12 CM_CLKSEL1_CORE[6:5] +***************************************************************************/ +#define II_DPLL_OUT_X2 0x2 /* x2 core out */ +#define II_MPU_DIV 0x2 /* mpu = core/2 */ +#define II_DSP_DIV 0x343 /* dsp & iva divider */ +#define II_GFX_DIV 0x2 +#define II_BUS_DIV 0x04601026 +#ifdef INPUT_CLK_13MHZ +#define II_DPLL_300 0x0112CC00 /* 13MHz */ +#else +#define II_DPLL_300 0x01832100 /* 12MHz */ +#endif + +/****************************************************************************; +; PRCM Scheme III <tested> +; +; Enable clocks and DPLL for: +; DPLL=266, DPLLout=532 M=5+1,N=133 CM_CLKSEL1_PLL[21:8] 12/6*133=266 +; Core=532 (core domain) DPLLx2 CM_CLKSEL2_PLL[1:0] +; MPUF=266 (mpu domain) /2 CM_CLKSEL_MPU[4:0] +; DSPF=177.3 (dsp domain) /3 CM_CLKSEL_DSP[4:0] +; DSPI=88.67 /6 CM_CLKSEL_DSP[6:5] +; DSP_S ACTIVATED CM_CLKSEL_DSP[7] +; IVAF=88.67 (dsp domain) /3 CM_CLKSEL_DSP[12:8] +; IVAF=88.67 auto +; IVAI auto +; IVA_MPU auto +; IVA_S ACTIVATED CM_CLKSEL_DSP[13] +; GFXF=66.5 (gfx domain) /8 CM_CLKSEL_FGX[2:0]: +; SSI_SSRF=177.3 /3 CM_CLKSEL1_CORE[24:20] +; SSI_SSTF=88.67 auto +; L3=133Mhz (sdram) /4 CM_CLKSEL1_CORE[4:0] +; L4=66.5Mhz /8 +; C_L4_USB=33.25 /16 CM_CLKSEL1_CORE[6:5] +***************************************************************************/ +#define III_DPLL_OUT_X2 0x2 /* x2 core out */ +#define III_MPU_DIV 0x2 /* mpu = core/2 */ +#define III_DSP_DIV 0x23C3 /* dsp & iva divider sych enabled*/ +#define III_GFX_DIV 0x2 +#define III_BUS_DIV 0x08301044 +#ifdef INPUT_CLK_13MHZ +#define III_DPLL_266 0x0110AC00 /* 13MHz */ +#else +#define III_DPLL_266 0x01885500 /* 12MHz */ +#endif + +/* set defaults for boot up */ +#ifdef PRCM_CONFIG_I +# define DPLL_OUT I_DPLL_OUT_X2 +# define MPU_DIV I_MPU_DIV +# define DSP_DIV I_DSP_DIV +# define GFX_DIV I_GFX_DIV +# define BUS_DIV I_BUS_DIV +# define DPLL_VAL I_DPLL_266 +#elif PRCM_CONFIG_II +# define DPLL_OUT II_DPLL_OUT_X2 +# define MPU_DIV II_MPU_DIV +# define DSP_DIV II_DSP_DIV +# define GFX_DIV II_GFX_DIV +# define BUS_DIV II_BUS_DIV +# define DPLL_VAL II_DPLL_300 +#elif PRCM_CONFIG_III +# define DPLL_OUT III_DPLL_OUT_X2 +# define MPU_DIV III_MPU_DIV +# define DSP_DIV III_DSP_DIV +# define GFX_DIV III_GFX_DIV +# define BUS_DIV III_BUS_DIV +# define DPLL_VAL III_DPLL_266 +#endif + +#endif
diff --git a/x-loader/include/asm/arch-arm1136/clocks243x.h b/x-loader/include/asm/arch-arm1136/clocks243x.h new file mode 100644 index 0000000..18d2e46 --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/clocks243x.h
@@ -0,0 +1,223 @@ +/* + * (C) Copyright 2005 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP243X_CLOCKS_H_ +#define _OMAP243X_CLOCKS_H_ + +/* cm_clksel core fields not ratio governed */ +#define RX_CLKSEL_DSS1 (0x10 << 8) +#define RX_CLKSEL_DSS2 (0x0 << 13) +#define RX_CLKSEL_SSI (0x5 << 20) + +/* 2430 Ratio's */ +/* 2430-Ratio Config 1 */ +#define R1_CLKSEL_L3 (4 << 0) +#define R1_CLKSEL_L4 (2 << 5) +#define R1_CLKSEL_USB (4 << 25) +#define R1_CM_CLKSEL1_CORE_VAL R1_CLKSEL_USB | RX_CLKSEL_SSI | RX_CLKSEL_DSS2 \ + | RX_CLKSEL_DSS1 | R1_CLKSEL_L4 | R1_CLKSEL_L3 +#define R1_CLKSEL_MPU (2 << 0) +#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU +#define R1_CLKSEL_DSP (2 << 0) +#define R1_CLKSEL_DSP_IF (2 << 5) +#define R1_CM_CLKSEL_DSP_VAL R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF +#define R1_CLKSEL_GFX (2 << 0) +#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX +#define R1_CLKSEL_MDM (4 << 0) +#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM + +/* 2430-Ratio Config 2 */ +#define R2_CLKSEL_L3 (6 << 0) +#define R2_CLKSEL_L4 (2 << 5) +#define R2_CLKSEL_USB (2 << 25) +#define R2_CM_CLKSEL1_CORE_VAL R2_CLKSEL_USB | RX_CLKSEL_SSI | RX_CLKSEL_DSS2 \ + | RX_CLKSEL_DSS1 | R2_CLKSEL_L4 | R2_CLKSEL_L3 +#define R2_CLKSEL_MPU (2 << 0) +#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU +#define R2_CLKSEL_DSP (2 << 0) +#define R2_CLKSEL_DSP_IF (3 << 5) +#define R2_CM_CLKSEL_DSP_VAL R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF +#define R2_CLKSEL_GFX (2 << 0) +#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX +#define R2_CLKSEL_MDM (6 << 0) +#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM + +/* 2430-Ratio Boot */ +#define RB_CLKSEL_L3 (1 << 0) +#define RB_CLKSEL_L4 (1 << 5) +#define RB_CLKSEL_USB (1 << 25) +#define RB_CM_CLKSEL1_CORE_VAL RB_CLKSEL_USB | RX_CLKSEL_SSI | RX_CLKSEL_DSS2 \ + | RX_CLKSEL_DSS1 | RB_CLKSEL_L4 | RB_CLKSEL_L3 +#define RB_CLKSEL_MPU (1 << 0) +#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU +#define RB_CLKSEL_DSP (1 << 0) +#define RB_CLKSEL_DSP_IF (1 << 5) +#define RB_CM_CLKSEL_DSP_VAL RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF +#define RB_CLKSEL_GFX (1 << 0) +#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX +#define RB_CLKSEL_MDM (1 << 0) +#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM + +/* 2430 Target modes: Along with each configuration the CPU has several modes + * which goes along with them. Modes mainly are the addition of descrite DPLL + * combinations to go along with a ratio. + */ +/* hardware goverend */ +#define MX_48M_SRC (0 << 3) +#define MX_54M_SRC (0 << 5) +#define MX_APLLS_CLIKIN_12 (3 << 23) +#define MX_APLLS_CLIKIN_13 (2 << 23) +#define MX_APLLS_CLIKIN_19_2 (0 << 23) + +/* 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed */ + +/* boot (boot) */ +#define MB_DPLL_MULT (1 << 12) +#define MB_DPLL_DIV (0 << 8) +#define MB_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV \ + | MB_DPLL_MULT | MX_APLLS_CLIKIN_12 + +#define MB_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV \ + | MB_DPLL_MULT | MX_APLLS_CLIKIN_13 + +#define MB_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV \ + | MB_DPLL_MULT | MX_APLLS_CLIKIN_19 + +/* #2 (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz */ + +#define M2_DPLL_MULT_12 (55 << 12) +#define M2_DPLL_DIV_12 (1 << 8) +#define M2_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | M2_DPLL_DIV_12 \ + | M2_DPLL_MULT_12 | MX_APLLS_CLIKIN_12 +/* Use 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2, relock time issue */ +#define M2_DPLL_MULT_13 (330 << 12) +#define M2_DPLL_DIV_13 (12 << 8) +#define M2_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | M2_DPLL_DIV_13 \ + | M2_DPLL_MULT_13 | MX_APLLS_CLIKIN_13 +#define M2_DPLL_MULT_19 (275 << 12) +#define M2_DPLL_DIV_19 (15 << 8) +#define M2_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | M2_DPLL_DIV_19 \ + | M2_DPLL_MULT_19 | MX_APLLS_CLIKIN_19_2 + +/* #3 (ratio2) DPLL = 330*2 = 660MHz, L3=110MHz */ +#define M3_DPLL_MULT_12 (55 << 12) +#define M3_DPLL_DIV_12 (1 << 8) +#define M3_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | M3_DPLL_DIV_12 \ + | M3_DPLL_MULT_12 | MX_APLLS_CLIKIN_12 +#define M3_DPLL_MULT_13 (330 << 12) +#define M3_DPLL_DIV_13 (12 << 8) +#define M3_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | M3_DPLL_DIV_13 \ + | M3_DPLL_MULT_13 | MX_APLLS_CLIKIN_13 +#define M3_DPLL_MULT_19 (275 << 12) +#define M3_DPLL_DIV_19 (15 << 8) +#define M3_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | M3_DPLL_DIV_19 \ + | M3_DPLL_MULT_19 | MX_APLLS_CLIKIN_19_2 + +/* #4 (ratio2), DPLL = 399*2 = 798MHz, L3=133MHz*/ +#define M4_DPLL_MULT_12 (133 << 12) +#define M4_DPLL_DIV_12 (3 << 8) +#define M4_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | M4_DPLL_DIV_12 \ + | M4_DPLL_MULT_12 | MX_APLLS_CLIKIN_12 +#define M4_DPLL_MULT_13 (399 << 12) +#define M4_DPLL_DIV_13 (12 << 8) +#define M4_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | M4_DPLL_DIV_13 \ + | M4_DPLL_MULT_13 | MX_APLLS_CLIKIN_13 +#define M4_DPLL_MULT_19 (145 << 12) +#define M4_DPLL_DIV_19 (6 << 8) +#define M4_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | M4_DPLL_DIV_19 \ + | M4_DPLL_MULT_19 | MX_APLLS_CLIKIN_19_2 + +/* #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz, L3=133MHz */ +#define M5A_DPLL_MULT_12 (133 << 12) +#define M5A_DPLL_DIV_12 (5 << 8) +#define M5A_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | M5A_DPLL_DIV_12 \ + | M5A_DPLL_MULT_12 | MX_APLLS_CLIKIN_12 +#define M5A_DPLL_MULT_13 (266 << 12) +#define M5A_DPLL_DIV_13 (12 << 8) +#define M5A_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | M5A_DPLL_DIV_13 \ + | M5A_DPLL_MULT_13 | MX_APLLS_CLIKIN_13 +#define M5A_DPLL_MULT_19 (180 << 12) +#define M5A_DPLL_DIV_19 (12 << 8) +#define M5A_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | M5A_DPLL_DIV_19 \ + | M5A_DPLL_MULT_19 | MX_APLLS_CLIKIN_19_2 + +/* #5b (ratio1) target DPLL = 200*2 = 400MHz, L3=100MHz */ +#define M5B_DPLL_MULT_12 (50 << 12) +#define M5B_DPLL_DIV_12 (2 << 8) +#define M5B_CM_CLKSEL1_PLL_12_VAL MX_48M_SRC | MX_54M_SRC | M5B_DPLL_DIV_12 \ + | M5B_DPLL_MULT_12 | MX_APLLS_CLIKIN_12 +#define M5B_DPLL_MULT_13 (200 << 12) +#define M5B_DPLL_DIV_13 (12 << 8) + +#define M5B_CM_CLKSEL1_PLL_13_VAL MX_48M_SRC | MX_54M_SRC | M5B_DPLL_DIV_13 \ + | M5B_DPLL_MULT_13 | MX_APLLS_CLIKIN_13 +#define M5B_DPLL_MULT_19 (125 << 12) +#define M5B_DPLL_DIV_19 (31 << 8) +#define M5B_CM_CLKSEL1_PLL_19_VAL MX_48M_SRC | MX_54M_SRC | M5B_DPLL_DIV_19 \ + | M5B_DPLL_MULT_19 | MX_APLLS_CLIKIN_19_2 + +/* 2430 - chassis (sedna) */ + /* 165 (ratio1) same as above #2 */ + /* 150 (ratio1)*/ + /* 133 (ratio2) same as above #4 */ + /* 110 (ratio2) same as above #3*/ + /* 104 (ratio2)*/ + /* boot (boot) */ + +/* high and low operation value */ +#define MX_CLKSEL2_PLL_2x_VAL (2 << 0) +#define MX_CLKSEL2_PLL_1x_VAL (1 << 0) + +/* set defaults for boot up */ +#if defined(PRCM_CONFIG_2) /* ARM-330MHz IVA2-330MHz L3-165MHz */ +# define DPLL_OUT MX_CLKSEL2_PLL_2x_VAL +# define MPU_DIV R1_CLKSEL_MPU +# define DSP_DIV R1_CM_CLKSEL_DSP_VAL +# define GFX_DIV R1_CM_CLKSEL_GFX_VAL +# define BUS_DIV R1_CM_CLKSEL1_CORE_VAL +# define DPLL_VAL M2_CM_CLKSEL1_PLL_13_VAL +# define MDM_DIV R2_CM_CLKSEL_MDM_VAL +#elif defined(PRCM_CONFIG_3) /* ARM-330MHz IVA2-330MHz L3-110MHz */ +# define DPLL_OUT MX_CLKSEL2_PLL_2x_VAL +# define MPU_DIV R2_CLKSEL_MPU +# define DSP_DIV R2_CM_CLKSEL_DSP_VAL +# define GFX_DIV R2_CM_CLKSEL_GFX_VAL +# define BUS_DIV R2_CM_CLKSEL1_CORE_VAL +# define DPLL_VAL M3_CM_CLKSEL1_PLL_13_VAL +# define MDM_DIV R2_CM_CLKSEL_MDM_VAL +#elif defined(PRCM_CONFIG_5A) /* ARM-266MHz IVA2-266MHz L3-133MHz */ +# define DPLL_OUT MX_CLKSEL2_PLL_2x_VAL +# define MPU_DIV R1_CLKSEL_MPU +# define DSP_DIV R1_CM_CLKSEL_DSP_VAL +# define GFX_DIV R1_CM_CLKSEL_GFX_VAL +# define BUS_DIV R1_CM_CLKSEL1_CORE_VAL +# define DPLL_VAL M5A_CM_CLKSEL1_PLL_13_VAL +# define MDM_DIV R2_CM_CLKSEL_MDM_VAL +#elif defined(PRCM_CONFIG_5B) /* ARM-200MHz IVA2-200MHz L3-100MHz */ +# define DPLL_OUT MX_CLKSEL2_PLL_2x_VAL +# define MPU_DIV R1_CLKSEL_MPU +# define DSP_DIV R1_CM_CLKSEL_DSP_VAL +# define GFX_DIV R1_CM_CLKSEL_GFX_VAL +# define BUS_DIV R1_CM_CLKSEL1_CORE_VAL +# define DPLL_VAL M5B_CM_CLKSEL1_PLL_13_VAL +# define MDM_DIV R1_CM_CLKSEL_MDM_VAL +#endif + +#endif
diff --git a/x-loader/include/asm/arch-arm1136/mem.h b/x-loader/include/asm/arch-arm1136/mem.h new file mode 100644 index 0000000..2a3da73 --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/mem.h
@@ -0,0 +1,383 @@ + +/* + * (C) Copyright 2004-2005 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP24XX_MEM_H_ +#define _OMAP24XX_MEM_H_ + +#define SDRC_CS0_OSET 0x0 +#define SDRC_CS1_OSET 0x30 /* mirror CS1 regs appear offset 0x30 from CS0 */ + +#ifndef __ASSEMBLY__ +/* struct's for holding data tables for current boards, they are getting used + early in init when NO global access are there */ +struct sdrc_data_s { + u32 sdrc_sharing; + u32 sdrc_mdcfg_0_ddr; + u32 sdrc_mdcfg_0_sdr; + u32 sdrc_actim_ctrla_0; + u32 sdrc_actim_ctrlb_0; + u32 sdrc_rfr_ctrl; + u32 sdrc_mr_0_ddr; + u32 sdrc_mr_0_sdr; + u32 sdrc_dllab_ctrl; +} /*__attribute__ ((packed))*/; +typedef struct sdrc_data_s sdrc_data_t; + +typedef enum { + STACKED = 0, + IP_DDR = 1, + COMBO_DDR = 2, + IP_SDR = 3, +} mem_t; + +#endif + +/* set the 243x-SDRC incoming address convention */ +#if defined(SDRC_B_R_C) +#define B_ALL (0 << 6) /* bank-row-column */ +#elif defined(SDRC_B1_R_B0_C) +#define B_ALL (1 << 6) /* bank1-row-bank0-column */ +#elif defined(SDRC_R_B_C) +#define B_ALL (2 << 6) /* row-bank-column */ +#endif + +/* Slower full frequency range default timings for x32 operation*/ +#define H4_2420_SDRC_SHARING 0x00000100 +#define H4_2420_SDRC_MDCFG_0_SDR 0x00D04010 /* discrete sdr module */ +#define H4_2420_SDRC_MR_0_SDR 0x00000031 +#define H4_2420_SDRC_MDCFG_0_DDR 0x01702011 /* descrite ddr module */ +#define SDP_2430_SDRC_MDCFG_0_DDR (0x02584019|B_ALL) /* Infin ddr module */ +#define H4_2420_COMBO_MDCFG_0_DDR 0x00801011 /* combo module */ +#define H4_2420_SDRC_MR_0_DDR 0x00000032 + +#define H4_2422_SDRC_SHARING 0x00004b00 +#define H4_2422_SDRC_MDCFG_MONO_DDR 0x01A02011 /* stacked mono die ddr on 2422 */ +#define H4_2422_SDRC_MDCFG_0_DDR 0x00801011 /* stacked dual die ddr on 2422 */ +#define H4_2422_SDRC_MR_0_DDR 0x00000032 + +#define H4_2423_SDRC_SHARING 0x00004900 /* 2420POP board cke1 not connected */ +#define H4_2423_SDRC_MDCFG_0_DDR 0x01A02011 /* stacked dual die ddr on 2423 */ +#define H4_2423_SDRC_MDCFG_1_DDR 0x00801011 /* stacked dual die ddr on 2423 */ + +/* ES1 work around timings */ +#define H4_242x_SDRC_ACTIM_CTRLA_0_ES1 0x9bead909 /* 165Mhz for use with 100/133 */ +#define H4_242x_SDRC_ACTIM_CTRLB_0_ES1 0x00000020 +#define H4_242x_SDRC_RFR_CTRL_ES1 0x00002401 /* use over refresh for ES1 */ + +/* optimized timings good for current shipping parts */ +#define H4_242X_SDRC_ACTIM_CTRLA_0_100MHz 0x5A59B485 +#define H4_242X_SDRC_ACTIM_CTRLB_0_100MHz 0x0000000e +#define H4_242X_SDRC_ACTIM_CTRLA_0_133MHz 0x8BA6E6C8 /* temp warn 0 settings */ +#define H4_242X_SDRC_ACTIM_CTRLB_0_133MHz 0x00000010 /* temp warn 0 settings */ +#define H4_242X_SDRC_RFR_CTRL_100MHz 0x0002da01 +#define H4_242X_SDRC_RFR_CTRL_133MHz 0x0003de01 /* 7.8us/7.5ns - 50 = 0x3de */ +#define SDP_24XX_SDRC_RFR_CTRL_165MHz 0x0004e201 /* 7.8us/6ns - 50 = 0x4e2 */ +#define H4_242X_SDRC_DLLAB_CTRL_100MHz 0x0000980E /* 90deg, allow DPLLout*1 to work (combo)*/ +#define H4_242X_SDRC_DLLAB_CTRL_133MHz 0x0000690E /* 90deg, for ES2 */ +#define SDP_24XX_SDRC_DLLAB_CTRL_165MHz 0x0000170C /* 72deg, code will recalc dll load */ + +/* Infineon part of 2430SDP (133MHz optimized) ~ 7.5ns + * TDAL = Twr/Tck + Trp/tck = 15/7.5 + 22.5/7.5 = 2 + 3 = 5 + * TDPL = 15/7.5 = 2 + * TRRD = 15/2.5 = 2 + * TRCD = 22.5/7.5 = 3 + * TRP = 22.5/7.5 = 3 + * TRAS = 45/7.5 = 6 + * TRC = 65/7.5 = 8.6->9 + * TRFC = 75/7.5 = 10 + * ACTIMB + * TCKE = 2 <new in 2430> + * XSR = 120/7.5 = 16 + */ +#define TDAL_133 5 +#define TDPL_133 2 +#define TRRD_133 2 +#define TRCD_133 3 +#define TRP_133 3 +#define TRAS_133 6 +#define TRC_133 9 +#define TRFC_133 10 +#define V_ACTIMA_133 ((TRFC_133 << 27) | (TRC_133 << 22) | (TRAS_133 << 18) |(TRP_133 << 15) | \ + (TRCD_133 << 12) |(TRRD_133 << 9) |(TDPL_133 << 6) | (TDAL_133)) + +#define TCKE_133 2 +#define XSR_133 16 +#define V_ACTIMB_133 ((TCKE_133 << 12) | (XSR_133 << 0)) + +/* Infineon part of 2430SDP (165MHz optimized) 6.06ns + * ACTIMA + * TDAL = Twr/Tck + Trp/tck = 15/6 + 18/6 = 2.5 + 3 = 5.5 -> 6 + * TDPL (Twr) = 15/6 = 2.5 -> 3 + * TRRD = 12/6 = 2 + * TRCD = 18/6 = 3 + * TRP = 18/6 = 3 + * TRAS = 42/6 = 7 + * TRC = 60/6 = 10 + * TRFC = 72/6 = 12 + * ACTIMB + * TCKE = 2 <new in 2430> + * XSR = 120/6 = 20 + */ +#define TDAL_165 6 +#define TDPL_165 3 +#define TRRD_165 2 +#define TRCD_165 3 +#define TRP_165 3 +#define TRAS_165 7 +#define TRC_165 10 +#define TRFC_165 12 +#define V_ACTIMA_165 ((TRFC_165 << 27) | (TRC_165 << 22) | (TRAS_165 << 18) |(TRP_165 << 15) | \ + (TRCD_165 << 12) |(TRRD_165 << 9) |(TDPL_165 << 6) | (TDAL_165)) + +#define TCKE_165 2 +#define XSR_165 20 +#define V_ACTIMB_165 ((TCKE_165 << 12) | (XSR_165 << 0)) + +#if defined(PRCM_CONFIG_II) || defined(PRCM_CONFIG_5B) +# define H4_2420_SDRC_ACTIM_CTRLA_0 H4_242X_SDRC_ACTIM_CTRLA_0_100MHz +# define SDP_2430_SDRC_ACTIM_CTRLA_0 V_ACTIMA_133 +# define H4_2420_SDRC_ACTIM_CTRLB_0 H4_242X_SDRC_ACTIM_CTRLB_0_100MHz +# define H4_2420_SDRC_RFR_CTRL H4_242X_SDRC_RFR_CTRL_100MHz +# define H4_2420_SDRC_DLLAB_CTRL H4_242X_SDRC_DLLAB_CTRL_100MHz +# define SDP_2430_SDRC_DLLAB_CTRL 0x0000730E +# define H4_2422_SDRC_ACTIM_CTRLA_0 H4_242X_SDRC_ACTIM_CTRLA_0_100MHz +# define H4_2422_SDRC_ACTIM_CTRLB_0 H4_242X_SDRC_ACTIM_CTRLB_0_100MHz +# define H4_2422_SDRC_RFR_CTRL H4_242X_SDRC_RFR_CTRL_100MHz +# define H4_2422_SDRC_DLLAB_CTRL H4_242X_SDRC_DLLAB_CTRL_100MHz +#elif defined(PRCM_CONFIG_III) || defined(PRCM_CONFIG_5A) || defined(PRCM_CONFIG_3) +# define H4_2420_SDRC_ACTIM_CTRLA_0 H4_242X_SDRC_ACTIM_CTRLA_0_133MHz +# define SDP_2430_SDRC_ACTIM_CTRLA_0 V_ACTIMA_133 +# define H4_2420_SDRC_ACTIM_CTRLB_0 H4_242X_SDRC_ACTIM_CTRLB_0_133MHz +# define H4_2420_SDRC_RFR_CTRL H4_242X_SDRC_RFR_CTRL_133MHz +# define H4_2420_SDRC_DLLAB_CTRL H4_242X_SDRC_DLLAB_CTRL_133MHz +# define SDP_2430_SDRC_DLLAB_CTRL 0x0000730E +# define H4_2422_SDRC_ACTIM_CTRLA_0 H4_242X_SDRC_ACTIM_CTRLA_0_133MHz +# define H4_2422_SDRC_ACTIM_CTRLB_0 H4_242X_SDRC_ACTIM_CTRLB_0_133MHz +# define H4_2422_SDRC_RFR_CTRL H4_242X_SDRC_RFR_CTRL_133MHz +# define H4_2422_SDRC_DLLAB_CTRL H4_242X_SDRC_DLLAB_CTRL_133MHz +#elif defined(PRCM_CONFIG_I) || defined(PRCM_CONFIG_2) +# define H4_2420_SDRC_ACTIM_CTRLA_0 V_ACTIMA_165 +# define SDP_2430_SDRC_ACTIM_CTRLA_0 V_ACTIMA_165 +# define H4_2420_SDRC_ACTIM_CTRLB_0 V_ACTIMB_165 +# define H4_2420_SDRC_RFR_CTRL SDP_24XX_SDRC_RFR_CTRL_165MHz +# define H4_2420_SDRC_DLLAB_CTRL SDP_24XX_SDRC_DLLAB_CTRL_165MHz +# define SDP_2430_SDRC_DLLAB_CTRL SDP_24XX_SDRC_DLLAB_CTRL_165MHz +# define H4_2422_SDRC_ACTIM_CTRLA_0 V_ACTIMA_165 +# define H4_2422_SDRC_ACTIM_CTRLB_0 V_ACTIMB_165 +# define H4_2422_SDRC_RFR_CTRL SDP_24XX_SDRC_RFR_CTRL_165MHz +# define H4_2422_SDRC_DLLAB_CTRL SDP_24XX_SDRC_DLLAB_CTRL_165MHz +#endif + +/* + * GPMC settings - + * Definitions is as per the following format + * # define <PART>_GPMC_CONFIG<x> <value> + * Where: + * PART is the part name e.g. STNOR - Intel Strata Flash + * x is GPMC config registers from 1 to 6 (there will be 6 macros) + * Value is corresponding value + * + * For every valid PRCM configuration there should be only one definition of the same. + * if values are independent of the board, this definition will be present in this file + * if values are dependent on the board, then this should go into corresponding mem-boardName.h file + * + * Currently valid part Names are (PART): + * STNOR - Intel Strata Flash + * SMNAND - Samsung NAND + * MPDB - H4 MPDB board + * SBNOR - Sibley NOR + * ONNAND - Samsung One NAND + * + * include/configs/file.h contains the following defn - for all CS we are interested + * #define OMAP24XX_GPMC_CSx PART + * #define OMAP24XX_GPMC_CSx_SIZE Size + * #define OMAP24XX_GPMC_CSx_MAP Map + * Where: + * x - CS number + * PART - Part Name as defined above + * SIZE - how big is the mapping to be + * GPMC_SIZE_128M - 0x8 + * GPMC_SIZE_64M - 0xC + * GPMC_SIZE_32M - 0xE + * GPMC_SIZE_16M - 0xF + * MAP - Map this CS to which address(GPMC address space)- Absolute address + * >>24 before being used. + */ + +#define GPMC_SIZE_256M 0x0 +#define GPMC_SIZE_128M 0x8 +#define GPMC_SIZE_64M 0xC +#define GPMC_SIZE_32M 0xE +#define GPMC_SIZE_16M 0xF + +#if defined(PRCM_CONFIG_II) || defined(PRCM_CONFIG_5B) /* L3 at 100MHz */ +# define SMNAND_GPMC_CONFIG1 0x0 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x00000A80 +# define STNOR_GPMC_CONFIG1 0x3 +# define STNOR_GPMC_CONFIG2 0x000f0f01 +# define STNOR_GPMC_CONFIG3 0x00050502 +# define STNOR_GPMC_CONFIG4 0x0C060C06 +# define STNOR_GPMC_CONFIG5 0x01131F1F +# define STNOR_GPMC_CONFIG6 0x0 /* 0? Not defined so far... this value is reset val as per gpmc doc */ +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001F1F00 +# define MPDB_GPMC_CONFIG3 0x00080802 +# define MPDB_GPMC_CONFIG4 0x1C091C09 +# define MPDB_GPMC_CONFIG5 0x031A1F1F +# define MPDB_GPMC_CONFIG6 0x000003C2 +#endif + +#if defined(PRCM_CONFIG_III) || defined(PRCM_CONFIG_5A) || defined(PRCM_CONFIG_3) /* L3 at 133MHz */ +# define SMNAND_GPMC_CONFIG1 0x00001800 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x00000A80 +# define SMNAND_GPMC_CONFIG7 0x00000C44 + +# define STNOR_GPMC_CONFIG1 0x3 +# define STNOR_GPMC_CONFIG2 0x00151501 +# define STNOR_GPMC_CONFIG3 0x00060602 +# define STNOR_GPMC_CONFIG4 0x10081008 +# define STNOR_GPMC_CONFIG5 0x01131F1F +# define STNOR_GPMC_CONFIG6 0x000004c4 + +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001f1f01 +# define MPDB_GPMC_CONFIG3 0x00080803 +# define MPDB_GPMC_CONFIG4 0x1C091C09 +# define MPDB_GPMC_CONFIG5 0x041f1F1F +# define MPDB_GPMC_CONFIG6 0x000004C4 + +# define SIBNOR_GPMC_CONFIG1 0x3 +# define SIBNOR_GPMC_CONFIG2 0x00151501 +# define SIBNOR_GPMC_CONFIG3 0x00060602 +# define SIBNOR_GPMC_CONFIG4 0x10081008 +# define SIBNOR_GPMC_CONFIG5 0x01131F1F +# define SIBNOR_GPMC_CONFIG6 0x00000000 + +# define ONENAND_GPMC_CONFIG1 0x00001200 +# define ONENAND_GPMC_CONFIG2 0x000c0c01 +# define ONENAND_GPMC_CONFIG3 0x00030301 +# define ONENAND_GPMC_CONFIG4 0x0c040c04 +# define ONENAND_GPMC_CONFIG5 0x010C1010 +# define ONENAND_GPMC_CONFIG6 0x00000000 + +# define PCMCIA_GPMC_CONFIG1 0x01E91200 +# define PCMCIA_GPMC_CONFIG2 0x001E1E01 +# define PCMCIA_GPMC_CONFIG3 0x00020203 +# define PCMCIA_GPMC_CONFIG4 0x1D041D04 +# define PCMCIA_GPMC_CONFIG5 0x031D1F1F +# define PCMCIA_GPMC_CONFIG6 0x000004C4 +#endif /* endif CFG_PRCM_III */ + +#if defined (PRCM_CONFIG_I) || defined(PRCM_CONFIG_2) /* L3 at 165MHz */ +# define SMNAND_GPMC_CONFIG1 0x00001800 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x00000A80 +# define SMNAND_GPMC_CONFIG7 0x00000C44 + +# define STNOR_GPMC_CONFIG1 0x3 +# define STNOR_GPMC_CONFIG2 0x00151501 +# define STNOR_GPMC_CONFIG3 0x00060602 +# define STNOR_GPMC_CONFIG4 0x11091109 +# define STNOR_GPMC_CONFIG5 0x01141F1F +# define STNOR_GPMC_CONFIG6 0x000004c4 + +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001f1f01 +# define MPDB_GPMC_CONFIG3 0x00080803 +# define MPDB_GPMC_CONFIG4 0x1c0b1c0a +# define MPDB_GPMC_CONFIG5 0x041f1F1F +# define MPDB_GPMC_CONFIG6 0x000004C4 + +# define SIBNOR_GPMC_CONFIG1 0x3 +# define SIBNOR_GPMC_CONFIG2 0x00151501 +# define SIBNOR_GPMC_CONFIG3 0x00060602 +# define SIBNOR_GPMC_CONFIG4 0x11091109 +# define SIBNOR_GPMC_CONFIG5 0x01141F1F +# define SIBNOR_GPMC_CONFIG6 0x00000000 + +# define ONENAND_GPMC_CONFIG1 0x00001200 +# define ONENAND_GPMC_CONFIG2 0x000F0F01 +# define ONENAND_GPMC_CONFIG3 0x00030301 +# define ONENAND_GPMC_CONFIG4 0x0F040F04 +# define ONENAND_GPMC_CONFIG5 0x010F1010 +# define ONENAND_GPMC_CONFIG6 0x00000000 + +# define PCMCIA_GPMC_CONFIG1 0x01E91200 +# define PCMCIA_GPMC_CONFIG2 0x001E1E01 +# define PCMCIA_GPMC_CONFIG3 0x00020203 +# define PCMCIA_GPMC_CONFIG4 0x1D041D04 +# define PCMCIA_GPMC_CONFIG5 0x031D1F1F +# define PCMCIA_GPMC_CONFIG6 0x000004C4 + +#endif + +#if 0 +/* Board Specific Settings for each of the configurations for chips + * whose values change as per platform. - None currently + */ +#if CONFIG_OMAP24XXH4 +#include <asm/arch/mem-h4.h> +#endif + +#if CONFIG_2430SDP +#include <asm/arch/mem-sdp2430.h> +#endif + +#endif /* if 0 */ + +/* max number of GPMC Chip Selects */ +#define GPMC_MAX_CS 8 +/* max number of GPMC regs */ +#define GPMC_MAX_REG 7 + +#define PROC_NOR 1 +#define PROC_NAND 2 +#define PISMO_SIBLEY0 3 +#define PISMO_SIBLEY1 4 +#define PISMO_ONENAND 5 +#define DBG_MPDB 6 +#define PISMO_PCMCIA 7 + +/* make it readable for the gpmc_init */ +#define PROC_NOR_BASE FLASH_BASE +#define PROC_NAND_BASE NAND_BASE +#define PISMO_SIB0_BASE SIBLEY_MAP1 +#define PISMO_SIB1_BASE SIBLEY_MAP2 +#define PISMO_ONEN_BASE ONENAND_MAP +#define DBG_MPDB_BASE DEBUG_BASE +#define PISMO_PCMCIA_BASE PCMCIA_BASE + +#endif /* endif _OMAP24XX_MEM_H_ */
diff --git a/x-loader/include/asm/arch-arm1136/omap2420.h b/x-loader/include/asm/arch-arm1136/omap2420.h new file mode 100644 index 0000000..29e679f --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/omap2420.h
@@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005 Texas Instruments, <www.ti.com> + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP2420_SYS_H_ +#define _OMAP2420_SYS_H_ + +#include <asm/arch/sizes.h> + +/* + * 2420 specific Section + */ + +/* CONTROL */ +#define OMAP2420_CTRL_BASE (0x48000000) +#define CONTROL_STATUS (OMAP2420_CTRL_BASE + 0x2F8) + +/* TAP information */ +#define OMAP2420_TAP_BASE (0x48014000) +#define TAP_IDCODE_REG (OMAP2420_TAP_BASE+0x204) + +/* GPMC */ +#define OMAP2420_GPMC_BASE (0x6800A000) +#define GPMC_SYSCONFIG (OMAP2420_GPMC_BASE+0x10) +#define GPMC_SYSSTATUS (OMAP2420_GPMC_BASE+0x14) +#define GPMC_IRQENABLE (OMAP2420_GPMC_BASE+0x1C) +#define GPMC_TIMEOUT_CONTROL (OMAP2420_GPMC_BASE+0x40) +#define GPMC_CONFIG (OMAP2420_GPMC_BASE+0x50) +#define GPMC_CONFIG1_0 (OMAP2420_GPMC_BASE+0x60) +#define GPMC_CONFIG2_0 (OMAP2420_GPMC_BASE+0x64) +#define GPMC_CONFIG3_0 (OMAP2420_GPMC_BASE+0x68) +#define GPMC_CONFIG4_0 (OMAP2420_GPMC_BASE+0x6C) +#define GPMC_CONFIG5_0 (OMAP2420_GPMC_BASE+0x70) +#define GPMC_CONFIG6_0 (OMAP2420_GPMC_BASE+0x74) +#define GPMC_CONFIG7_0 (OMAP2420_GPMC_BASE+0x78) +#define GPMC_CONFIG1_1 (OMAP2420_GPMC_BASE+0x90) +#define GPMC_CONFIG2_1 (OMAP2420_GPMC_BASE+0x94) +#define GPMC_CONFIG3_1 (OMAP2420_GPMC_BASE+0x98) +#define GPMC_CONFIG4_1 (OMAP2420_GPMC_BASE+0x9C) +#define GPMC_CONFIG5_1 (OMAP2420_GPMC_BASE+0xA0) +#define GPMC_CONFIG6_1 (OMAP2420_GPMC_BASE+0xA4) +#define GPMC_CONFIG7_1 (OMAP2420_GPMC_BASE+0xA8) + +/* SMS */ +#define OMAP2420_SMS_BASE 0x68008000 +#define SMS_SYSCONFIG (OMAP2420_SMS_BASE+0x10) + +/* SDRC */ +#define OMAP2420_SDRC_BASE 0x68009000 +#define SDRC_SYSCONFIG (OMAP2420_SDRC_BASE+0x10) +#define SDRC_STATUS (OMAP2420_SDRC_BASE+0x14) +#define SDRC_SHARING (OMAP2420_SDRC_BASE+0x44) +#define SDRC_DLLA_CTRL (OMAP2420_SDRC_BASE+0x60) +#define SDRC_DLLA_STATUS (OMAP2420_SDRC_BASE+0x64) +#define SDRC_DLLB_CTRL (OMAP2420_SDRC_BASE+0x68) +#define SDRC_POWER (OMAP2420_SDRC_BASE+0x70) +#define SDRC_MCFG_0 (OMAP2420_SDRC_BASE+0x80) +#define SDRC_MR_0 (OMAP2420_SDRC_BASE+0x84) +#define SDRC_ACTIM_CTRLA_0 (OMAP2420_SDRC_BASE+0x9C) +#define SDRC_ACTIM_CTRLB_0 (OMAP2420_SDRC_BASE+0xA0) +#define SDRC_MCFG_1 (OMAP2420_SDRC_BASE+0xB0) +#define SDRC_MR_1 (OMAP2420_SDRC_BASE+0xB4) +#define SDRC_EMR2_1 (OMAP2420_SDRC_BASE+0xBC) +#define SDRC_ACTIM_CTRLA_1 (OMAP2420_SDRC_BASE+0xC4) +#define SDRC_ACTIM_CTRLB_1 (OMAP2420_SDRC_BASE+0xC8) +#define SDRC_RFR_CTRL (OMAP2420_SDRC_BASE+0xA4) +#define SDRC_MANUAL_0 (OMAP2420_SDRC_BASE+0xA8) +#define SDRC_RFR_CTRL1 (OMAP2420_SDRC_BASE+0xD4) +#define SDRC_MANUAL_1 (OMAP2420_SDRC_BASE+0xD8) + +#define OMAP2420_SDRC_CS0 0x80000000 +#define OMAP2420_SDRC_CS1 0xA0000000 + +#define LOADDLL BIT2 +#define CMD_NOP 0x0 +#define CMD_PRECHARGE 0x1 +#define CMD_AUTOREFRESH 0x2 +#define CMD_ENTR_PWRDOWN 0x3 +#define CMD_EXIT_PWRDOWN 0x4 +#define CMD_ENTR_SRFRSH 0x5 +#define CMD_CKE_HIGH 0x6 +#define CMD_CKE_LOW 0x7 +#define SOFTRESET BIT1 +#define SMART_IDLE (0x2 << 3) +#define REF_ON_IDLE (0x1 << 6) + + +/* UART */ +#define OMAP2420_UART1 0x4806A000 +#define OMAP2420_UART2 0x4806C000 +#define OMAP2420_UART3 0x4806E000 + +/* General Purpose Timers */ +#define OMAP2420_GPT1 0x48028000 +#define OMAP2420_GPT2 0x4802A000 +#define OMAP2420_GPT3 0x48078000 +#define OMAP2420_GPT4 0x4807A000 +#define OMAP2420_GPT5 0x4807C000 +#define OMAP2420_GPT6 0x4807E000 +#define OMAP2420_GPT7 0x48080000 +#define OMAP2420_GPT8 0x48082000 +#define OMAP2420_GPT9 0x48084000 +#define OMAP2420_GPT10 0x48086000 +#define OMAP2420_GPT11 0x48088000 +#define OMAP2420_GPT12 0x4808A000 + +/* timer regs offsets (32 bit regs) */ +#define TIDR 0x0 /* r */ +#define TIOCP_CFG 0x10 /* rw */ +#define TISTAT 0x14 /* r */ +#define TISR 0x18 /* rw */ +#define TIER 0x1C /* rw */ +#define TWER 0x20 /* rw */ +#define TCLR 0x24 /* rw */ +#define TCRR 0x28 /* rw */ +#define TLDR 0x2C /* rw */ +#define TTGR 0x30 /* rw */ +#define TWPS 0x34 /* r */ +#define TMAR 0x38 /* rw */ +#define TCAR1 0x3c /* r */ +#define TSICR 0x40 /* rw */ +#define TCAR2 0x44 /* r */ + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE 0x48020000 +#define WD2_BASE 0x48022000 +#define WD3_BASE 0x48024000 +#define WD4_BASE 0x48026000 +#define WWPS 0x34 /* r */ +#define WSPR 0x48 /* rw */ +#define WD_UNLOCK1 0xAAAA +#define WD_UNLOCK2 0x5555 + +/* PRCM */ +#define OMAP2420_CM_BASE 0x48008000 +#define PRCM_CLKCFG_CTRL (OMAP2420_CM_BASE+0x080) +#define CM_CLKSEL_MPU (OMAP2420_CM_BASE+0x140) +#define CM_FCLKEN1_CORE (OMAP2420_CM_BASE+0x200) +#define CM_FCLKEN2_CORE (OMAP2420_CM_BASE+0x204) +#define CM_ICLKEN1_CORE (OMAP2420_CM_BASE+0x210) +#define CM_ICLKEN2_CORE (OMAP2420_CM_BASE+0x214) +#define CM_CLKSEL1_CORE (OMAP2420_CM_BASE+0x240) +#define CM_CLKSEL_WKUP (OMAP2420_CM_BASE+0x440) +#define CM_CLKSEL2_CORE (OMAP2420_CM_BASE+0x244) +#define CM_CLKSEL_GFX (OMAP2420_CM_BASE+0x340) +#define PM_RSTCTRL_WKUP (OMAP2420_CM_BASE+0x450) +#define CM_CLKEN_PLL (OMAP2420_CM_BASE+0x500) +#define CM_IDLEST_CKGEN (OMAP2420_CM_BASE+0x520) +#define CM_CLKSEL1_PLL (OMAP2420_CM_BASE+0x540) +#define CM_CLKSEL2_PLL (OMAP2420_CM_BASE+0x544) +#define CM_CLKSEL_DSP (OMAP2420_CM_BASE+0x840) + +/* + * H4 specific Section + */ + +/* + * The 2420's chip selects are programmable. The mask ROM + * does configure CS0 to 0x08000000 before dispatch. So, if + * you want your code to live below that address, you have to + * be prepared to jump though hoops, to reset the base address. + */ +#if defined(CONFIG_OMAP2420H4) +/* GPMC */ +#ifdef CONFIG_VIRTIO_A /* Pre version B */ +# define H4_CS0_BASE 0x08000000 /* flash (64 Meg aligned) */ +# define H4_CS1_BASE 0x04000000 /* debug board */ +# define H4_CS2_BASE 0x0A000000 /* wifi board */ +#else +# define H4_CS0_BASE 0x04000000 /* flash (64 Meg aligned) */ +# define H4_CS1_BASE 0x08000000 /* debug board */ +# define H4_CS2_BASE 0x0A000000 /* wifi board */ +#endif + +/* base address for indirect vectors (internal boot mode) */ +#define SRAM_OFFSET0 0x40000000 +#define SRAM_OFFSET1 0x00200000 +#define SRAM_OFFSET2 0x0000F800 +#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) + +#define LOW_LEVEL_SRAM_STACK 0x4020FFFC + +#define PERIFERAL_PORT_BASE 0x480FE003 + +/* FPGA on Debug board.*/ +#define ETH_CONTROL_REG (H4_CS1_BASE+0x30b) +#define LAN_RESET_REGISTER (H4_CS1_BASE+0x1c) +#endif /* endif CONFIG_2420H4 */ + +#endif +
diff --git a/x-loader/include/asm/arch-arm1136/omap2430.h b/x-loader/include/asm/arch-arm1136/omap2430.h new file mode 100644 index 0000000..d2288aa --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/omap2430.h
@@ -0,0 +1,246 @@ +/* + * (C) Copyright 2004-2005 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP2430_SYS_H_ +#define _OMAP2430_SYS_H_ + +#include <asm/arch/sizes.h> + +/* device type */ +#define DEVICE_MASK (BIT8|BIT9|BIT10) +#define TST_DEVICE 0x0 +#define EMU_DEVICE 0x1 +#define HS_DEVICE 0x2 +#define GP_DEVICE 0x3 + +/* + * 2430 specific Section + */ +#define OMAP243X_CORE_L4_IO_BASE 0x48000000 +#define OMAP243X_WAKEUP_L4_IO_BASE 0x49000000 +#define OMAP24XX_L4_IO_BASE OMAP243X_CORE_L4_IO_BASE + + +/* CONTROL */ +#define OMAP24XX_CTRL_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0x2000) +#define CONTROL_STATUS (OMAP24XX_CTRL_BASE + 0x2F8) + +/* TAP information */ +#define OMAP24XX_TAP_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0xA000) +#define TAP_IDCODE_REG (OMAP24XX_TAP_BASE+0x204) + +/* + GPMC : In 2430 NOR and NAND can coexist. + During NAND booting , NAND is at CS0 and NOR at CS1 + and Debug FPGA is GPMC_CS5 +*/ +#define OMAP24XX_GPMC_BASE (0x6E000000) + +#define GPMC_SYSCONFIG (OMAP24XX_GPMC_BASE+0x10) +#define GPMC_SYSSTATUS (OMAP24XX_GPMC_BASE+0x14) +#define GPMC_IRQENABLE (OMAP24XX_GPMC_BASE+0x1C) +#define GPMC_TIMEOUT_CONTROL (OMAP24XX_GPMC_BASE+0x40) +#define GPMC_CONFIG (OMAP24XX_GPMC_BASE+0x50) +#define GPMC_CONFIG1_0 (OMAP24XX_GPMC_BASE+0x60) +#define GPMC_CONFIG2_0 (OMAP24XX_GPMC_BASE+0x64) +#define GPMC_CONFIG3_0 (OMAP24XX_GPMC_BASE+0x68) +#define GPMC_CONFIG4_0 (OMAP24XX_GPMC_BASE+0x6C) +#define GPMC_CONFIG5_0 (OMAP24XX_GPMC_BASE+0x70) +#define GPMC_CONFIG6_0 (OMAP24XX_GPMC_BASE+0x74) +#define GPMC_CONFIG7_0 (OMAP24XX_GPMC_BASE+0x78) +#define GPMC_CONFIG1_1 (OMAP24XX_GPMC_BASE+0x90) +#define GPMC_CONFIG2_1 (OMAP24XX_GPMC_BASE+0x94) +#define GPMC_CONFIG3_1 (OMAP24XX_GPMC_BASE+0x98) +#define GPMC_CONFIG4_1 (OMAP24XX_GPMC_BASE+0x9C) +#define GPMC_CONFIG5_1 (OMAP24XX_GPMC_BASE+0xA0) +#define GPMC_CONFIG6_1 (OMAP24XX_GPMC_BASE+0xA4) +#define GPMC_CONFIG7_1 (OMAP24XX_GPMC_BASE+0xA8) +#define GPMC_CONFIG1_5 (OMAP24XX_GPMC_BASE+0x150) +#define GPMC_CONFIG2_5 (OMAP24XX_GPMC_BASE+0x154) +#define GPMC_CONFIG3_5 (OMAP24XX_GPMC_BASE+0x158) +#define GPMC_CONFIG4_5 (OMAP24XX_GPMC_BASE+0x15C) +#define GPMC_CONFIG5_5 (OMAP24XX_GPMC_BASE+0x160) +#define GPMC_CONFIG6_5 (OMAP24XX_GPMC_BASE+0x164) +#define GPMC_CONFIG7_5 (OMAP24XX_GPMC_BASE+0x168) + + +/* SMS */ +#define OMAP24XX_SMS_BASE 0x6C000000 +#define SMS_SYSCONFIG (OMAP24XX_SMS_BASE+0x10) + +/* SDRC */ +#define OMAP24XX_SDRC_BASE 0x6D000000 +#define OMAP24XX_SDRC_CS0 0x80000000 +#define OMAP24XX_SDRC_CS1 0xA0000000 +#define SDRC_SYSCONFIG (OMAP24XX_SDRC_BASE+0x10) +#define SDRC_STATUS (OMAP24XX_SDRC_BASE+0x14) +#define SDRC_SHARING (OMAP24XX_SDRC_BASE+0x44) +#define SDRC_DLLA_CTRL (OMAP24XX_SDRC_BASE+0x60) +#define SDRC_DLLA_STATUS (OMAP24XX_SDRC_BASE+0x64) +#define SDRC_DLLB_CTRL (OMAP24XX_SDRC_BASE+0x68) +#define SDRC_POWER (OMAP24XX_SDRC_BASE+0x70) +#define SDRC_MCFG_0 (OMAP24XX_SDRC_BASE+0x80) +#define SDRC_MR_0 (OMAP24XX_SDRC_BASE+0x84) +#define SDRC_ACTIM_CTRLA_0 (OMAP24XX_SDRC_BASE+0x9C) +#define SDRC_ACTIM_CTRLB_0 (OMAP24XX_SDRC_BASE+0xA0) +#define SDRC_MCFG_1 (OMAP24XX_SDRC_BASE+0xB0) +#define SDRC_ACTIM_CTRLA_1 (OMAP24XX_SDRC_BASE+0xC4) +#define SDRC_ACTIM_CTRLB_1 (OMAP24XX_SDRC_BASE+0xC8) +#define SDRC_RFR_CTRL (OMAP24XX_SDRC_BASE+0xA4) +#define SDRC_MANUAL_0 (OMAP24XX_SDRC_BASE+0xA8) +#define SDRC_RFR_CTRL1 (OMAP24XX_SDRC_BASE+0xD4) + +#define LOADDLL BIT2 +#define CMD_NOP 0x0 +#define CMD_PRECHARGE 0x1 +#define CMD_AUTOREFRESH 0x2 +#define CMD_ENTR_PWRDOWN 0x3 +#define CMD_EXIT_PWRDOWN 0x4 +#define CMD_ENTR_SRFRSH 0x5 +#define CMD_CKE_HIGH 0x6 +#define CMD_CKE_LOW 0x7 +#define SOFTRESET BIT1 +#define SMART_IDLE (0x2 << 3) +#define REF_ON_IDLE (0x1 << 6) + + +/* UART */ +#define OMAP2430_UART1 0x4806A000 +#define OMAP2430_UART2 0x4806C000 +#define OMAP2430_UART3 0x4806E000 + +/* General Purpose Timers */ +#define OMAP24XX_GPT1 (OMAP243X_WAKEUP_L4_IO_BASE+0x18000) +#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000) +#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000) +#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000) +#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000) +#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000) +#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000) +#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000) +#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000) +#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000) +#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000) +#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000 + +/* timer regs offsets (32 bit regs) */ +#define TIDR 0x0 /* r */ +#define TIOCP_CFG 0x10 /* rw */ +#define TISTAT 0x14 /* r */ +#define TISR 0x18 /* rw */ +#define TIER 0x1C /* rw */ +#define TWER 0x20 /* rw */ +#define TCLR 0x24 /* rw */ +#define TCRR 0x28 /* rw */ +#define TLDR 0x2C /* rw */ +#define TTGR 0x30 /* rw */ +#define TWPS 0x34 /* r */ +#define TMAR 0x38 /* rw */ +#define TCAR1 0x3c /* r */ +#define TSICR 0x40 /* rw */ +#define TCAR2 0x44 /* r */ + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0x14000) +#define WD2_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0x16000) +#define WD3_BASE (OMAP24XX_L4_IO_BASE+0x24000) /* not present */ +#define WD4_BASE (OMAP24XX_L4_IO_BASE+0x26000) + +/* 32KTIMER */ +#define SYNC_32KTIMER_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0x20000) +#define S32K_CR (SYNC_32KTIMER_BASE+0x10) + +#define WWPS 0x34 /* r */ +#define WSPR 0x48 /* rw */ +#define WD_UNLOCK1 0xAAAA +#define WD_UNLOCK2 0x5555 + +/* PRCM */ +#define OMAP24XX_CM_BASE (OMAP243X_WAKEUP_L4_IO_BASE+0x06000) + +#define PRCM_CLKSRC_CTRL (OMAP24XX_CM_BASE+0x060) +#define PRCM_CLKOUT_CTRL (OMAP24XX_CM_BASE+0x070) +#define PRCM_CLKEMUL_CTRL (OMAP24XX_CM_BASE+0x078) +#define PRCM_CLKCFG_CTRL (OMAP24XX_CM_BASE+0x080) +#define PRCM_CLKCFG_STATUS (OMAP24XX_CM_BASE+0x084) +#define CM_CLKSEL_MPU (OMAP24XX_CM_BASE+0x140) +#define CM_FCLKEN1_CORE (OMAP24XX_CM_BASE+0x200) +#define CM_FCLKEN2_CORE (OMAP24XX_CM_BASE+0x204) +#define CM_ICLKEN1_CORE (OMAP24XX_CM_BASE+0x210) +#define CM_ICLKEN2_CORE (OMAP24XX_CM_BASE+0x214) +#define CM_CLKSEL1_CORE (OMAP24XX_CM_BASE+0x240) +#define CM_CLKSEL_WKUP (OMAP24XX_CM_BASE+0x440) +#define CM_CLKSEL2_CORE (OMAP24XX_CM_BASE+0x244) +#define CM_FCLKEN_GFX (OMAP24XX_CM_BASE+0x300) +#define CM_ICLKEN_GFX (OMAP24XX_CM_BASE+0x310) +#define CM_CLKSEL_GFX (OMAP24XX_CM_BASE+0x340) +#define RM_RSTCTRL_GFX (OMAP24XX_CM_BASE+0x350) +#define CM_FCLKEN_WKUP (OMAP24XX_CM_BASE+0x400) +#define CM_ICLKEN_WKUP (OMAP24XX_CM_BASE+0x410) +#define PM_RSTCTRL_WKUP (OMAP24XX_CM_BASE+0x450) +#define CM_CLKEN_PLL (OMAP24XX_CM_BASE+0x500) +#define CM_IDLEST_CKGEN (OMAP24XX_CM_BASE+0x520) +#define CM_CLKSEL1_PLL (OMAP24XX_CM_BASE+0x540) +#define CM_CLKSEL2_PLL (OMAP24XX_CM_BASE+0x544) +#define CM_CLKSEL_DSP (OMAP24XX_CM_BASE+0x840) +#define CM_CLKSEL_MDM (OMAP24XX_CM_BASE+0xC40) + +/* SMX-APE */ +#define SMX_APE_BASE 0x68000000 +#define PM_RT_APE_BASE_ADDR_ARM (SMX_APE_BASE + 0x10000) +#define PM_GPMC_BASE_ADDR_ARM (SMX_APE_BASE + 0x12400) +#define PM_OCM_RAM_BASE_ADDR_ARM (SMX_APE_BASE + 0x12800) +#define PM_OCM_ROM_BASE_ADDR_ARM (SMX_APE_BASE + 0x12C00) + +/* IVA2 */ +#define PM_IVA2_BASE_ADDR_ARM (SMX_APE_BASE + 0x14000) + +/* + * The 2430's chip selects are programmable. The mask ROM + * does configure CS0 to 0x08000000 before dispatch. So, if + * you want your code to live below that address, you have to + * be prepared to jump though hoops, to reset the base address. + */ +#if defined(CONFIG_OMAP243X) + +/* GPMC */ +/* This is being used by the macros in mem.h. PHYS_FLASH_1 is defined to H4_CS0_BASE */ +# define H4_CS1_BASE 0x09000000 /* flash (64 Meg aligned) */ +#define CFG_FLASH_BASE H4_CS1_BASE +#define DEBUG_BASE 0x08000000 + +/* base address for indirect vectors (internal boot mode) */ +#define SRAM_OFFSET0 0x40000000 +#define SRAM_OFFSET1 0x00200000 +#define SRAM_OFFSET2 0x0000F800 +#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) + +#define LOW_LEVEL_SRAM_STACK 0x4020FFFC + +#define PERIFERAL_PORT_BASE 0x480FE003 + +#endif /* endif CONFIG_2430SDP */ + +#endif +
diff --git a/x-loader/include/asm/arch-arm1136/sizes.h b/x-loader/include/asm/arch-arm1136/sizes.h new file mode 100644 index 0000000..3dddd8e --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/sizes.h
@@ -0,0 +1,50 @@ +/* + * 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 + */ +/* Size defintions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_32K 0x00008000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_31M 0x01F00000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif /* __sizes_h */ +
diff --git a/x-loader/include/asm/arch-arm1136/sys_info.h b/x-loader/include/asm/arch-arm1136/sys_info.h new file mode 100644 index 0000000..94a09cd --- /dev/null +++ b/x-loader/include/asm/arch-arm1136/sys_info.h
@@ -0,0 +1,139 @@ +/* + * Copyright 2005 (C) Texas Instruments, <www.ti.com> + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP24XX_SYS_INFO_H_ +#define _OMAP24XX_SYS_INFO_H_ + +#if 0 +typedef struct h4_system_data { + /* base board info */ + u32 base_b_rev; /* rev from base board i2c */ + /* cpu board info */ + u32 cpu_b_rev; /* rev from cpu board i2c */ + u32 cpu_b_mux; /* mux type on daughter board */ + u32 cpu_b_ddr_type; /* mem type */ + u32 cpu_b_ddr_speed; /* ddr speed rating */ + u32 cpu_b_switches; /* boot ctrl switch settings */ + /* cpu info */ + u32 cpu_type; /* type of cpu; 2420, 2422, 2430,...*/ + u32 cpu_rev; /* rev of given cpu; ES1, ES2,...*/ +} h4_sys_data; + +#endif + +#define XDR_POP 5 /* package on package part */ +#define SDR_DISCRETE 4 /* 128M memory SDR module*/ +#define DDR_STACKED 3 /* stacked part on 2422 */ +#define DDR_COMBO 2 /* combo part on cpu daughter card (menalaeus) */ +#define DDR_DISCRETE 1 /* 2x16 parts on daughter card */ + +#define DDR_100 100 /* type found on most mem d-boards */ +#define DDR_111 111 /* some combo parts */ +#define DDR_133 133 /* most combo, some mem d-boards */ +#define DDR_165 165 /* future parts */ + +#define CPU_2420 0x2420 +#define CPU_2422 0x2422 /* 2420 + 64M stacked */ +#define CPU_2423 0x2423 /* 2420 + 96M stacked */ +#define CPU_2430 0x2430 + +/* 242x real hardware: + * ES1 = rev 0 + * ES2 = rev 1 + * ES2.05 = rev 2 + * ES2.1 = rev 3 + * ES2.1.1 = rev 4 + */ + +/* 242x code defines: + * ES1 = 0+1 = 1 + * ES2 = 1+1 = 2 + * ES2.05 = 2+1 = 3 + * ES2.1 = 3+1 = 4 + * Es2.1.1 = 4+1 = 5 + */ +#define CPU_2422_ES1 1 +#define CPU_2422_ES2 2 +#define CPU_2422_ES2_05 3 +#define CPU_2422_ES2_1 4 +#define CPU_2422_ES2_1_1 5 + +#define CPU_2420_ES1 1 +#define CPU_2420_ES2 2 +#define CPU_2420_ES2_05 3 +#define CPU_2420_ES2_1 4 +#define CPU_2420_ES2_1_1 5 + +#define CPU_242X_ES1 1 +#define CPU_242X_ES2 2 +#define CPU_242X_ES2_05 3 +#define CPU_242X_ES2_1 4 +#define CPU_242X_ES2_1_1 5 + +#define CPU_2420_2422_ES1 1 +#define CPU_2420_2422_ES2_1 4 + +/* 243x real hardware: + * ES1 = rev 0 + * ES2 = rev 1 + * + * 243x code defines: + * ES1 = 0+1 = 1 + * ES2 = 1+1 = 2 + */ +#define CPU_2430_ES1 1 +#define CPU_2430_ES2 2 + +#ifdef VPOM2430 +# define CPU_2430_VIRTIO 3 +#else +# define CPU_2430_VIRTIO 1 +#endif +#define CPU_2430_ZEBU 0xD + +#define CPU_2420_CHIPID 0x0B5D9000 +#define CPU_2430_CHIPID 0x0B68A000 +#define CPU_24XX_ID_MASK 0x0FFFF000 +#define CPU_242X_REV_MASK 0xF0000000 +#define CPU_242X_PID_MASK 0x000F0000 + +#define BOARD_H4_MENELAUS 1 +#define BOARD_H4_SDP 2 +#define BOARD_H4_MENELAUS_HRP 3 +#define BOARD_SDP_2430 4 + +#define GPMC_MUXED 1 +#define GPMC_NONMUXED 0 + +#define TYPE_NAND 0x800 /* bit pos for nand in gpmc reg */ +#define TYPE_NOR 0x000 +#define TYPE_ONENAND 0x800 + +#define WIDTH_8BIT 0x0000 +#define WIDTH_16BIT 0x1000 /* bit pos for 16 bit in gpmc */ + +#define I2C_MENELAUS 0x72 /* i2c id for companion chip */ + +#endif
diff --git a/x-loader/include/asm/arch-arm926ejs/sizes.h b/x-loader/include/asm/arch-arm926ejs/sizes.h new file mode 100644 index 0000000..ef0b99b --- /dev/null +++ b/x-loader/include/asm/arch-arm926ejs/sizes.h
@@ -0,0 +1,51 @@ +/* + * 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, MA0 2111-1307 + * USA + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Size defintions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif /* __sizes_h */
diff --git a/x-loader/include/asm/arch-omap3/bits.h b/x-loader/include/asm/arch-omap3/bits.h new file mode 100644 index 0000000..ad468be --- /dev/null +++ b/x-loader/include/asm/arch-omap3/bits.h
@@ -0,0 +1,57 @@ +/* bits.h + * + * Copyright (c) 2010 Nest Labs, Inc. + * + * Copyright (c) 2004 Texas Instruments + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the license found in the file + * named COPYING that should have accompanied this file. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef __bits_h +#define __bits_h 1 + +#define ARM_REG_MASK(bits) ((1 << (bits)) - 1) +#define ARM_REG_VAL(bit, mask) ((mask) << (bit)) +#define ARM_REG_VAL_ENCODE(shift, mask, value) (((value) << (shift)) & (mask)) +#define ARM_REG_VAL_DECODE(shift, mask, value) (((value) & (mask)) >> (shift)) + + +#define BIT0 ARM_REG_VAL( 0, 1) +#define BIT1 ARM_REG_VAL( 1, 1) +#define BIT2 ARM_REG_VAL( 2, 1) +#define BIT3 ARM_REG_VAL( 3, 1) +#define BIT4 ARM_REG_VAL( 4, 1) +#define BIT5 ARM_REG_VAL( 5, 1) +#define BIT6 ARM_REG_VAL( 6, 1) +#define BIT7 ARM_REG_VAL( 7, 1) +#define BIT8 ARM_REG_VAL( 8, 1) +#define BIT9 ARM_REG_VAL( 9, 1) +#define BIT10 ARM_REG_VAL(10, 1) +#define BIT11 ARM_REG_VAL(11, 1) +#define BIT12 ARM_REG_VAL(12, 1) +#define BIT13 ARM_REG_VAL(13, 1) +#define BIT14 ARM_REG_VAL(14, 1) +#define BIT15 ARM_REG_VAL(15, 1) +#define BIT16 ARM_REG_VAL(16, 1) +#define BIT17 ARM_REG_VAL(17, 1) +#define BIT18 ARM_REG_VAL(18, 1) +#define BIT19 ARM_REG_VAL(19, 1) +#define BIT20 ARM_REG_VAL(20, 1) +#define BIT21 ARM_REG_VAL(21, 1) +#define BIT22 ARM_REG_VAL(22, 1) +#define BIT23 ARM_REG_VAL(23, 1) +#define BIT24 ARM_REG_VAL(24, 1) +#define BIT25 ARM_REG_VAL(25, 1) +#define BIT26 ARM_REG_VAL(26, 1) +#define BIT27 ARM_REG_VAL(27, 1) +#define BIT28 ARM_REG_VAL(28, 1) +#define BIT29 ARM_REG_VAL(29, 1) +#define BIT30 ARM_REG_VAL(30, 1) +#define BIT31 ARM_REG_VAL(31, 1) + +#endif
diff --git a/x-loader/include/asm/arch-omap3/clocks.h b/x-loader/include/asm/arch-omap3/clocks.h new file mode 100644 index 0000000..f6d21d3 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/clocks.h
@@ -0,0 +1,36 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP34XX_CLOCKS_H_ +#define _OMAP34XX_CLOCKS_H_ + +#define LDELAY 12000000 + +#define S12M 12000000 +#define S13M 13000000 +#define S16_8M 16800000 +#define S19_2M 19200000 +#define S24M 24000000 +#define S26M 26000000 +#define S38_4M 38400000 + +#include <asm/arch/clocks343x.h> + +#endif
diff --git a/x-loader/include/asm/arch-omap3/clocks343x.h b/x-loader/include/asm/arch-omap3/clocks343x.h new file mode 100644 index 0000000..133edd1 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/clocks343x.h
@@ -0,0 +1,157 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP343X_CLOCKS_H_ +#define _OMAP343X_CLOCKS_H_ + +#define PLL_STOP 1 /* PER & IVA */ +#define PLL_LOW_POWER_BYPASS 5 /* MPU, IVA & CORE */ +#define PLL_FAST_RELOCK_BYPASS 6 /* CORE */ +#define PLL_LOCK 7 /* MPU, IVA, CORE & PER */ + +/* The following configurations are OPP and SysClk value independant + * and hence are defined here. All the other DPLL related values are + * tabulated in lowlevel_init.S. + */ + +/* CORE DPLL */ +# define CORE_M3X2 2 /* 332MHz : CM_CLKSEL1_EMU */ +# define CORE_SSI_DIV 3 /* 221MHz : CM_CLKSEL_CORE */ +# define CORE_FUSB_DIV 2 /* 41.5MHz: */ +# define CORE_L4_DIV 2 /* 83MHz : L4 */ +# define CORE_L3_DIV 2 /* 166MHz : L3 {DDR} */ +# define GFX_DIV_34X 3 /* 96MHz : CM_CLKSEL_GFX */ +# define GFX_DIV_36X 5 /* 200MHz : CM_CLKSEL_GFX */ +/* Keep default to 96Mhz */ +# define GFX_DIV 3 /* 96MHz : CM_CLKSEL_GFX */ +# define WKUP_RSM 2 /* 41.5MHz: CM_CLKSEL_WKUP */ + +/* PER DPLL */ +# define PER_M6X2 3 /* 288MHz: CM_CLKSEL1_EMU */ +# define PER_M5X2 4 /* 216MHz: CM_CLKSEL_CAM */ +# define PER_M4X2 9 /* 96MHz : CM_CLKSEL_DSS-dss1 */ +# define PER_M3X2 16 /* 54MHz : CM_CLKSEL_DSS-tv */ + +# define CLSEL1_EMU_VAL ((CORE_M3X2 << 16) | (PER_M6X2 << 24) | (0x0a50)) + +#ifdef PRCM_CLK_CFG2_332MHZ +# define M_12 0xA6 +# define N_12 0x05 +# define FSEL_12 0x07 +# define M2_12 0x01 /* M3 of 2 */ + +# define M_12_ES1 0x0E +# define FSL_12_ES1 0x03 +# define M2_12_ES1 0x1 /* M3 of 2 */ + +# define M_13 0x14C +# define N_13 0x0C +# define FSEL_13 0x03 +# define M2_13 0x01 /* M3 of 2 */ + +# define M_13_ES1 0x1B2 +# define N_13_ES1 0x10 +# define FSL_13_ES1 0x03 +# define M2_13_ES1 0x01 /* M3 of 2 */ + +# define M_19p2 0x19F +# define N_19p2 0x17 +# define FSEL_19p2 0x03 +# define M2_19p2 0x01 /* M3 of 2 */ + +# define M_19p2_ES1 0x19F +# define N_19p2_ES1 0x17 +# define FSL_19p2_ES1 0x03 +# define M2_19p2_ES1 0x01 /* M3 of 2 */ + +# define M_26 0xA6 +# define N_26 0x0C +# define FSEL_26 0x07 +# define M2_26 0x01 /* M3 of 2 */ + +# define M_26_ES1 0x1B2 +# define N_26_ES1 0x21 +# define FSL_26_ES1 0x03 +# define M2_26_ES1 0x01 /* M3 of 2 */ + +# define M_38p4 0x19F +# define N_38p4 0x2F +# define FSEL_38p4 0x03 +# define M2_38p4 0x01 /* M3 of 2 */ + +# define M_38p4_ES1 0x19F +# define N_38p4_ES1 0x2F +# define FSL_38p4_ES1 0x03 +# define M2_38p4_ES1 0x01 /* M3 of 2 */ + +#elif defined(PRCM_CLK_CFG2_266MHZ) +# define M_12 0x85 +# define N_12 0x05 +# define FSEL_12 0x07 +# define M2_12 0x02 /* M3 of 2 */ + +# define M_12_ES1 0x85 /* 0x10A */ +# define N_12_ES1 0x05 /* 0x05 */ +# define FSL_12_ES1 0x07 /* 0x7 */ +# define M2_12_ES1 0x2 /* 0x2 with an M3 of 4*/ + +# define M_13 0x10A +# define N_13 0x0C +# define FSEL_13 0x3 +# define M2_13 0x1 /* M3 of 2 */ + +# define M_13_ES1 0x10A /* 0x214 */ +# define N_13_ES1 0x0C /* 0xC */ +# define FSL_13_ES1 0x3 /* 0x3 */ +# define M2_13_ES1 0x1 /* 0x2 with an M3 of 4*/ + +# define M_19p2 0x115 +# define N_19p2 0x13 +# define FSEL_19p2 0x03 +# define M2_19p2 0x01 /* M3 of 2 */ + +# define M_19p2_ES1 0x115 /* 0x299 */ +# define N_19p2_ES1 0x13 /* 0x17 */ +# define FSL_19p2_ES1 0x03 /* 0x03 */ +# define M2_19p2_ES1 0x01 /* 0x2 with M3 of 4 */ + +# define M_26 0x85 +# define N_26 0x0C +# define FSEL_26 0x07 +# define M2_26 0x01 /* M3 of 2 */ + +# define M_26_ES1 0x85 /* 0x10A */ +# define N_26_ES1 0x0C /* 0xC */ +# define FSL_26_ES1 0x07 /* 0x7 */ +# define M2_26_ES1 0x01 /* 0x2 with an M3 of 4 */ + +# define M_38p4 0x11C +# define N_38p4 0x28 +# define FSEL_38p4 0x03 +# define M2_38p4 0x01 /* M3 of 2 */ + +# define M_38p4_ES1 0x11C /* 0x299 */ +# define N_38p4_ES1 0x28 /* 0x2f */ +# define FSL_38p4_ES1 0x03 /* 0x3 */ +# define M2_38p4_ES1 0x01 /* 0x2 with an M3 of 4*/ + + # endif + +#endif /* endif _OMAP343X_CLOCKS_H_ */
diff --git a/x-loader/include/asm/arch-omap3/cpu.h b/x-loader/include/asm/arch-omap3/cpu.h new file mode 100644 index 0000000..c4a7831 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/cpu.h
@@ -0,0 +1,469 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _OMAP34XX_CPU_H +#define _OMAP34XX_CPU_H +#if defined (CONFIG_AM3517EVM) || defined (CONFIG_AM3517TEB) +#include <asm/arch/omap3.h> +#elif defined (CONFIG_OMAP3430) +#include <asm/arch/omap3430.h> +#endif + +#include <asm/arch/gpmc.h> +#include <asm/arch/prcm.h> +#include <asm/arch/sdrc.h> + +/* Register offsets of common modules */ +/* Control */ +#define CONTROL_STATUS (OMAP34XX_CTRL_BASE + 0x2F0) +#define OMAP34XX_MCR (OMAP34XX_CTRL_BASE + 0x8C) +#define CONTROL_SCALABLE_OMAP_STATUS (OMAP34XX_CTRL_BASE + 0x44C) +#define CONTROL_SCALABLE_OMAP_OCP (OMAP34XX_CTRL_BASE + 0x534) + + +/* Tap Information */ +#define TAP_IDCODE_REG (OMAP34XX_TAP_BASE+0x204) +#define PRODUCTION_ID (OMAP34XX_TAP_BASE+0x208) + +/* OMAP 34XX/35XX/36xx/37xx Control ID */ +#define OMAP34XX_CONTROL_ID (OMAP34XX_WAKEUP_L4_IO_BASE + 0xa204) + +#define CONTROL_STATUS_DEVICETYPE_MASK ARM_REG_VAL(8, 0x7) +#define CONTROL_STATUS_DEVICETYPE_ENCODE(v) (((v) << 8) & CONTROL_STATUS_DEVICETYPE_MASK) +#define CONTROL_STATUS_DEVICETYPE_DECODE(v) (((v) & CONTROL_STATUS_DEVICETYPE_MASK) >> 8) +#define CONTROL_STATUS_DEVICETYPE_TST 0x0 +#define CONTROL_STATUS_DEVICETYPE_EMU 0x1 +#define CONTROL_STATUS_DEVICETYPE_HS 0x2 +#define CONTROL_STATUS_DEVICETYPE_GP 0x3 + +/* + * Legacy mnemonics + */ +#define DEVICE_MASK CONTROL_STATUS_DEVICETYPE_MASK +#define TST_DEVICE CONTROL_STATUS_DEVICETYPE_TST +#define EMU_DEVICE CONTROL_STATUS_DEVICETYPE_EMU +#define HS_DEVICE CONTROL_STATUS_DEVICETYPE_HS +#define GP_DEVICE CONTROL_STATUS_DEVICETYPE_GP + +#define CONTROL_STATUS_SYSBOOT_MASK ARM_REG_VAL(0, 0x3F) +#define CONTROL_STATUS_SYSBOOT_ENCODE(v) (((v) << 0) & CONTROL_STATUS_SYSBOOT_MASK) +#define CONTROL_STATUS_SYSBOOT_DECODE(v) (((v) & CONTROL_STATUS_SYSBOOT_MASK) >> 0) + +#define CONTROL_STATUS_SYSBOOT_TYPE_MASK ARM_REG_VAL(5, 0x1) +#define CONTROL_STATUS_SYSBOOT_TYPE_ENCODE(v) (((v) << 0) & CONTROL_STATUS_SYSBOOT_TYPE_MASK) +#define CONTROL_STATUS_SYSBOOT_TYPE_DECODE(v) (((v) & CONTROL_STATUS_SYSBOOT_TYPE_MASK) >> 0) +#define CONTROL_STATUS_SYSBOOT_TYPE_MEMORY 0x0 +#define CONTROL_STATUS_SYSBOOT_TYPE_PERIPHERAL 0x1 + +#define CONTROL_STATUS_SYSBOOT_ORDER_MASK ARM_REG_VAL(0, 0x1F) +#define CONTROL_STATUS_SYSBOOT_ORDER_ENCODE(v) (((v) << 0) & CONTROL_STATUS_SYSBOOT_ORDER_MASK) +#define CONTROL_STATUS_SYSBOOT_ORDER_DECODE(v) (((v) & CONTROL_STATUS_SYSBOOT_ORDER_MASK) >> 0) + +/* + * Legacy mneomnic + * + * We are not concerned with BIT5 as it only determines the prirotiy + * between memory or perpheral booting + */ +#define SYSBOOT_MASK CONTROL_STATUS_SYSBOOT_ORDER_MASK + +/* GPMC CS3/cs4/cs6 not avaliable */ + +#define GPMC_BASE (OMAP34XX_GPMC_BASE) + +#define GPMC_REVISION (GPMC_BASE + 0x0000) +#define GPMC_SYSCONFIG (GPMC_BASE + 0x0010) +#define GPMC_SYSSTATUS (GPMC_BASE + 0x0014) +#define GPMC_IRQSTATUS (GPMC_BASE + 0x0018) +#define GPMC_IRQENABLE (GPMC_BASE + 0x001C) +#define GPMC_TIMEOUT_CONTROL (GPMC_BASE + 0x0040) +#define GPMC_ERR_ADDRESS (GPMC_BASE + 0x0044) +#define GPMC_ERR_TYPE (GPMC_BASE + 0x0048) +#define GPMC_CONFIG (GPMC_BASE + 0x0050) +#define GPMC_STATUS (GPMC_BASE + 0x0054) + +#define GPMC_CONFIG_BASE (GPMC_BASE + 0x0060) +#define GPMC_CONFIG_SIZE 0x0030 +#define GPMC_CONFIGX_BASE(reg) (GPMC_CONFIG_BASE + (((reg) - 1) * 4)) +#define GPMC_CONFIGX(reg, cs) (GPMC_CONFIGX_BASE(reg) + ((cs) * GPMC_CONFIG_SIZE)) + +#define GPMC_CONFIG1(cs) GPMC_CONFIGX(1, cs) +#define GPMC_CONFIG2(cs) GPMC_CONFIGX(2, cs) +#define GPMC_CONFIG3(cs) GPMC_CONFIGX(3, cs) +#define GPMC_CONFIG4(cs) GPMC_CONFIGX(4, cs) +#define GPMC_CONFIG5(cs) GPMC_CONFIGX(5, cs) +#define GPMC_CONFIG6(cs) GPMC_CONFIGX(6, cs) +#define GPMC_CONFIG7(cs) GPMC_CONFIGX(7, cs) + +#define GPMC_CONFIG1_0 GPMC_CONFIG1(0) +#define GPMC_CONFIG2_0 GPMC_CONFIG2(0) +#define GPMC_CONFIG3_0 GPMC_CONFIG3(0) +#define GPMC_CONFIG4_0 GPMC_CONFIG4(0) +#define GPMC_CONFIG5_0 GPMC_CONFIG5(0) +#define GPMC_CONFIG6_0 GPMC_CONFIG6(0) +#define GPMC_CONFIG7_0 GPMC_CONFIG7(0) + +#define GPMC_CONFIG1_1 GPMC_CONFIG1(1) +#define GPMC_CONFIG2_1 GPMC_CONFIG2(1) +#define GPMC_CONFIG3_1 GPMC_CONFIG3(1) +#define GPMC_CONFIG4_1 GPMC_CONFIG4(1) +#define GPMC_CONFIG5_1 GPMC_CONFIG5(1) +#define GPMC_CONFIG6_1 GPMC_CONFIG6(1) +#define GPMC_CONFIG7_1 GPMC_CONFIG7(1) + +#define GPMC_CONFIG1_2 GPMC_CONFIG1(2) +#define GPMC_CONFIG2_2 GPMC_CONFIG2(2) +#define GPMC_CONFIG3_2 GPMC_CONFIG3(2) +#define GPMC_CONFIG5_2 GPMC_CONFIG5(2) +#define GPMC_CONFIG4_2 GPMC_CONFIG4(2) +#define GPMC_CONFIG6_2 GPMC_CONFIG6(2) +#define GPMC_CONFIG7_2 GPMC_CONFIG7(2) + +#define GPMC_CONFIG1_3 GPMC_CONFIG1(3) +#define GPMC_CONFIG2_3 GPMC_CONFIG2(3) +#define GPMC_CONFIG3_3 GPMC_CONFIG3(3) +#define GPMC_CONFIG4_3 GPMC_CONFIG4(3) +#define GPMC_CONFIG5_3 GPMC_CONFIG5(3) +#define GPMC_CONFIG6_3 GPMC_CONFIG6(3) +#define GPMC_CONFIG7_3 GPMC_CONFIG7(3) + +#define GPMC_CONFIG1_4 GPMC_CONFIG1(4) +#define GPMC_CONFIG2_4 GPMC_CONFIG2(4) +#define GPMC_CONFIG3_4 GPMC_CONFIG3(4) +#define GPMC_CONFIG4_4 GPMC_CONFIG4(4) +#define GPMC_CONFIG5_4 GPMC_CONFIG5(4) +#define GPMC_CONFIG6_4 GPMC_CONFIG6(4) +#define GPMC_CONFIG7_4 GPMC_CONFIG7(4) + +#define GPMC_CONFIG1_5 GPMC_CONFIG1(5) +#define GPMC_CONFIG2_5 GPMC_CONFIG2(5) +#define GPMC_CONFIG3_5 GPMC_CONFIG3(5) +#define GPMC_CONFIG4_5 GPMC_CONFIG4(5) +#define GPMC_CONFIG5_5 GPMC_CONFIG5(5) +#define GPMC_CONFIG6_5 GPMC_CONFIG6(5) +#define GPMC_CONFIG7_5 GPMC_CONFIG7(5) + +#define GPMC_CONFIG1_6 GPMC_CONFIG1(6) +#define GPMC_CONFIG2_6 GPMC_CONFIG2(6) +#define GPMC_CONFIG3_6 GPMC_CONFIG3(6) +#define GPMC_CONFIG4_6 GPMC_CONFIG4(6) +#define GPMC_CONFIG5_6 GPMC_CONFIG5(6) +#define GPMC_CONFIG6_6 GPMC_CONFIG6(6) +#define GPMC_CONFIG7_6 GPMC_CONFIG7(6) + +#define GPMC_CONFIG1_7 GPMC_CONFIG1(7) +#define GPMC_CONFIG2_7 GPMC_CONFIG2(7) +#define GPMC_CONFIG3_7 GPMC_CONFIG3(7) +#define GPMC_CONFIG4_7 GPMC_CONFIG4(7) +#define GPMC_CONFIG5_7 GPMC_CONFIG5(7) +#define GPMC_CONFIG6_7 GPMC_CONFIG6(7) +#define GPMC_CONFIG7_7 GPMC_CONFIG7(7) + +#define GPMC_NAND_COMMAND(i) (GPMC_BASE + 0x007C + ((i) * 0x0030)) +#define GPMC_NAND_COMMAND_0 GPMC_NAND_COMMAND(0) +#define GPMC_NAND_COMMAND_1 GPMC_NAND_COMMAND(1) +#define GPMC_NAND_COMMAND_2 GPMC_NAND_COMMAND(2) +#define GPMC_NAND_COMMAND_3 GPMC_NAND_COMMAND(3) +#define GPMC_NAND_COMMAND_4 GPMC_NAND_COMMAND(4) +#define GPMC_NAND_COMMAND_5 GPMC_NAND_COMMAND(5) +#define GPMC_NAND_COMMAND_6 GPMC_NAND_COMMAND(6) +#define GPMC_NAND_COMMAND_7 GPMC_NAND_COMMAND(7) + +#define GPMC_NAND_ADDRESS(i) (GPMC_BASE + 0x0080 + ((i) * 0x0030)) +#define GPMC_NAND_ADDRESS_0 GPMC_NAND_ADDRESS(0) +#define GPMC_NAND_ADDRESS_1 GPMC_NAND_ADDRESS(1) +#define GPMC_NAND_ADDRESS_2 GPMC_NAND_ADDRESS(2) +#define GPMC_NAND_ADDRESS_3 GPMC_NAND_ADDRESS(3) +#define GPMC_NAND_ADDRESS_4 GPMC_NAND_ADDRESS(4) +#define GPMC_NAND_ADDRESS_5 GPMC_NAND_ADDRESS(5) +#define GPMC_NAND_ADDRESS_6 GPMC_NAND_ADDRESS(6) +#define GPMC_NAND_ADDRESS_7 GPMC_NAND_ADDRESS(7) + +#define GPMC_NAND_DATA(i) (GPMC_BASE + 0x0084 + ((i) * 0x0030)) +#define GPMC_NAND_DATA_0 GPMC_NAND_DATA(0) +#define GPMC_NAND_DATA_1 GPMC_NAND_DATA(1) +#define GPMC_NAND_DATA_2 GPMC_NAND_DATA(2) +#define GPMC_NAND_DATA_3 GPMC_NAND_DATA(3) +#define GPMC_NAND_DATA_4 GPMC_NAND_DATA(4) +#define GPMC_NAND_DATA_5 GPMC_NAND_DATA(5) +#define GPMC_NAND_DATA_6 GPMC_NAND_DATA(6) +#define GPMC_NAND_DATA_7 GPMC_NAND_DATA(7) + +#define GPMC_PREFETCH_CONFIG1 (GPMC_BASE + 0x01E0) +#define GPMC_PREFETCH_CONFIG2 (GPMC_BASE + 0x01E4) +#define GPMC_PREFETCH_CONTROL (GPMC_BASE + 0x01EC) +#define GPMC_PREFETCH_STATUS (GPMC_BASE + 0x01F0) + +#define GPMC_ECC_CONFIG (GPMC_BASE + 0x01F4) +#define GPMC_ECC_CONTROL (GPMC_BASE + 0x01F8) +#define GPMC_ECC_SIZE_CONFIG (GPMC_BASE + 0x01FC) +#define GPMC_ECC_RESULT(j) (GPMC_BASE + 0x0200 + \ + (((j) - 1) * 0x0004)) +#define GPMC_ECC1_RESULT GPMC_ECC_RESULT(1) +#define GPMC_ECC2_RESULT GPMC_ECC_RESULT(2) +#define GPMC_ECC3_RESULT GPMC_ECC_RESULT(3) +#define GPMC_ECC4_RESULT GPMC_ECC_RESULT(4) +#define GPMC_ECC5_RESULT GPMC_ECC_RESULT(5) +#define GPMC_ECC6_RESULT GPMC_ECC_RESULT(6) +#define GPMC_ECC7_RESULT GPMC_ECC_RESULT(7) +#define GPMC_ECC8_RESULT GPMC_ECC_RESULT(8) +#define GPMC_ECC9_RESULT GPMC_ECC_RESULT(9) + +#define GPMC_BCH_RESULT0(i) (GPMC_BASE + 0x0240 + ((i) * 0x0010)) +#define GPMC_BCH_RESULT0_0 GPMC_BCH_RESULT0(0) +#define GPMC_BCH_RESULT0_1 GPMC_BCH_RESULT0(1) +#define GPMC_BCH_RESULT0_2 GPMC_BCH_RESULT0(2) +#define GPMC_BCH_RESULT0_3 GPMC_BCH_RESULT0(3) +#define GPMC_BCH_RESULT0_4 GPMC_BCH_RESULT0(4) +#define GPMC_BCH_RESULT0_5 GPMC_BCH_RESULT0(5) +#define GPMC_BCH_RESULT0_6 GPMC_BCH_RESULT0(6) +#define GPMC_BCH_RESULT0_7 GPMC_BCH_RESULT0(7) + +#define GPMC_BCH_RESULT1(i) (GPMC_BASE + 0x0244 + ((i) * 0x0010)) +#define GPMC_BCH_RESULT1_0 GPMC_BCH_RESULT1(0) +#define GPMC_BCH_RESULT1_1 GPMC_BCH_RESULT1(1) +#define GPMC_BCH_RESULT1_2 GPMC_BCH_RESULT1(2) +#define GPMC_BCH_RESULT1_3 GPMC_BCH_RESULT1(3) +#define GPMC_BCH_RESULT1_4 GPMC_BCH_RESULT1(4) +#define GPMC_BCH_RESULT1_5 GPMC_BCH_RESULT1(5) +#define GPMC_BCH_RESULT1_6 GPMC_BCH_RESULT1(6) +#define GPMC_BCH_RESULT1_7 GPMC_BCH_RESULT1(7) + +#define GPMC_BCH_RESULT2(i) (GPMC_BASE + 0x0248 + ((i) * 0x0010)) +#define GPMC_BCH_RESULT2_0 GPMC_BCH_RESULT2(0) +#define GPMC_BCH_RESULT2_1 GPMC_BCH_RESULT2(1) +#define GPMC_BCH_RESULT2_2 GPMC_BCH_RESULT2(2) +#define GPMC_BCH_RESULT2_3 GPMC_BCH_RESULT2(3) +#define GPMC_BCH_RESULT2_4 GPMC_BCH_RESULT2(4) +#define GPMC_BCH_RESULT2_5 GPMC_BCH_RESULT2(5) +#define GPMC_BCH_RESULT2_6 GPMC_BCH_RESULT2(6) +#define GPMC_BCH_RESULT2_7 GPMC_BCH_RESULT2(7) + +#define GPMC_BCH_RESULT3(i) (GPMC_BASE + 0x024C + ((i) * 0x0010)) +#define GPMC_BCH_RESULT3_0 GPMC_BCH_RESULT3(0) +#define GPMC_BCH_RESULT3_1 GPMC_BCH_RESULT3(1) +#define GPMC_BCH_RESULT3_2 GPMC_BCH_RESULT3(2) +#define GPMC_BCH_RESULT3_3 GPMC_BCH_RESULT3(3) +#define GPMC_BCH_RESULT3_4 GPMC_BCH_RESULT3(4) +#define GPMC_BCH_RESULT3_5 GPMC_BCH_RESULT3(5) +#define GPMC_BCH_RESULT3_6 GPMC_BCH_RESULT3(6) +#define GPMC_BCH_RESULT3_7 GPMC_BCH_RESULT3(7) + +#define GPMC_BCH_SWDATA (GPMC_BASE + 0x02D0) + +#if defined (CONFIG_OMAP34XX) || defined (CONFIG_AM3517EVM) +#define GPMC_CONFIG_CS0 (OMAP34XX_GPMC_BASE+0x60) +#elif defined (CONFIG_AM3517TEB) +#define GPMC_CONFIG_CS0 (OMAP34XX_GPMC_BASE+0xC0) +#endif + +/* GPMC Mapping */ +# define FLASH_BASE 0x10000000 /* NOR flash (aligned to 256 Meg) */ +# define FLASH_BASE_SDPV1 0x04000000 /* NOR flash (aligned to 64 Meg) */ +# define FLASH_BASE_SDPV2 0x10000000 /* NOR flash (aligned to 256 Meg) */ +# define DEBUG_BASE 0x08000000 /* debug board */ +# define NAND_BASE 0x30000000 /* NAND addr (actual size small port)*/ +# define PISMO2_BASE 0x18000000 /* PISMO2 CS1/2 */ +# define ONENAND_MAP 0x20000000 /* OneNand addr (actual size small port */ + +/* SMS */ +#define SMS_SYSCONFIG (OMAP34XX_SMS_BASE+0x10) +#define SMS_RG_ATT0 (OMAP34XX_SMS_BASE+0x48) +#define SMS_CLASS_ARB0 (OMAP34XX_SMS_BASE+0xD0) +#define BURSTCOMPLETE_GROUP7 BIT31 + +/* SDRC */ +#define SDRC_REVISION (OMAP34XX_SDRC_BASE + 0x00) +#define SDRC_SYSCONFIG (OMAP34XX_SDRC_BASE + 0x10) +#define SDRC_SYSSTATUS (OMAP34XX_SDRC_BASE + 0x14) +#define SDRC_STATUS SDRC_SYSSTATUS +#define SDRC_CS_CFG (OMAP34XX_SDRC_BASE + 0x40) +#define SDRC_SHARING (OMAP34XX_SDRC_BASE + 0x44) +#define SDRC_ERR_ADDR (OMAP34XX_SDRC_BASE + 0x48) +#define SDRC_ERR_TYPE (OMAP34XX_SDRC_BASE + 0x4C) +#define SDRC_DLLA_CTRL (OMAP34XX_SDRC_BASE + 0x60) +#define SDRC_DLLA_STATUS (OMAP34XX_SDRC_BASE + 0x64) +#define SDRC_DLLB_CTRL (OMAP34XX_SDRC_BASE + 0x68) +#define SDRC_DLLB_STATUS (OMAP34XX_SDRC_BASE + 0x6C) +#define DLLPHASE BIT1 +#define LOADDLL BIT2 +#define DLL_DELAY_MASK 0xFF00 +#define DLL_NO_FILTER_MASK (BIT8|BIT9) +#define SDRC_POWER_REG (OMAP34XX_SDRC_BASE + 0x70) +#define SDRC_POWER SDRC_POWER_REG +#define WAKEUPPROC BIT26 + +#define SDRC_MCFG_0 (OMAP34XX_SDRC_BASE + 0x80) +#define SDRC_MR_0 (OMAP34XX_SDRC_BASE + 0x84) +#define SDRC_EMR2_0 (OMAP34XX_SDRC_BASE + 0x8C) +#define SDRC_ACTIM_CTRLA_0 (OMAP34XX_SDRC_BASE + 0x9C) +#define SDRC_ACTIM_CTRLB_0 (OMAP34XX_SDRC_BASE + 0xA0) +#define SDRC_RFR_CTRL_0 (OMAP34XX_SDRC_BASE + 0xA4) +#define SDRC_MANUAL_0 (OMAP34XX_SDRC_BASE + 0xA8) +#define SDRC_MCFG_1 (OMAP34XX_SDRC_BASE + 0xB0) +#define SDRC_MR_1 (OMAP34XX_SDRC_BASE + 0xB4) +#define SDRC_EMR2_1 (OMAP34XX_SDRC_BASE + 0xBC) +#define SDRC_ACTIM_CTRLA_1 (OMAP34XX_SDRC_BASE + 0xC4) +#define SDRC_ACTIM_CTRLB_1 (OMAP34XX_SDRC_BASE + 0xC8) +#define SDRC_RFR_CTRL_1 (OMAP34XX_SDRC_BASE + 0xD4) +#define SDRC_MANUAL_1 (OMAP34XX_SDRC_BASE + 0xD8) +#define OMAP34XX_SDRC_CS0 0x80000000 +#define OMAP34XX_SDRC_CS1 0xA0000000 +#define CMD_NOP 0x0 +#define CMD_PRECHARGE 0x1 +#define CMD_AUTOREFRESH 0x2 +#define CMD_ENTR_PWRDOWN 0x3 +#define CMD_EXIT_PWRDOWN 0x4 +#define CMD_ENTR_SRFRSH 0x5 +#define CMD_CKE_HIGH 0x6 +#define CMD_CKE_LOW 0x7 +#define SOFTRESET BIT1 +#define SMART_IDLE (0x2 << 3) +#define REF_ON_IDLE (0x1 << 6) + +/* EMIF4 register */ +#define EMIF4_BASE OMAP34XX_SDRC_BASE +#define EMIF4_MOD_ID (EMIF4_BASE + 0x00) +#define EMIF4_SDRAM_STS (EMIF4_BASE + 0x04) +#define EMIF4_SDRAM_CFG (EMIF4_BASE + 0x08) +#define EMIF4_SDRAM_RFCR (EMIF4_BASE + 0x10) +#define EMIF4_SDRAM_RFCR_SHDW (EMIF4_BASE + 0x14) +#define EMIF4_SDRAM_TIM1 (EMIF4_BASE + 0x18) +#define EMIF4_SDRAM_TIM1_SHDW (EMIF4_BASE + 0x1C) +#define EMIF4_SDRAM_TIM2 (EMIF4_BASE + 0x20) +#define EMIF4_SDRAM_TIM2_SHDW (EMIF4_BASE + 0x24) +#define EMIF4_SDRAM_TIM3 (EMIF4_BASE + 0x28) +#define EMIF4_SDRAM_TIM3_SHDW (EMIF4_BASE + 0x2c) +#define EMIF4_PWR_MGT_CTRL (EMIF4_BASE + 0x38) +#define EMIF4_PWR_MGT_CTRL_SHDW (EMIF4_BASE + 0x3C) +#define EMIF4_IODFT_TLGC (EMIF4_BASE + 0x60) +#define EMIF4_DDR_PHYCTL1 (EMIF4_BASE + 0xE4) +#define EMIF4_DDR_PHYCTL1_SHDW (EMIF4_BASE + 0xE8) +#define EMIF4_DDR_PHYCTL2 (EMIF4_BASE + 0xEC) + + +/* timer regs offsets (32 bit regs) */ +#define TIDR 0x0 /* r */ +#define TIOCP_CFG 0x10 /* rw */ +#define TISTAT 0x14 /* r */ +#define TISR 0x18 /* rw */ +#define TIER 0x1C /* rw */ +#define TWER 0x20 /* rw */ +#define TCLR 0x24 /* rw */ +#define TCRR 0x28 /* rw */ +#define TLDR 0x2C /* rw */ +#define TTGR 0x30 /* rw */ +#define TWPS 0x34 /* r */ +#define TMAR 0x38 /* rw */ +#define TCAR1 0x3c /* r */ +#define TSICR 0x40 /* rw */ +#define TCAR2 0x44 /* r */ +#define GPT_EN ((0<<2)|BIT1|BIT0) /* enable sys_clk NO-prescale /1 */ + +/* Watchdog */ +#define WWPS 0x34 /* r */ +#define WSPR 0x48 /* rw */ +#define WD_UNLOCK1 0xAAAA +#define WD_UNLOCK2 0x5555 + +/* PRCM */ +#define CM_FCLKEN_IVA2 0x48004000 +#define CM_CLKEN_PLL_IVA2 0x48004004 +#define CM_IDLEST_PLL_IVA2 0x48004024 +#define CM_CLKSEL1_PLL_IVA2 0x48004040 +#define CM_CLKSEL2_PLL_IVA2 0x48004044 +#define CM_CLKEN_PLL_MPU 0x48004904 +#define CM_IDLEST_PLL_MPU 0x48004924 +#define CM_CLKSEL1_PLL_MPU 0x48004940 +#define CM_CLKSEL2_PLL_MPU 0x48004944 +#define CM_FCLKEN1_CORE 0x48004a00 +#define CM_ICLKEN1_CORE 0x48004a10 +#define CM_ICLKEN2_CORE 0x48004a14 +#define CM_CLKSEL_CORE 0x48004a40 +#define CM_FCLKEN_GFX 0x48004b00 +#define CM_ICLKEN_GFX 0x48004b10 +#define CM_CLKSEL_GFX 0x48004b40 +#define CM_FCLKEN_WKUP 0x48004c00 +#define CM_ICLKEN_WKUP 0x48004c10 +#define CM_CLKSEL_WKUP 0x48004c40 +#define CM_IDLEST_WKUP 0x48004c20 +#define CM_CLKEN_PLL 0x48004d00 +#define CM_IDLEST_CKGEN 0x48004d20 +#define CM_CLKSEL1_PLL 0x48004d40 +#define CM_CLKSEL2_PLL 0x48004d44 +#define CM_CLKSEL3_PLL 0x48004d48 +#define CM_FCLKEN_DSS 0x48004e00 +#define CM_ICLKEN_DSS 0x48004e10 +#define CM_CLKSEL_DSS 0x48004e40 +#define CM_FCLKEN_CAM 0x48004f00 +#define CM_ICLKEN_CAM 0x48004f10 +#define CM_CLKSEL_CAM 0x48004F40 +#define CM_FCLKEN_PER 0x48005000 +#define CM_ICLKEN_PER 0x48005010 +#define CM_CLKSEL_PER 0x48005040 +#define CM_CLKSEL1_EMU 0x48005140 + +/* SMX-APE */ +#define PM_RT_APE_BASE_ADDR_ARM (SMX_APE_BASE + 0x10000) +#define PM_GPMC_BASE_ADDR_ARM (SMX_APE_BASE + 0x12400) +#define PM_OCM_RAM_BASE_ADDR_ARM (SMX_APE_BASE + 0x12800) +#define PM_OCM_ROM_BASE_ADDR_ARM (SMX_APE_BASE + 0x12C00) +#define PM_IVA2_BASE_ADDR_ARM (SMX_APE_BASE + 0x14000) + +#define RT_REQ_INFO_PERMISSION_1 (PM_RT_APE_BASE_ADDR_ARM + 0x68) +#define RT_READ_PERMISSION_0 (PM_RT_APE_BASE_ADDR_ARM + 0x50) +#define RT_WRITE_PERMISSION_0 (PM_RT_APE_BASE_ADDR_ARM + 0x58) +#define RT_ADDR_MATCH_1 (PM_RT_APE_BASE_ADDR_ARM + 0x60) + +#define GPMC_REQ_INFO_PERMISSION_0 (PM_GPMC_BASE_ADDR_ARM + 0x48) +#define GPMC_READ_PERMISSION_0 (PM_GPMC_BASE_ADDR_ARM + 0x50) +#define GPMC_WRITE_PERMISSION_0 (PM_GPMC_BASE_ADDR_ARM + 0x58) + +#define OCM_REQ_INFO_PERMISSION_0 (PM_OCM_RAM_BASE_ADDR_ARM + 0x48) +#define OCM_READ_PERMISSION_0 (PM_OCM_RAM_BASE_ADDR_ARM + 0x50) +#define OCM_WRITE_PERMISSION_0 (PM_OCM_RAM_BASE_ADDR_ARM + 0x58) +#define OCM_ADDR_MATCH_2 (PM_OCM_RAM_BASE_ADDR_ARM + 0x80) + +#define IVA2_REQ_INFO_PERMISSION_0 (PM_IVA2_BASE_ADDR_ARM + 0x48) +#define IVA2_READ_PERMISSION_0 (PM_IVA2_BASE_ADDR_ARM + 0x50) +#define IVA2_WRITE_PERMISSION_0 (PM_IVA2_BASE_ADDR_ARM + 0x58) + +#define IVA2_REQ_INFO_PERMISSION_1 (PM_IVA2_BASE_ADDR_ARM + 0x68) +#define IVA2_READ_PERMISSION_1 (PM_IVA2_BASE_ADDR_ARM + 0x70) +#define IVA2_WRITE_PERMISSION_1 (PM_IVA2_BASE_ADDR_ARM + 0x78) + +#define IVA2_REQ_INFO_PERMISSION_2 (PM_IVA2_BASE_ADDR_ARM + 0x88) +#define IVA2_READ_PERMISSION_2 (PM_IVA2_BASE_ADDR_ARM + 0x90) +#define IVA2_WRITE_PERMISSION_2 (PM_IVA2_BASE_ADDR_ARM + 0x98) + +#define IVA2_REQ_INFO_PERMISSION_3 (PM_IVA2_BASE_ADDR_ARM + 0xA8) +#define IVA2_READ_PERMISSION_3 (PM_IVA2_BASE_ADDR_ARM + 0xB0) +#define IVA2_WRITE_PERMISSION_3 (PM_IVA2_BASE_ADDR_ARM + 0xB8) + +/* I2C base */ +#define I2C_BASE1 (OMAP34XX_CORE_L4_IO_BASE + 0x70000) +#define I2C_BASE2 (OMAP34XX_CORE_L4_IO_BASE + 0x72000) +#define I2C_BASE3 (OMAP34XX_CORE_L4_IO_BASE + 0x60000) + +#endif
diff --git a/x-loader/include/asm/arch-omap3/gpmc.h b/x-loader/include/asm/arch-omap3/gpmc.h new file mode 100644 index 0000000..32b11d9 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/gpmc.h
@@ -0,0 +1,142 @@ +/* + * Copyright (c) 2010 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines register and register field constants and + * macros for the Texas Instruments Open Multimedia Application + * Platform (OMAP) 3 General Purpose Memory Controller (GPMC). + */ + +#ifndef _OMAP3_GPMC_H +#define _OMAP3_GPMC_H + +#include <asm/arch/bits.h> + +/* + * GPMC Interconnect Configuration + */ +#define GPMC_SYSCONFIG_AUTOIDLE_DISABLE ARM_REG_VAL(0, 0) +#define GPMC_SYSCONFIG_AUTOIDLE_ENABLE ARM_REG_VAL(0, 1) +#define GPMC_SYSCONFIG_SOFTRESET ARM_REG_VAL(1, 1) +#define GPMC_SYSCONFIG_IDLEMODE_FORCE ARM_REG_VAL(3, 0) +#define GPMC_SYSCONFIG_IDLEMODE_NONE ARM_REG_VAL(3, 1) +#define GPMC_SYSCONFIG_IDLEMODE_SMART ARM_REG_VAL(3, 2) + +#define GPMC_SYSCONFIG_IRQENABLE_FIFOEVENT_DISABLE ARM_REG_VAL(0, 0) +#define GPMC_SYSCONFIG_IRQENABLE_FIFOEVENT_ENABLE ARM_REG_VAL(0, 1) + +#define GPMC_SYSCONFIG_IRQENABLE_TERMINALCOUNT_DISABLE ARM_REG_VAL(0, 0) +#define GPMC_SYSCONFIG_IRQENABLE_TERMINALCOUNT_ENABLE ARM_REG_VAL(0, 1) + +#define GPMC_SYSCONFIG_IRQENABLE_TERMINALCOUNT_DISABLE ARM_REG_VAL(0, 0) +#define GPMC_SYSCONFIG_IRQENABLE_TERMINALCOUNT_ENABLE ARM_REG_VAL(0, 1) + +/* + * GPMC Interrupt Control + */ + +#define GPMC_IRQENABLE_WAIT3EDGEDETECTION_DISABLE ARM_REG_VAL(11, 0) +#define GPMC_IRQENABLE_WAIT3EDGEDETECTION_ENABLE ARM_REG_VAL(11, 1) + +#define GPMC_IRQENABLE_WAIT2EDGEDETECTION_DISABLE ARM_REG_VAL(10, 0) +#define GPMC_IRQENABLE_WAIT2EDGEDETECTION_ENABLE ARM_REG_VAL(10, 1) + +#define GPMC_IRQENABLE_WAIT1EDGEDETECTION_DISABLE ARM_REG_VAL(9, 0) +#define GPMC_IRQENABLE_WAIT1EDGEDETECTION_ENABLE ARM_REG_VAL(9, 1) + +#define GPMC_IRQENABLE_WAIT0EDGEDETECTION_DISABLE ARM_REG_VAL(8, 0) +#define GPMC_IRQENABLE_WAIT0EDGEDETECTION_ENABLE ARM_REG_VAL(8, 1) + +#define GPMC_IRQENABLE_TERMINALCOUNTEVENT_DISABLE ARM_REG_VAL(1, 0) +#define GPMC_IRQENABLE_TERMINALCOUNTEVENT_ENABLE ARM_REG_VAL(1, 1) + +#define GPMC_IRQENABLE_FIFOEVENTENABLE_DISABLE ARM_REG_VAL(0, 0) +#define GPMC_IRQENABLE_FIFOEVENTENABLE_ENABLE ARM_REG_VAL(0, 0) + +#define GPMC_IRQENABLE_ALL_DISABLE \ + (GPMC_IRQENABLE_WAIT3EDGEDETECTION_DISABLE | \ + GPMC_IRQENABLE_WAIT2EDGEDETECTION_DISABLE | \ + GPMC_IRQENABLE_WAIT1EDGEDETECTION_DISABLE | \ + GPMC_IRQENABLE_WAIT0EDGEDETECTION_DISABLE | \ + GPMC_IRQENABLE_TERMINALCOUNTEVENT_DISABLE | \ + GPMC_IRQENABLE_FIFOEVENTENABLE_DISABLE) + +#define GPMC_IRQENABLE_ALL_ENABLE \ + (GPMC_IRQENABLE_WAIT3EDGEDETECTION_ENABLE | \ + GPMC_IRQENABLE_WAIT2EDGEDETECTION_ENABLE | \ + GPMC_IRQENABLE_WAIT1EDGEDETECTION_ENABLE | \ + GPMC_IRQENABLE_WAIT0EDGEDETECTION_ENABLE | \ + GPMC_IRQENABLE_TERMINALCOUNTEVENT_ENABLE | \ + GPMC_IRQENABLE_FIFOEVENTENABLE_ENABLE) + +/* + * GPMC Timeout Counter Control + */ + +#define GPMC_TIMEOUTSTARTVALUE_MASK ARM_REG_VAL(4, 0x1FF) +#define GPMC_TIMEOUTSTARTVALUE_ENCODE(v) ARM_REG_VAL_ENCODE(4, GPMC_TIMEOUTSTARTVALUE_MASK, v) +#define GPMC_TIMEOUTSTARTVALUE_DECODE(v) ARM_REG_VAL_DECODE(4, GPMC_TIMEOUTSTARTVALUE_MASK, v) + +#define GPMC_TIMEOUTENABLE_OFF ARM_REG_VAL(0, 0) +#define GPMC_TIMEOUTENABLE_ON ARM_REG_VAL(0, 1) + +/* + * GPMC Global Configuration + */ +#define GPMC_WAIT3PINPOLARITY_ACTIVE_LOW ARM_REG_VAL(11, 0) +#define GPMC_WAIT3PINPOLARITY_ACTIVE_HIGH ARM_REG_VAL(11, 1) + +#define GPMC_WAIT2PINPOLARITY_ACTIVE_LOW ARM_REG_VAL(10, 0) +#define GPMC_WAIT2PINPOLARITY_ACTIVE_HIGH ARM_REG_VAL(10, 1) + +#define GPMC_WAIT1PINPOLARITY_ACTIVE_LOW ARM_REG_VAL(9, 0) +#define GPMC_WAIT1PINPOLARITY_ACTIVE_HIGH ARM_REG_VAL(9, 1) + +#define GPMC_WAIT0PINPOLARITY_ACTIVE_LOW ARM_REG_VAL(8, 0) +#define GPMC_WAIT0PINPOLARITY_ACTIVE_HIGH ARM_REG_VAL(8, 1) + +#define GPMC_WRITEPROTECT_LOW ARM_REG_VAL(4, 0) +#define GPMC_WRITEPROTECT_HIGH ARM_REG_VAL(4, 1) + +#define GPMC_LIMITEDADDRESS_DISABLED ARM_REG_VAL(1, 0) +#define GPMC_LIMITEDADDRESS_ENABLED ARM_REG_VAL(1, 1) + +#define GPMC_NANDFORCEPOSTEDWRITE_DISABLED ARM_REG_VAL(0, 0) +#define GPMC_NANDFORCEPOSTEDWRITE_ENABLED ARM_REG_VAL(0, 1) + +#define GPMC_CONFIG7_MASKADDRESS_MASK ARM_REG_VAL(8, 0xF) +#define GPMC_CONFIG7_MASKADDRESS_ENCODE(v) ARM_REG_VAL_ENCODE(8, GPMC_CONFIG7_MASKADDRESS_MASK, v) +#define GPMC_CONFIG7_MASKADDRESS_DECODE(v) ARM_REG_VAL_DECODE(8, GPMC_CONFIG7_MASKADDRESS_MASK, v) +#define GPMC_CONFIG7_MASKADDRESS_256_MB 0x0 +#define GPMC_CONFIG7_MASKADDRESS_128_MB 0x8 +#define GPMC_CONFIG7_MASKADDRESS_64_MB 0xC +#define GPMC_CONFIG7_MASKADDRESS_32_MB 0xE +#define GPMC_CONFIG7_MASKADDRESS_16_MB 0xF + +#define GPMC_CONFIG7_CSVALID_DISABLED ARM_REG_VAL(6, 0) +#define GPMC_CONFIG7_CSVALID_ENABLED ARM_REG_VAL(6, 1) + +#define GPMC_CONFIG7_BASEADDRESS_MASK ARM_REG_VAL(0, 0x3F) +#define GPMC_CONFIG7_BASEADDRESS_ENCODE(v) ARM_REG_VAL_ENCODE(0, GPMC_CONFIG7_BASEADDRESS_MASK, ((v) >> 24)) +#define GPMC_CONFIG7_BASEADDRESS_DECODE(v) (ARM_REG_VAL_DECODE(0, GPMC_CONFIG7_BASEADDRESS_MASK, v) << 24) + + +#endif /* _OMAP3_GPMC_H */
diff --git a/x-loader/include/asm/arch-omap3/i2c.h b/x-loader/include/asm/arch-omap3/i2c.h new file mode 100755 index 0000000..afcda5e --- /dev/null +++ b/x-loader/include/asm/arch-omap3/i2c.h
@@ -0,0 +1,131 @@ +/* + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP34XX_I2C_H_ +#define _OMAP34XX_I2C_H_ + +/* Get the i2c base addresses */ +#include <asm/arch/cpu.h> + +#define I2C_DEFAULT_BASE I2C_BASE1 + +#define I2C_REV (0x00) +#define I2C_IE (0x04) +#define I2C_STAT (0x08) +#define I2C_IV (0x0c) +#define I2C_BUF (0x14) +#define I2C_CNT (0x18) +#define I2C_DATA (0x1c) +#define I2C_SYSC (0x20) +#define I2C_CON (0x24) +#define I2C_OA (0x28) +#define I2C_SA (0x2c) +#define I2C_PSC (0x30) +#define I2C_SCLL (0x34) +#define I2C_SCLH (0x38) +#define I2C_SYSTEST (0x3c) + +/* I2C masks */ + +/* I2C Interrupt Enable Register (I2C_IE): */ +#define I2C_IE_GC_IE (1 << 5) +#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */ +#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */ +#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */ +#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */ + +/* I2C Status Register (I2C_STAT): */ + +#define I2C_STAT_SBD (1 << 15) /* Single byte data */ +#define I2C_STAT_BB (1 << 12) /* Bus busy */ +#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */ +#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */ +#define I2C_STAT_AAS (1 << 9) /* Address as slave */ +#define I2C_STAT_GC (1 << 5) +#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */ +#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */ +#define I2C_STAT_ARDY (1 << 2) /* Register access ready */ +#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */ + + +/* I2C Interrupt Code Register (I2C_INTCODE): */ + +#define I2C_INTCODE_MASK 7 +#define I2C_INTCODE_NONE 0 +#define I2C_INTCODE_AL 1 /* Arbitration lost */ +#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */ +#define I2C_INTCODE_ARDY 3 /* Register access ready */ +#define I2C_INTCODE_RRDY 4 /* Rcv data ready */ +#define I2C_INTCODE_XRDY 5 /* Xmit data ready */ + +/* I2C Buffer Configuration Register (I2C_BUF): */ + +#define I2C_BUF_RDMA_EN (1 << 15) /* Receive DMA channel enable */ +#define I2C_BUF_XDMA_EN (1 << 7) /* Transmit DMA channel enable */ + +/* I2C Configuration Register (I2C_CON): */ + +#define I2C_CON_EN (1 << 15) /* I2C module enable */ +#define I2C_CON_BE (1 << 14) /* Big endian mode */ +#define I2C_CON_STB (1 << 11) /* Start byte mode (master mode only) */ +#define I2C_CON_MST (1 << 10) /* Master/slave mode */ +#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */ +#define I2C_CON_XA (1 << 8) /* Expand address */ +#define I2C_CON_STP (1 << 1) /* Stop condition (master mode only) */ +#define I2C_CON_STT (1 << 0) /* Start condition (master mode only) */ + +/* I2C System Test Register (I2C_SYSTEST): */ + +#define I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */ +#define I2C_SYSTEST_FREE (1 << 14) /* Free running mode (on breakpoint) */ +#define I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */ +#define I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */ +#define I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense input value */ +#define I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive output value */ +#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */ +#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */ + +#define I2C_SCLL_SCLL (0) +#define I2C_SCLL_SCLL_M (0xFF) +#define I2C_SCLL_HSSCLL (8) +#define I2C_SCLH_HSSCLL_M (0xFF) +#define I2C_SCLH_SCLH (0) +#define I2C_SCLH_SCLH_M (0xFF) +#define I2C_SCLH_HSSCLH (8) +#define I2C_SCLH_HSSCLH_M (0xFF) + +#define OMAP_I2C_STANDARD 100 +#define OMAP_I2C_FAST_MODE 400 +#define OMAP_I2C_HIGH_SPEED 3400 + +#define SYSTEM_CLOCK_12 12000 +#define SYSTEM_CLOCK_13 13000 +#define SYSTEM_CLOCK_192 19200 +#define SYSTEM_CLOCK_96 96000 + +#define I2C_IP_CLK SYSTEM_CLOCK_96 +#define I2C_PSC_MAX (0x0f) +#define I2C_PSC_MIN (0x00) + +#endif
diff --git a/x-loader/include/asm/arch-omap3/mem.h b/x-loader/include/asm/arch-omap3/mem.h new file mode 100644 index 0000000..c40bce5 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/mem.h
@@ -0,0 +1,586 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP34XX_MEM_H_ +#define _OMAP34XX_MEM_H_ + +#define SDRC_CS0_OSET 0x0 +#define SDRC_CS1_OSET 0x30 /* mirror CS1 regs appear offset 0x30 from CS0 */ + +#ifndef __ASSEMBLY__ + +typedef enum { + STACKED = 0, + IP_DDR = 1, + COMBO_DDR = 2, + IP_SDR = 3, +} mem_t; + + +/* Memory that can be connected to GPMC */ +#define GPMC_NOR 0 +#define GPMC_NAND 1 +#define GPMC_MDOC 2 +#define GPMC_ONENAND 3 +#define MMC_NAND 4 +#define MMC_ONENAND 5 +#define USB_PERIPHERAL 6 + +#endif + +/* set the 343x-SDRC incoming address convention */ +#if defined(SDRC_B_R_C) +#define B_ALL (0 << 6) /* bank-row-column */ +#elif defined(SDRC_B1_R_B0_C) +#define B_ALL (1 << 6) /* bank1-row-bank0-column */ +#elif defined(SDRC_R_B_C) +#define B_ALL (2 << 6) /* row-bank-column */ +#endif + +/* Future memory combinations based on past */ +#define SDP_SDRC_MDCFG_MONO_DDR 0x0 +#define SDP_COMBO_MDCFG_0_DDR 0x0 +#define SDP_SDRC_MDCFG_0_SDR 0x0 + +/* Slower full frequency range default timings for x32 operation*/ +#define SDP_SDRC_SHARING 0x00000100 +#define SDP_SDRC_MR_0_SDR 0x00000031 + +#ifdef CONFIG_3430ZEBU +#define SDP_SDRC_MDCFG_0_DDR (0x02582019|B_ALL) /* Infin ddr module */ +#else +#define SDP_SDRC_MDCFG_0_DDR (0x02584019|B_ALL) /* Infin ddr module */ +#endif + +#define SDP_SDRC_MR_0_DDR 0x00000032 + +/* Diabling power down mode using CKE pin */ +#define SDP_SDRC_POWER_POP 0x00000081 + +/* optimized timings good for current shipping parts */ +#define SDP_3430_SDRC_RFR_CTRL_100MHz 0x0002da01 +#define SDP_3430_SDRC_RFR_CTRL_133MHz 0x0003de01 /* 7.8us/7.5ns - 50=0x3de */ +#define SDP_3430_SDRC_RFR_CTRL_165MHz 0x0004e201 /* 7.8us/6ns - 50=0x4e2 */ + +#define DLL_OFFSET 0 +#define DLL_WRITEDDRCLKX2DIS 1 +#define DLL_ENADLL 1 +#define DLL_LOCKDLL 0 +#define DLL_DLLPHASE_72 0 +#define DLL_DLLPHASE_90 1 + +// rkw - need to find of 90/72 degree recommendation for speed like before. +#define SDP_SDRC_DLLAB_CTRL ((DLL_ENADLL << 3) | \ + (DLL_LOCKDLL << 2) | (DLL_DLLPHASE_90 << 1)) + +/* Infineon part of 3430SDP (133MHz optimized) ~ 7.5ns + * TDAL = Twr/Tck + Trp/tck = 15/7.5 + 22.5/7.5 = 2 + 3 = 5 + * TDPL = 15/7.5 = 2 + * TRRD = 15/2.5 = 2 + * TRCD = 22.5/7.5 = 3 + * TRP = 22.5/7.5 = 3 + * TRAS = 45/7.5 = 6 + * TRC = 65/7.5 = 8.6->9 + * TRFC = 75/7.5 = 10 + * ACTIMB + * TCKE = 2 + * XSR = 120/7.5 = 16 + */ +#define INFINEON_TDAL_133 5 +#define INFINEON_TDPL_133 2 +#define INFINEON_TRRD_133 2 +#define INFINEON_TRCD_133 3 +#define INFINEON_TRP_133 3 +#define INFINEON_TRAS_133 6 +#define INFINEON_TRC_133 9 +#define INFINEON_TRFC_133 10 +#define INFINEON_V_ACTIMA_133 ((INFINEON_TRFC_133 << 27) | (INFINEON_TRC_133 << 22) | (INFINEON_TRAS_133 << 18) \ + |(INFINEON_TRP_133 << 15) | (INFINEON_TRCD_133 << 12) |(INFINEON_TRRD_133 << 9) |(INFINEON_TDPL_133 << 6) \ + | (INFINEON_TDAL_133)) + +#define INFINEON_TWTR_133 1 +#define INFINEON_TCKE_133 2 +#define INFINEON_TXP_133 2 +#define INFINEON_XSR_133 16 +#define INFINEON_V_ACTIMB_133 ((INFINEON_TCKE_133 << 12) | (INFINEON_XSR_133 << 0)) | \ + (INFINEON_TXP_133 << 8) | (INFINEON_TWTR_133 << 16) + +#define INFINEON_V_ACTIMA_100 INFINEON_V_ACTIMA_133 +#define INFINEON_V_ACTIMB_100 INFINEON_V_ACTIMB_133 + + +/* Infineon part of 3430SDP (165MHz optimized) 6.06ns + * ACTIMA + * TDAL = Twr/Tck + Trp/tck = 15/6 + 18/6 = 2.5 + 3 = 5.5 -> 6 + * TDPL (Twr) = 15/6 = 2.5 -> 3 + * TRRD = 12/6 = 2 + * TRCD = 18/6 = 3 + * TRP = 18/6 = 3 + * TRAS = 42/6 = 7 + * TRC = 60/6 = 10 + * TRFC = 72/6 = 12 + * ACTIMB + * TCKE = 2 + * XSR = 120/6 = 20 + */ +#define INFINEON_TDAL_165 6 +#define INFINEON_TDPL_165 3 +#define INFINEON_TRRD_165 2 +#define INFINEON_TRCD_165 3 +#define INFINEON_TRP_165 3 +#define INFINEON_TRAS_165 7 +#define INFINEON_TRC_165 10 +#define INFINEON_TRFC_165 12 +#define INFINEON_V_ACTIMA_165 ((INFINEON_TRFC_165 << 27) | (INFINEON_TRC_165 << 22) | (INFINEON_TRAS_165 << 18) \ + | (INFINEON_TRP_165 << 15) | (INFINEON_TRCD_165 << 12) |(INFINEON_TRRD_165 << 9) | \ + (INFINEON_TDPL_165 << 6) | (INFINEON_TDAL_165)) + +#define INFINEON_TWTR_165 1 +#define INFINEON_TCKE_165 2 +#define INFINEON_TXP_165 2 +#define INFINEON_XSR_165 20 +#define INFINEON_V_ACTIMB_165 ((INFINEON_TCKE_165 << 12) | (INFINEON_XSR_165 << 0)) | \ + (INFINEON_TXP_165 << 8) | (INFINEON_TWTR_165 << 16) + +/* Micron part of 3430 EVM (133MHz optimized) ~ 7.5ns + * TDAL = Twr/Tck + Trp/tck = 15/7.5 + 22.5/7.5 = 2 + 3 = 5 + * TDPL = 15/7.5 = 2 + * TRRD = 15/7.5 = 2 + * TRCD = 22.5/7.5 = 3 + * TRP = 22.5/7.5 = 3 + * TRAS = 45/7.5 = 6 + * TRC = 75/7.5 = 10 + * TRFC = 125/7.5 = 16.6->17 + * ACTIMB + * TWTR = 1 + * TCKE = 1 + * TXSR = 138/7.5 = 18.3->19 + * TXP = 25/7.5 = 3.3->4 + */ +#define MICRON_TDAL_133 5 +#define MICRON_TDPL_133 2 +#define MICRON_TRRD_133 2 +#define MICRON_TRCD_133 3 +#define MICRON_TRP_133 3 +#define MICRON_TRAS_133 6 +#define MICRON_TRC_133 10 +#define MICRON_TRFC_133 17 +#define MICRON_V_ACTIMA_133 ((MICRON_TRFC_133 << 27) | (MICRON_TRC_133 << 22) | (MICRON_TRAS_133 << 18) \ + |(MICRON_TRP_133 << 15) | (MICRON_TRCD_133 << 12) |(MICRON_TRRD_133 << 9) |(MICRON_TDPL_133 << 6) \ + | (MICRON_TDAL_133)) + +#define MICRON_TWTR_133 1 +#define MICRON_TCKE_133 1 +#define MICRON_TXSR_133 19 +#define MICRON_TXP_133 4 +#define MICRON_V_ACTIMB_133 ((MICRON_TWTR_133 << 16) | (MICRON_TCKE_133 << 12) | (MICRON_TXP_133 << 8) \ + | (MICRON_TXSR_133 << 0)) + +#define MICRON_V_ACTIMA_100 MICRON_V_ACTIMA_133 +#define MICRON_V_ACTIMB_100 MICRON_V_ACTIMB_133 + +/* Micron part of 3430 EVM (165MHz optimized) 6.06ns + * ACTIMA + * TDAL = Twr/Tck + Trp/tck = 15/6 + 18 /6 = 2.5 + 3 = 5.5 -> 6 + * TDPL (Twr) = 15/6 = 2.5 -> 3 + * TRRD = 12/6 = 2 + * TRCD = 18/6 = 3 + * TRP = 18/6 = 3 + * TRAS = 42/6 = 7 + * TRC = 60/6 = 10 + * TRFC = 125/6 = 21 + * ACTIMB + * TWTR = 1 + * TCKE = 1 + * TXSR = 138/6 = 23 + * TXP = 25/6 = 4.1 ~5 + */ +#define MICRON_TDAL_165 6 +#define MICRON_TDPL_165 3 +#define MICRON_TRRD_165 2 +#define MICRON_TRCD_165 3 +#define MICRON_TRP_165 3 +#define MICRON_TRAS_165 7 +#define MICRON_TRC_165 10 +#define MICRON_TRFC_165 21 +#define MICRON_V_ACTIMA_165 ((MICRON_TRFC_165 << 27) | (MICRON_TRC_165 << 22) | (MICRON_TRAS_165 << 18) \ + | (MICRON_TRP_165 << 15) | (MICRON_TRCD_165 << 12) |(MICRON_TRRD_165 << 9) | \ + (MICRON_TDPL_165 << 6) | (MICRON_TDAL_165)) + +#define MICRON_TWTR_165 1 +#define MICRON_TCKE_165 1 +#define MICRON_TXP_165 5 +#define MICRON_XSR_165 23 +#define MICRON_V_ACTIMB_165 ((MICRON_TCKE_165 << 12) | (MICRON_XSR_165 << 0)) | \ + (MICRON_TXP_165 << 8) | (MICRON_TWTR_165 << 16) + + + +/* Hynix part of AM/DM37xEVM (200MHz optimized) + * ACTIMA + * TDAL = 6 + * TDPL (Twr) = 3 + * TRRD = 2 + * TRCD = 4 + * TRP = 3 + * TRAS = 8 + * TRC = 11 + * TRFC = 18 + * ACTIMB + * TWTR = 2 + * TCKE = 1 + * TXP = 1 + * TXSR = 28 + */ +#define HYNIX_TDAL_200 6 +#define HYNIX_TDPL_200 3 +#define HYNIX_TRRD_200 2 +#define HYNIX_TRCD_200 4 +#define HYNIX_TRP_200 3 +#define HYNIX_TRAS_200 8 +#define HYNIX_TRC_200 11 +#define HYNIX_TRFC_200 18 +#define HYNIX_V_ACTIMA_200 ((HYNIX_TRFC_200 << 27) | (HYNIX_TRC_200 << 22) | \ + (HYNIX_TRAS_200 << 18) | (HYNIX_TRP_200 << 15) | \ + (HYNIX_TRCD_200 << 12) | (HYNIX_TRRD_200 << 9) | \ + (HYNIX_TDPL_200 << 6) | (HYNIX_TDAL_200)) + +#define HYNIX_TWTR_200 2 +#define HYNIX_TCKE_200 1 +#define HYNIX_TXP_200 1 +#define HYNIX_XSR_200 28 +#define HYNIX_V_ACTIMB_200 (((HYNIX_TCKE_200 << 12) | (HYNIX_XSR_200 << 0)) | \ + (HYNIX_TXP_200 << 8) | (HYNIX_TWTR_200 << 16)) + +#define HYNIX_SDRC_ACTIM_CTRLA_0 HYNIX_V_ACTIMA_200 +#define HYNIX_SDRC_ACTIM_CTRLB_0 HYNIX_V_ACTIMB_200 + + + +/* New and compatability speed defines */ +#if defined(PRCM_CLK_CFG2_200MHZ) || defined(PRCM_CONFIG_II) || defined(PRCM_CONFIG_5B) +# define L3_100MHZ /* Use with <= 100MHz SDRAM */ +#elif defined (PRCM_CLK_CFG2_266MHZ) || defined(PRCM_CONFIG_III) || defined(PRCM_CONFIG_5A) +# define L3_133MHZ /* Use with <= 133MHz SDRAM*/ +#elif defined(PRCM_CLK_CFG2_332MHZ) || defined(PRCM_CONFIG_I) || defined(PRCM_CONFIG_2) +# define L3_165MHZ /* Use with <= 165MHz SDRAM (L3=166 on 3430) */ +#endif + +#if defined(L3_100MHZ) +# define MICRON_SDRC_ACTIM_CTRLA_0 MICRON_V_ACTIMA_100 +# define MICRON_SDRC_ACTIM_CTRLB_0 MICRON_V_ACTIMB_100 +#elif defined(L3_133MHZ) +# define MICRON_SDRC_ACTIM_CTRLA_0 MICRON_V_ACTIMA_133 +# define MICRON_SDRC_ACTIM_CTRLB_0 MICRON_V_ACTIMB_133 +#elif defined(L3_165MHZ) +# define MICRON_SDRC_ACTIM_CTRLA_0 MICRON_V_ACTIMA_165 +# define MICRON_SDRC_ACTIM_CTRLB_0 MICRON_V_ACTIMB_165 +#endif + + +#if defined(L3_100MHZ) +# define INFINEON_SDRC_ACTIM_CTRLA_0 INFINEON_V_ACTIMA_100 +# define INFINEON_SDRC_ACTIM_CTRLB_0 INFINEON_V_ACTIMB_100 +#elif defined(L3_133MHZ) +# define INFINEON_SDRC_ACTIM_CTRLA_0 INFINEON_V_ACTIMA_133 +# define INFINEON_SDRC_ACTIM_CTRLB_0 INFINEON_V_ACTIMB_133 +#elif defined(L3_165MHZ) +# define INFINEON_SDRC_ACTIM_CTRLA_0 INFINEON_V_ACTIMA_165 +# define INFINEON_SDRC_ACTIM_CTRLB_0 INFINEON_V_ACTIMB_165 +#endif + +#if defined(L3_100MHZ) +# define SDP_SDRC_RFR_CTRL SDP_3430_SDRC_RFR_CTRL_100MHz +#elif defined(L3_133MHZ) +# define SDP_SDRC_RFR_CTRL SDP_3430_SDRC_RFR_CTRL_133MHz +#elif defined(L3_165MHZ) +# define SDP_SDRC_RFR_CTRL SDP_3430_SDRC_RFR_CTRL_165MHz +#endif + +/* + * GPMC settings - + * Definitions is as per the following format + * # define <PART>_GPMC_CONFIG<x> <value> + * Where: + * PART is the part name e.g. STNOR - Intel Strata Flash + * x is GPMC config registers from 1 to 6 (there will be 6 macros) + * Value is corresponding value + * + * For every valid PRCM configuration there should be only one definition of + * the same. if values are independent of the board, this definition will be + * present in this file if values are dependent on the board, then this should + * go into corresponding mem-boardName.h file + * + * Currently valid part Names are (PART): + * STNOR - Intel Strata Flash + * SMNAND - Samsung NAND + * M_NAND - Micron Large page x16 NAND + * MPDB - H4 MPDB board + * SBNOR - Sibley NOR + * ONNAND - Samsung One NAND + * + * include/configs/file.h contains the defn - for all CS we are interested + * #define OMAP34XX_GPMC_CSx PART + * #define OMAP34XX_GPMC_CSx_SIZE Size + * #define OMAP34XX_GPMC_CSx_MAP Map + * Where: + * x - CS number + * PART - Part Name as defined above + * SIZE - how big is the mapping to be + * GPMC_SIZE_128M - 0x8 + * GPMC_SIZE_64M - 0xC + * GPMC_SIZE_32M - 0xE + * GPMC_SIZE_16M - 0xF + * MAP - Map this CS to which address(GPMC address space)- Absolute address + * >>24 before being used. + */ +#define GPMC_SIZE_128M 0x8 +#define GPMC_SIZE_64M 0xC +#define GPMC_SIZE_32M 0xE +#define GPMC_SIZE_16M 0xF + +#if defined(L3_100MHZ) +# define SMNAND_GPMC_CONFIG1 0x0 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x00000A80 + +#if defined (CONFIG_OMAP34XX) + +# define M_NAND_GPMC_CONFIG1 0x00001800 +# define M_NAND_GPMC_CONFIG2 0x00090900 +# define M_NAND_GPMC_CONFIG3 0x00090900 +# define M_NAND_GPMC_CONFIG4 0x07010702 +# define M_NAND_GPMC_CONFIG5 0x01050908 +# define M_NAND_GPMC_CONFIG6 0x1F0F0380 + +#elif defined (CONFIG_AM3517EVM) || defined (CONFIG_AM3517TEB) + +#ifdef NAND_16BIT +# define M_NAND_GPMC_CONFIG1 0x00001800 +#else +# define M_NAND_GPMC_CONFIG1 0x00000800 +#endif +# define M_NAND_GPMC_CONFIG2 0x00080800 +# define M_NAND_GPMC_CONFIG3 0x00080800 +# define M_NAND_GPMC_CONFIG4 0x06000600 +# define M_NAND_GPMC_CONFIG5 0x00070808 +# define M_NAND_GPMC_CONFIG6 0x000003cf +# define M_NAND_GPMC_CONFIG7 0x00000848 + +#endif + +# define STNOR_GPMC_CONFIG1 0x3 +# define STNOR_GPMC_CONFIG2 0x000f0f01 +# define STNOR_GPMC_CONFIG3 0x00050502 +# define STNOR_GPMC_CONFIG4 0x0C060C06 +# define STNOR_GPMC_CONFIG5 0x01131F1F +# define STNOR_GPMC_CONFIG6 0x0 /* 0? */ +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001F1F00 +# define MPDB_GPMC_CONFIG3 0x00080802 +# define MPDB_GPMC_CONFIG4 0x1C091C09 +# define MPDB_GPMC_CONFIG5 0x031A1F1F +# define MPDB_GPMC_CONFIG6 0x000003C2 +#endif + +#if defined(L3_133MHZ) +# define SMNAND_GPMC_CONFIG1 0x00000800 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x00000A80 +# define SMNAND_GPMC_CONFIG7 0x00000C44 + +#if defined (CONFIG_OMAP34XX) + +# define M_NAND_GPMC_CONFIG1 0x00001800 +# define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 +# define M_NAND_GPMC_CONFIG3 SMNAND_GPMC_CONFIG3 +# define M_NAND_GPMC_CONFIG4 SMNAND_GPMC_CONFIG4 +# define M_NAND_GPMC_CONFIG5 SMNAND_GPMC_CONFIG5 +# define M_NAND_GPMC_CONFIG6 SMNAND_GPMC_CONFIG6 +# define M_NAND_GPMC_CONFIG7 SMNAND_GPMC_CONFIG7 + +#elif defined (CONFIG_AM3517EVM) || defined (CONFIG_AM3517TEB) + +#ifdef NAND_16BIT +# define M_NAND_GPMC_CONFIG1 0x00001800 +#else +# define M_NAND_GPMC_CONFIG1 0x00000800 +#endif +# define M_NAND_GPMC_CONFIG2 0x00080800 +# define M_NAND_GPMC_CONFIG3 0x00080800 +# define M_NAND_GPMC_CONFIG4 0x06000600 +# define M_NAND_GPMC_CONFIG5 0x00070808 +# define M_NAND_GPMC_CONFIG6 0x000003cf +# define M_NAND_GPMC_CONFIG7 0x00000848 + +#endif + + +# define STNOR_GPMC_CONFIG1 0x1203 +# define STNOR_GPMC_CONFIG2 0x00151501 +# define STNOR_GPMC_CONFIG3 0x00060602 +# define STNOR_GPMC_CONFIG4 0x10081008 +# define STNOR_GPMC_CONFIG5 0x01131F1F +# define STNOR_GPMC_CONFIG6 0x000004c4 + +# define SIBNOR_GPMC_CONFIG1 0x1200 +# define SIBNOR_GPMC_CONFIG2 0x001f1f00 +# define SIBNOR_GPMC_CONFIG3 0x00080802 +# define SIBNOR_GPMC_CONFIG4 0x1C091C09 +# define SIBNOR_GPMC_CONFIG5 0x01131F1F +# define SIBNOR_GPMC_CONFIG6 0x000003C2 + +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001f1f01 +# define MPDB_GPMC_CONFIG3 0x00080803 +# define MPDB_GPMC_CONFIG4 0x1C091C09 +# define MPDB_GPMC_CONFIG5 0x041f1F1F +# define MPDB_GPMC_CONFIG6 0x000004C4 + +# define P2_GPMC_CONFIG1 0x0 +# define P2_GPMC_CONFIG2 0x0 +# define P2_GPMC_CONFIG3 0x0 +# define P2_GPMC_CONFIG4 0x0 +# define P2_GPMC_CONFIG5 0x0 +# define P2_GPMC_CONFIG6 0x0 + +# define ONENAND_GPMC_CONFIG1 0x00001200 +# define ONENAND_GPMC_CONFIG2 0x000c0c01 +# define ONENAND_GPMC_CONFIG3 0x00030301 +# define ONENAND_GPMC_CONFIG4 0x0c040c04 +# define ONENAND_GPMC_CONFIG5 0x010C1010 +# define ONENAND_GPMC_CONFIG6 0x00000000 + +#endif /* endif L3_133MHZ */ + +#if defined (L3_165MHZ) +# define SMNAND_GPMC_CONFIG1 0x00000800 +# define SMNAND_GPMC_CONFIG2 0x00141400 +# define SMNAND_GPMC_CONFIG3 0x00141400 +# define SMNAND_GPMC_CONFIG4 0x0F010F01 +# define SMNAND_GPMC_CONFIG5 0x010C1414 +# define SMNAND_GPMC_CONFIG6 0x1F0F0A80 +# define SMNAND_GPMC_CONFIG7 0x00000C44 + +#if defined (CONFIG_OMAP34XX) + +# define M_NAND_GPMC_CONFIG1 0x00001800 +# define M_NAND_GPMC_CONFIG2 SMNAND_GPMC_CONFIG2 +# define M_NAND_GPMC_CONFIG3 SMNAND_GPMC_CONFIG3 +# define M_NAND_GPMC_CONFIG4 SMNAND_GPMC_CONFIG4 +# define M_NAND_GPMC_CONFIG5 SMNAND_GPMC_CONFIG5 +# define M_NAND_GPMC_CONFIG6 SMNAND_GPMC_CONFIG6 +# define M_NAND_GPMC_CONFIG7 SMNAND_GPMC_CONFIG7 + +#elif defined (CONFIG_AM3517EVM) || defined (CONFIG_AM3517TEB) + +#ifdef NAND_16BIT +# define M_NAND_GPMC_CONFIG1 0x00001800 +#else +# define M_NAND_GPMC_CONFIG1 0x00000800 +#endif +# define M_NAND_GPMC_CONFIG2 0x00080800 +# define M_NAND_GPMC_CONFIG3 0x00080800 +# define M_NAND_GPMC_CONFIG4 0x06000600 +# define M_NAND_GPMC_CONFIG5 0x00070808 +# define M_NAND_GPMC_CONFIG6 0x000003cf +# define M_NAND_GPMC_CONFIG7 0x00000848 + +#endif + + +# define STNOR_GPMC_CONFIG1 0x3 +# define STNOR_GPMC_CONFIG2 0x00151501 +# define STNOR_GPMC_CONFIG3 0x00060602 +# define STNOR_GPMC_CONFIG4 0x11091109 +# define STNOR_GPMC_CONFIG5 0x01141F1F +# define STNOR_GPMC_CONFIG6 0x000004c4 + +# define SIBNOR_GPMC_CONFIG1 0x1200 +# define SIBNOR_GPMC_CONFIG2 0x001f1f00 +# define SIBNOR_GPMC_CONFIG3 0x00080802 +# define SIBNOR_GPMC_CONFIG4 0x1C091C09 +# define SIBNOR_GPMC_CONFIG5 0x01131F1F +# define SIBNOR_GPMC_CONFIG6 0x1F0F03C2 + +# define SDPV2_MPDB_GPMC_CONFIG1 0x00611200 +# define SDPV2_MPDB_GPMC_CONFIG2 0x001F1F01 +# define SDPV2_MPDB_GPMC_CONFIG3 0x00080803 +# define SDPV2_MPDB_GPMC_CONFIG4 0x1D091D09 +# define SDPV2_MPDB_GPMC_CONFIG5 0x041D1F1F +# define SDPV2_MPDB_GPMC_CONFIG6 0x1D0904C4 + +# define MPDB_GPMC_CONFIG1 0x00011000 +# define MPDB_GPMC_CONFIG2 0x001f1f01 +# define MPDB_GPMC_CONFIG3 0x00080803 +# define MPDB_GPMC_CONFIG4 0x1c0b1c0a +# define MPDB_GPMC_CONFIG5 0x041f1F1F +# define MPDB_GPMC_CONFIG6 0x1F0F04C4 + +# define P2_GPMC_CONFIG1 0x0 +# define P2_GPMC_CONFIG2 0x0 +# define P2_GPMC_CONFIG3 0x0 +# define P2_GPMC_CONFIG4 0x0 +# define P2_GPMC_CONFIG5 0x0 +# define P2_GPMC_CONFIG6 0x0 + +# define ONENAND_GPMC_CONFIG1 0x00001200 +# define ONENAND_GPMC_CONFIG2 0x000F0F01 +# define ONENAND_GPMC_CONFIG3 0x00030301 +# define ONENAND_GPMC_CONFIG4 0x0F040F04 +# define ONENAND_GPMC_CONFIG5 0x010F1010 +# define ONENAND_GPMC_CONFIG6 0x1F060000 + +#endif + +/* max number of GPMC Chip Selects */ +#define GPMC_MAX_CS 8 +/* max number of GPMC regs */ +#define GPMC_MAX_REG 7 + +#define PISMO1_NOR 1 +#define PISMO1_NAND 2 +#define PISMO2_CS0 3 +#define PISMO2_CS1 4 +#define PISMO1_ONENAND 5 +#define POP_ONENAND 5 +#define DBG_MPDB 6 +#define PISMO2_NAND_CS0 7 +#define PISMO2_NAND_CS1 8 + +/* make it readable for the gpmc_init */ +#define PISMO1_NOR_BASE FLASH_BASE +#define PISMO1_NAND_BASE NAND_BASE +#define PISMO2_CS0_BASE PISMO2_MAP1 +#define PISMO1_ONEN_BASE ONENAND_MAP +#define POP_ONEN_BASE ONENAND_MAP +#define DBG_MPDB_BASE DEBUG_BASE + +#endif /* endif _OMAP34XX_MEM_H_ */
diff --git a/x-loader/include/asm/arch-omap3/mmc.h b/x-loader/include/asm/arch-omap3/mmc.h new file mode 100755 index 0000000..7bceb5f --- /dev/null +++ b/x-loader/include/asm/arch-omap3/mmc.h
@@ -0,0 +1,187 @@ +/* + * linux/drivers/mmc/mmc_pxa.h + * + * Author: Vladimir Shebordaev, Igor Oblakov + * Copyright: MontaVista Software Inc. + * + * $Id: mmc_pxa.h,v 0.3.1.6 2002/09/25 19:25:48 ted Exp ted $ + * + * 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. + */ +#ifndef __MMC_PXA_P_H__ +#define __MMC_PXA_P_H__ + +/* PXA-250 MMC controller registers */ + +/* MMC_STRPCL */ +#define MMC_STRPCL_STOP_CLK (0x0001UL) +#define MMC_STRPCL_START_CLK (0x0002UL) + +/* MMC_STAT */ + +#define MMC_STAT_ERRORS (MMC_STAT_RES_CRC_ERROR | MMC_STAT_SPI_READ_ERROR_TOKEN\ + | MMC_STAT_CRC_READ_ERROR | MMC_STAT_TIME_OUT_RESPONSE \ + | MMC_STAT_READ_TIME_OUT | MMC_STAT_CRC_WRITE_ERROR) + +/* MMC_CLKRT */ +#define MMC_CLKRT_20MHZ (0x0000UL) +#define MMC_CLKRT_10MHZ (0x0001UL) +#define MMC_CLKRT_5MHZ (0x0002UL) +#define MMC_CLKRT_2_5MHZ (0x0003UL) +#define MMC_CLKRT_1_25MHZ (0x0004UL) +#define MMC_CLKRT_0_625MHZ (0x0005UL) +#define MMC_CLKRT_0_3125MHZ (0x0006UL) + +/* MMC_SPI */ +#define MMC_SPI_DISABLE (0x00UL) +#define MMC_SPI_EN (0x01UL) +#define MMC_SPI_CS_EN (0x01UL << 2) +#define MMC_SPI_CS_ADDRESS (0x01UL << 3) +#define MMC_SPI_CRC_ON (0x01UL << 1) + +/* MMC_CMDAT */ +#define MMC_CMDAT_MMC_DMA_EN (0x0001UL << 7) +#define MMC_CMDAT_INIT (0x0001UL << 6) +#define MMC_CMDAT_BUSY (0x0001UL << 5) +#define MMC_CMDAT_STREAM (0x0001UL << 4) +#define MMC_CMDAT_BLOCK (0x0000UL << 4) +#define MMC_CMDAT_WRITE (0x0001UL << 3) +#define MMC_CMDAT_READ (0x0000UL << 3) +#define MMC_CMDAT_DATA_EN (0x0001UL << 2) +#define MMC_CMDAT_R1 (0x0001UL) +#define MMC_CMDAT_R2 (0x0002UL) +#define MMC_CMDAT_R3 (0x0003UL) + +/* MMC_RESTO */ +#define MMC_RES_TO_MAX (0x007fUL) /* [6:0] */ + +/* MMC_RDTO */ +#define MMC_READ_TO_MAX (0x0ffffUL) /* [15:0] */ + +/* MMC_BLKLEN */ +#define MMC_BLK_LEN_MAX (0x03ffUL) /* [9:0] */ + +/* MMC_PRTBUF */ +#define MMC_PRTBUF_BUF_PART_FULL (0x01UL) +#define MMC_PRTBUF_BUF_FULL (0x00UL) + +/* MMC_I_MASK */ +#define MMC_I_MASK_TXFIFO_WR_REQ (0x01UL << 6) +#define MMC_I_MASK_RXFIFO_RD_REQ (0x01UL << 5) +#define MMC_I_MASK_CLK_IS_OFF (0x01UL << 4) +#define MMC_I_MASK_STOP_CMD (0x01UL << 3) +#define MMC_I_MASK_END_CMD_RES (0x01UL << 2) +#define MMC_I_MASK_PRG_DONE (0x01UL << 1) +#define MMC_I_MASK_DATA_TRAN_DONE (0x01UL) +#define MMC_I_MASK_ALL (0x07fUL) + + +/* MMC_I_REG */ +#define MMC_I_REG_TXFIFO_WR_REQ (0x01UL << 6) +#define MMC_I_REG_RXFIFO_RD_REQ (0x01UL << 5) +#define MMC_I_REG_CLK_IS_OFF (0x01UL << 4) +#define MMC_I_REG_STOP_CMD (0x01UL << 3) +#define MMC_I_REG_END_CMD_RES (0x01UL << 2) +#define MMC_I_REG_PRG_DONE (0x01UL << 1) +#define MMC_I_REG_DATA_TRAN_DONE (0x01UL) +#define MMC_I_REG_ALL (0x007fUL) + +/* MMC_CMD */ +#define MMC_CMD_INDEX_MAX (0x006fUL) /* [5:0] */ +#define CMD(x) (x) + +#define MMC_DEFAULT_RCA 1 + +#define MMC_BLOCK_SIZE 512 +#define MMC_CMD_RESET 0 +#define MMC_CMD_SEND_OP_COND 1 +#define MMC_CMD_ALL_SEND_CID 2 +#define MMC_CMD_SET_RCA 3 +#define MMC_CMD_SEND_CSD 9 +#define MMC_CMD_SEND_CID 10 +#define MMC_CMD_SEND_STATUS 13 +#define MMC_CMD_SET_BLOCKLEN 16 +#define MMC_CMD_READ_BLOCK 17 +#define MMC_CMD_RD_BLK_MULTI 18 +#define MMC_CMD_WRITE_BLOCK 24 + +#define MMC_MAX_BLOCK_SIZE 512 + +#define MMC_R1_IDLE_STATE 0x01 +#define MMC_R1_ERASE_STATE 0x02 +#define MMC_R1_ILLEGAL_CMD 0x04 +#define MMC_R1_COM_CRC_ERR 0x08 +#define MMC_R1_ERASE_SEQ_ERR 0x01 +#define MMC_R1_ADDR_ERR 0x02 +#define MMC_R1_PARAM_ERR 0x04 + +#define MMC_R1B_WP_ERASE_SKIP 0x0002 +#define MMC_R1B_ERR 0x0004 +#define MMC_R1B_CC_ERR 0x0008 +#define MMC_R1B_CARD_ECC_ERR 0x0010 +#define MMC_R1B_WP_VIOLATION 0x0020 +#define MMC_R1B_ERASE_PARAM 0x0040 +#define MMC_R1B_OOR 0x0080 +#define MMC_R1B_IDLE_STATE 0x0100 +#define MMC_R1B_ERASE_RESET 0x0200 +#define MMC_R1B_ILLEGAL_CMD 0x0400 +#define MMC_R1B_COM_CRC_ERR 0x0800 +#define MMC_R1B_ERASE_SEQ_ERR 0x1000 +#define MMC_R1B_ADDR_ERR 0x2000 +#define MMC_R1B_PARAM_ERR 0x4000 + +typedef struct mmc_cid { +/* FIXME: BYTE_ORDER */ + unsigned char year:4, + month:4; + unsigned char sn[3]; + unsigned char fwrev:4, + hwrev:4; + unsigned char name[6]; + unsigned char id[3]; +} mmc_cid_t; + +typedef struct mmc_csd +{ + unsigned char ecc:2, + file_format:2, + tmp_write_protect:1, + perm_write_protect:1, + copy:1, + file_format_grp:1; + unsigned long int content_prot_app:1, + rsvd3:4, + write_bl_partial:1, + write_bl_len:4, + r2w_factor:3, + default_ecc:2, + wp_grp_enable:1, + wp_grp_size:5, + erase_grp_mult:5, + erase_grp_size:5, + c_size_mult1:3, + vdd_w_curr_max:3, + vdd_w_curr_min:3, + vdd_r_curr_max:3, + vdd_r_curr_min:3, + c_size:12, + rsvd2:2, + dsr_imp:1, + read_blk_misalign:1, + write_blk_misalign:1, + read_bl_partial:1; + + unsigned short read_bl_len:4, + ccc:12; + unsigned char tran_speed; + unsigned char nsac; + unsigned char taac; + unsigned char rsvd1:2, + spec_vers:4, + csd_structure:2; +} mmc_csd_t; + + +#endif /* __MMC_PXA_P_H__ */
diff --git a/x-loader/include/asm/arch-omap3/mux.h b/x-loader/include/asm/arch-omap3/mux.h new file mode 100644 index 0000000..0c01c73 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/mux.h
@@ -0,0 +1,412 @@ +/* + * (C) Copyright 2006-2008 + * Texas Instruments, <www.ti.com> + * Syed Mohammed Khasim <x0khasim@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _MUX_H_ +#define _MUX_H_ + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + */ + +#define IEN (1 << 8) + +#define IDIS (0 << 8) +#define PTU (1 << 4) +#define PTD (0 << 4) +#define EN (1 << 3) +#define DIS (0 << 3) + +#define M0 0 +#define M1 1 +#define M2 2 +#define M3 3 +#define M4 4 +#define M5 5 +#define M6 6 +#define M7 7 + +/* + * To get the actual address the offset has to added + * with OMAP34XX_CTRL_BASE to get the actual address + */ + +/*SDRC*/ +#define CONTROL_PADCONF_SDRC_D0 0x0030 +#define CONTROL_PADCONF_SDRC_D1 0x0032 +#define CONTROL_PADCONF_SDRC_D2 0x0034 +#define CONTROL_PADCONF_SDRC_D3 0x0036 +#define CONTROL_PADCONF_SDRC_D4 0x0038 +#define CONTROL_PADCONF_SDRC_D5 0x003A +#define CONTROL_PADCONF_SDRC_D6 0x003C +#define CONTROL_PADCONF_SDRC_D7 0x003E +#define CONTROL_PADCONF_SDRC_D8 0x0040 +#define CONTROL_PADCONF_SDRC_D9 0x0042 +#define CONTROL_PADCONF_SDRC_D10 0x0044 +#define CONTROL_PADCONF_SDRC_D11 0x0046 +#define CONTROL_PADCONF_SDRC_D12 0x0048 +#define CONTROL_PADCONF_SDRC_D13 0x004A +#define CONTROL_PADCONF_SDRC_D14 0x004C +#define CONTROL_PADCONF_SDRC_D15 0x004E +#define CONTROL_PADCONF_SDRC_D16 0x0050 +#define CONTROL_PADCONF_SDRC_D17 0x0052 +#define CONTROL_PADCONF_SDRC_D18 0x0054 +#define CONTROL_PADCONF_SDRC_D19 0x0056 +#define CONTROL_PADCONF_SDRC_D20 0x0058 +#define CONTROL_PADCONF_SDRC_D21 0x005A +#define CONTROL_PADCONF_SDRC_D22 0x005C +#define CONTROL_PADCONF_SDRC_D23 0x005E +#define CONTROL_PADCONF_SDRC_D24 0x0060 +#define CONTROL_PADCONF_SDRC_D25 0x0062 +#define CONTROL_PADCONF_SDRC_D26 0x0064 +#define CONTROL_PADCONF_SDRC_D27 0x0066 +#define CONTROL_PADCONF_SDRC_D28 0x0068 +#define CONTROL_PADCONF_SDRC_D29 0x006A +#define CONTROL_PADCONF_SDRC_D30 0x006C +#define CONTROL_PADCONF_SDRC_D31 0x006E +#define CONTROL_PADCONF_SDRC_CLK 0x0070 +#define CONTROL_PADCONF_SDRC_DQS0 0x0072 +#define CONTROL_PADCONF_SDRC_DQS1 0x0074 +#define CONTROL_PADCONF_SDRC_DQS2 0x0076 +#define CONTROL_PADCONF_SDRC_DQS3 0x0078 +/*GPMC*/ +#define CONTROL_PADCONF_GPMC_A1 0x007A +#define CONTROL_PADCONF_GPMC_A2 0x007C +#define CONTROL_PADCONF_GPMC_A3 0x007E +#define CONTROL_PADCONF_GPMC_A4 0x0080 +#define CONTROL_PADCONF_GPMC_A5 0x0082 +#define CONTROL_PADCONF_GPMC_A6 0x0084 +#define CONTROL_PADCONF_GPMC_A7 0x0086 +#define CONTROL_PADCONF_GPMC_A8 0x0088 +#define CONTROL_PADCONF_GPMC_A9 0x008A +#define CONTROL_PADCONF_GPMC_A10 0x008C +#define CONTROL_PADCONF_GPMC_D0 0x008E +#define CONTROL_PADCONF_GPMC_D1 0x0090 +#define CONTROL_PADCONF_GPMC_D2 0x0092 +#define CONTROL_PADCONF_GPMC_D3 0x0094 +#define CONTROL_PADCONF_GPMC_D4 0x0096 +#define CONTROL_PADCONF_GPMC_D5 0x0098 +#define CONTROL_PADCONF_GPMC_D6 0x009A +#define CONTROL_PADCONF_GPMC_D7 0x009C +#define CONTROL_PADCONF_GPMC_D8 0x009E +#define CONTROL_PADCONF_GPMC_D9 0x00A0 +#define CONTROL_PADCONF_GPMC_D10 0x00A2 +#define CONTROL_PADCONF_GPMC_D11 0x00A4 +#define CONTROL_PADCONF_GPMC_D12 0x00A6 +#define CONTROL_PADCONF_GPMC_D13 0x00A8 +#define CONTROL_PADCONF_GPMC_D14 0x00AA +#define CONTROL_PADCONF_GPMC_D15 0x00AC +#define CONTROL_PADCONF_GPMC_NCS0 0x00AE +#define CONTROL_PADCONF_GPMC_NCS1 0x00B0 +#define CONTROL_PADCONF_GPMC_NCS2 0x00B2 +#define CONTROL_PADCONF_GPMC_NCS3 0x00B4 +#define CONTROL_PADCONF_GPMC_NCS4 0x00B6 +#define CONTROL_PADCONF_GPMC_NCS5 0x00B8 +#define CONTROL_PADCONF_GPMC_NCS6 0x00BA +#define CONTROL_PADCONF_GPMC_NCS7 0x00BC +#define CONTROL_PADCONF_GPMC_CLK 0x00BE +#define CONTROL_PADCONF_GPMC_NADV_ALE 0x00C0 +#define CONTROL_PADCONF_GPMC_NOE 0x00C2 +#define CONTROL_PADCONF_GPMC_NWE 0x00C4 +#define CONTROL_PADCONF_GPMC_NBE0_CLE 0x00C6 +#define CONTROL_PADCONF_GPMC_NBE1 0x00C8 +#define CONTROL_PADCONF_GPMC_NWP 0x00CA +#define CONTROL_PADCONF_GPMC_WAIT0 0x00CC +#define CONTROL_PADCONF_GPMC_WAIT1 0x00CE +#define CONTROL_PADCONF_GPMC_WAIT2 0x00D0 +#define CONTROL_PADCONF_GPMC_WAIT3 0x00D2 +/*DSS*/ +#define CONTROL_PADCONF_DSS_PCLK 0x00D4 +#define CONTROL_PADCONF_DSS_HSYNC 0x00D6 +#define CONTROL_PADCONF_DSS_VSYNC 0x00D8 +#define CONTROL_PADCONF_DSS_ACBIAS 0x00DA +#define CONTROL_PADCONF_DSS_DATA0 0x00DC +#define CONTROL_PADCONF_DSS_DATA1 0x00DE +#define CONTROL_PADCONF_DSS_DATA2 0x00E0 +#define CONTROL_PADCONF_DSS_DATA3 0x00E2 +#define CONTROL_PADCONF_DSS_DATA4 0x00E4 +#define CONTROL_PADCONF_DSS_DATA5 0x00E6 +#define CONTROL_PADCONF_DSS_DATA6 0x00E8 +#define CONTROL_PADCONF_DSS_DATA7 0x00EA +#define CONTROL_PADCONF_DSS_DATA8 0x00EC +#define CONTROL_PADCONF_DSS_DATA9 0x00EE +#define CONTROL_PADCONF_DSS_DATA10 0x00F0 +#define CONTROL_PADCONF_DSS_DATA11 0x00F2 +#define CONTROL_PADCONF_DSS_DATA12 0x00F4 +#define CONTROL_PADCONF_DSS_DATA13 0x00F6 +#define CONTROL_PADCONF_DSS_DATA14 0x00F8 +#define CONTROL_PADCONF_DSS_DATA15 0x00FA +#define CONTROL_PADCONF_DSS_DATA16 0x00FC +#define CONTROL_PADCONF_DSS_DATA17 0x00FE +#define CONTROL_PADCONF_DSS_DATA18 0x0100 +#define CONTROL_PADCONF_DSS_DATA19 0x0102 +#define CONTROL_PADCONF_DSS_DATA20 0x0104 +#define CONTROL_PADCONF_DSS_DATA21 0x0106 +#define CONTROL_PADCONF_DSS_DATA22 0x0108 +#define CONTROL_PADCONF_DSS_DATA23 0x010A +/*CAMERA*/ +#define CONTROL_PADCONF_CAM_HS 0x010C +#define CONTROL_PADCONF_CAM_VS 0x010E +#define CONTROL_PADCONF_CAM_XCLKA 0x0110 +#define CONTROL_PADCONF_CAM_PCLK 0x0112 +#define CONTROL_PADCONF_CAM_FLD 0x0114 +#define CONTROL_PADCONF_CAM_D0 0x0116 +#define CONTROL_PADCONF_CAM_D1 0x0118 +#define CONTROL_PADCONF_CAM_D2 0x011A +#define CONTROL_PADCONF_CAM_D3 0x011C +#define CONTROL_PADCONF_CAM_D4 0x011E +#define CONTROL_PADCONF_CAM_D5 0x0120 +#define CONTROL_PADCONF_CAM_D6 0x0122 +#define CONTROL_PADCONF_CAM_D7 0x0124 +#define CONTROL_PADCONF_CAM_D8 0x0126 +#define CONTROL_PADCONF_CAM_D9 0x0128 +#define CONTROL_PADCONF_CAM_D10 0x012A +#define CONTROL_PADCONF_CAM_D11 0x012C +#define CONTROL_PADCONF_CAM_XCLKB 0x012E +#define CONTROL_PADCONF_CAM_WEN 0x0130 +#define CONTROL_PADCONF_CAM_STROBE 0x0132 +#define CONTROL_PADCONF_CSI2_DX0 0x0134 +#define CONTROL_PADCONF_CSI2_DY0 0x0136 +#define CONTROL_PADCONF_CSI2_DX1 0x0138 +#define CONTROL_PADCONF_CSI2_DY1 0x013A +/*Audio Interface */ +#define CONTROL_PADCONF_MCBSP2_FSX 0x013C +#define CONTROL_PADCONF_MCBSP2_CLKX 0x013E +#define CONTROL_PADCONF_MCBSP2_DR 0x0140 +#define CONTROL_PADCONF_MCBSP2_DX 0x0142 +#define CONTROL_PADCONF_MMC1_CLK 0x0144 +#define CONTROL_PADCONF_MMC1_CMD 0x0146 +#define CONTROL_PADCONF_MMC1_DAT0 0x0148 +#define CONTROL_PADCONF_MMC1_DAT1 0x014A +#define CONTROL_PADCONF_MMC1_DAT2 0x014C +#define CONTROL_PADCONF_MMC1_DAT3 0x014E +#define CONTROL_PADCONF_MMC1_DAT4 0x0150 +#define CONTROL_PADCONF_MMC1_DAT5 0x0152 +#define CONTROL_PADCONF_MMC1_DAT6 0x0154 +#define CONTROL_PADCONF_MMC1_DAT7 0x0156 +/*Wireless LAN */ +#define CONTROL_PADCONF_MMC2_CLK 0x0158 +#define CONTROL_PADCONF_MMC2_CMD 0x015A +#define CONTROL_PADCONF_MMC2_DAT0 0x015C +#define CONTROL_PADCONF_MMC2_DAT1 0x015E +#define CONTROL_PADCONF_MMC2_DAT2 0x0160 +#define CONTROL_PADCONF_MMC2_DAT3 0x0162 +#define CONTROL_PADCONF_MMC2_DAT4 0x0164 +#define CONTROL_PADCONF_MMC2_DAT5 0x0166 +#define CONTROL_PADCONF_MMC2_DAT6 0x0168 +#define CONTROL_PADCONF_MMC2_DAT7 0x016A +/*Bluetooth*/ +#define CONTROL_PADCONF_MCBSP3_DX 0x016C +#define CONTROL_PADCONF_MCBSP3_DR 0x016E +#define CONTROL_PADCONF_MCBSP3_CLKX 0x0170 +#define CONTROL_PADCONF_MCBSP3_FSX 0x0172 +#define CONTROL_PADCONF_UART2_CTS 0x0174 +#define CONTROL_PADCONF_UART2_RTS 0x0176 +#define CONTROL_PADCONF_UART2_TX 0x0178 +#define CONTROL_PADCONF_UART2_RX 0x017A +/*Modem Interface */ +#define CONTROL_PADCONF_UART1_TX 0x017C +#define CONTROL_PADCONF_UART1_RTS 0x017E +#define CONTROL_PADCONF_UART1_CTS 0x0180 +#define CONTROL_PADCONF_UART1_RX 0x0182 +#define CONTROL_PADCONF_MCBSP4_CLKX 0x0184 +#define CONTROL_PADCONF_MCBSP4_DR 0x0186 +#define CONTROL_PADCONF_MCBSP4_DX 0x0188 +#define CONTROL_PADCONF_MCBSP4_FSX 0x018A +#define CONTROL_PADCONF_MCBSP1_CLKR 0x018C +#define CONTROL_PADCONF_MCBSP1_FSR 0x018E +#define CONTROL_PADCONF_MCBSP1_DX 0x0190 +#define CONTROL_PADCONF_MCBSP1_DR 0x0192 +#define CONTROL_PADCONF_MCBSP_CLKS 0x0194 +#define CONTROL_PADCONF_MCBSP1_FSX 0x0196 +#define CONTROL_PADCONF_MCBSP1_CLKX 0x0198 +/*Serial Interface*/ +#define CONTROL_PADCONF_UART3_CTS_RCTX 0x019A +#define CONTROL_PADCONF_UART3_RTS_SD 0x019C +#define CONTROL_PADCONF_UART3_RX_IRRX 0x019E +#define CONTROL_PADCONF_UART3_TX_IRTX 0x01A0 +#define CONTROL_PADCONF_HSUSB0_CLK 0x01A2 +#define CONTROL_PADCONF_HSUSB0_STP 0x01A4 +#define CONTROL_PADCONF_HSUSB0_DIR 0x01A6 +#define CONTROL_PADCONF_HSUSB0_NXT 0x01A8 +#define CONTROL_PADCONF_HSUSB0_DATA0 0x01AA +#define CONTROL_PADCONF_HSUSB0_DATA1 0x01AC +#define CONTROL_PADCONF_HSUSB0_DATA2 0x01AE +#define CONTROL_PADCONF_HSUSB0_DATA3 0x01B0 +#define CONTROL_PADCONF_HSUSB0_DATA4 0x01B2 +#define CONTROL_PADCONF_HSUSB0_DATA5 0x01B4 +#define CONTROL_PADCONF_HSUSB0_DATA6 0x01B6 +#define CONTROL_PADCONF_HSUSB0_DATA7 0x01B8 +#define CONTROL_PADCONF_I2C1_SCL 0x01BA +#define CONTROL_PADCONF_I2C1_SDA 0x01BC +#define CONTROL_PADCONF_I2C2_SCL 0x01BE +#define CONTROL_PADCONF_I2C2_SDA 0x01C0 +#define CONTROL_PADCONF_I2C3_SCL 0x01C2 +#define CONTROL_PADCONF_I2C3_SDA 0x01C4 +#define CONTROL_PADCONF_I2C4_SCL 0x0A00 +#define CONTROL_PADCONF_I2C4_SDA 0x0A02 +#define CONTROL_PADCONF_HDQ_SIO 0x01C6 +#define CONTROL_PADCONF_MCSPI1_CLK 0x01C8 +#define CONTROL_PADCONF_MCSPI1_SIMO 0x01CA +#define CONTROL_PADCONF_MCSPI1_SOMI 0x01CC +#define CONTROL_PADCONF_MCSPI1_CS0 0x01CE +#define CONTROL_PADCONF_MCSPI1_CS1 0x01D0 +#define CONTROL_PADCONF_MCSPI1_CS2 0x01D2 +#define CONTROL_PADCONF_MCSPI1_CS3 0x01D4 +#define CONTROL_PADCONF_MCSPI2_CLK 0x01D6 +#define CONTROL_PADCONF_MCSPI2_SIMO 0x01D8 +#define CONTROL_PADCONF_MCSPI2_SOMI 0x01DA +#define CONTROL_PADCONF_MCSPI2_CS0 0x01DC +#define CONTROL_PADCONF_MCSPI2_CS1 0x01DE +/*Control and debug */ +#define CONTROL_PADCONF_SYS_32K 0x0A04 +#define CONTROL_PADCONF_SYS_CLKREQ 0x0A06 +#define CONTROL_PADCONF_SYS_NIRQ 0x01E0 +#define CONTROL_PADCONF_SYS_BOOT0 0x0A0A +#define CONTROL_PADCONF_SYS_BOOT1 0x0A0C +#define CONTROL_PADCONF_SYS_BOOT2 0x0A0E +#define CONTROL_PADCONF_SYS_BOOT3 0x0A10 +#define CONTROL_PADCONF_SYS_BOOT4 0x0A12 +#define CONTROL_PADCONF_SYS_BOOT5 0x0A14 +#define CONTROL_PADCONF_SYS_BOOT6 0x0A16 +#define CONTROL_PADCONF_SYS_OFF_MODE 0x0A18 +#define CONTROL_PADCONF_SYS_CLKOUT1 0x0A1A +#define CONTROL_PADCONF_SYS_CLKOUT2 0x01E2 +#define CONTROL_PADCONF_JTAG_nTRST 0x0A1C +#define CONTROL_PADCONF_JTAG_TCK 0x0A1E +#define CONTROL_PADCONF_JTAG_TMS 0x0A20 +#define CONTROL_PADCONF_JTAG_TDI 0x0A22 +#define CONTROL_PADCONF_JTAG_EMU0 0x0A24 +#define CONTROL_PADCONF_JTAG_EMU1 0x0A26 +#define CONTROL_PADCONF_ETK_CLK 0x0A28 +#define CONTROL_PADCONF_ETK_CTL 0x0A2A +#define CONTROL_PADCONF_ETK_D0 0x0A2C +#define CONTROL_PADCONF_ETK_D1 0x0A2E +#define CONTROL_PADCONF_ETK_D2 0x0A30 +#define CONTROL_PADCONF_ETK_D3 0x0A32 +#define CONTROL_PADCONF_ETK_D4 0x0A34 +#define CONTROL_PADCONF_ETK_D5 0x0A36 +#define CONTROL_PADCONF_ETK_D6 0x0A38 +#define CONTROL_PADCONF_ETK_D7 0x0A3A +#define CONTROL_PADCONF_ETK_D8 0x0A3C +#define CONTROL_PADCONF_ETK_D9 0x0A3E +#define CONTROL_PADCONF_ETK_D10 0x0A40 +#define CONTROL_PADCONF_ETK_D11 0x0A42 +#define CONTROL_PADCONF_ETK_D12 0x0A44 +#define CONTROL_PADCONF_ETK_D13 0x0A46 +#define CONTROL_PADCONF_ETK_D14 0x0A48 +#define CONTROL_PADCONF_ETK_D15 0x0A4A +#define CONTROL_PADCONF_ETK_CLK_ES2 0x05D8 +#define CONTROL_PADCONF_ETK_CTL_ES2 0x05DA +#define CONTROL_PADCONF_ETK_D0_ES2 0x05DC +#define CONTROL_PADCONF_ETK_D1_ES2 0x05DE +#define CONTROL_PADCONF_ETK_D2_ES2 0x05E0 +#define CONTROL_PADCONF_ETK_D3_ES2 0x05E2 +#define CONTROL_PADCONF_ETK_D4_ES2 0x05E4 +#define CONTROL_PADCONF_ETK_D5_ES2 0x05E6 +#define CONTROL_PADCONF_ETK_D6_ES2 0x05E8 +#define CONTROL_PADCONF_ETK_D7_ES2 0x05EA +#define CONTROL_PADCONF_ETK_D8_ES2 0x05EC +#define CONTROL_PADCONF_ETK_D9_ES2 0x05EE +#define CONTROL_PADCONF_ETK_D10_ES2 0x05F0 +#define CONTROL_PADCONF_ETK_D11_ES2 0x05F2 +#define CONTROL_PADCONF_ETK_D12_ES2 0x05F4 +#define CONTROL_PADCONF_ETK_D13_ES2 0x05F6 +#define CONTROL_PADCONF_ETK_D14_ES2 0x05F8 +#define CONTROL_PADCONF_ETK_D15_ES2 0x05FA +/*Die to Die */ +#define CONTROL_PADCONF_D2D_MCAD0 0x01E4 +#define CONTROL_PADCONF_D2D_MCAD1 0x01E6 +#define CONTROL_PADCONF_D2D_MCAD2 0x01E8 +#define CONTROL_PADCONF_D2D_MCAD3 0x01EA +#define CONTROL_PADCONF_D2D_MCAD4 0x01EC +#define CONTROL_PADCONF_D2D_MCAD5 0x01EE +#define CONTROL_PADCONF_D2D_MCAD6 0x01F0 +#define CONTROL_PADCONF_D2D_MCAD7 0x01F2 +#define CONTROL_PADCONF_D2D_MCAD8 0x01F4 +#define CONTROL_PADCONF_D2D_MCAD9 0x01F6 +#define CONTROL_PADCONF_D2D_MCAD10 0x01F8 +#define CONTROL_PADCONF_D2D_MCAD11 0x01FA +#define CONTROL_PADCONF_D2D_MCAD12 0x01FC +#define CONTROL_PADCONF_D2D_MCAD13 0x01FE +#define CONTROL_PADCONF_D2D_MCAD14 0x0200 +#define CONTROL_PADCONF_D2D_MCAD15 0x0202 +#define CONTROL_PADCONF_D2D_MCAD16 0x0204 +#define CONTROL_PADCONF_D2D_MCAD17 0x0206 +#define CONTROL_PADCONF_D2D_MCAD18 0x0208 +#define CONTROL_PADCONF_D2D_MCAD19 0x020A +#define CONTROL_PADCONF_D2D_MCAD20 0x020C +#define CONTROL_PADCONF_D2D_MCAD21 0x020E +#define CONTROL_PADCONF_D2D_MCAD22 0x0210 +#define CONTROL_PADCONF_D2D_MCAD23 0x0212 +#define CONTROL_PADCONF_D2D_MCAD24 0x0214 +#define CONTROL_PADCONF_D2D_MCAD25 0x0216 +#define CONTROL_PADCONF_D2D_MCAD26 0x0218 +#define CONTROL_PADCONF_D2D_MCAD27 0x021A +#define CONTROL_PADCONF_D2D_MCAD28 0x021C +#define CONTROL_PADCONF_D2D_MCAD29 0x021E +#define CONTROL_PADCONF_D2D_MCAD30 0x0220 +#define CONTROL_PADCONF_D2D_MCAD31 0x0222 +#define CONTROL_PADCONF_D2D_MCAD32 0x0224 +#define CONTROL_PADCONF_D2D_MCAD33 0x0226 +#define CONTROL_PADCONF_D2D_MCAD34 0x0228 +#define CONTROL_PADCONF_D2D_MCAD35 0x022A +#define CONTROL_PADCONF_D2D_MCAD36 0x022C +#define CONTROL_PADCONF_D2D_CLK26MI 0x022E +#define CONTROL_PADCONF_D2D_NRESPWRON 0x0230 +#define CONTROL_PADCONF_D2D_NRESWARM 0x0232 +#define CONTROL_PADCONF_D2D_ARM9NIRQ 0x0234 +#define CONTROL_PADCONF_D2D_UMA2P6FIQ 0x0236 +#define CONTROL_PADCONF_D2D_SPINT 0x0238 +#define CONTROL_PADCONF_D2D_FRINT 0x023A +#define CONTROL_PADCONF_D2D_DMAREQ0 0x023C +#define CONTROL_PADCONF_D2D_DMAREQ1 0x023E +#define CONTROL_PADCONF_D2D_DMAREQ2 0x0240 +#define CONTROL_PADCONF_D2D_DMAREQ3 0x0242 +#define CONTROL_PADCONF_D2D_N3GTRST 0x0244 +#define CONTROL_PADCONF_D2D_N3GTDI 0x0246 +#define CONTROL_PADCONF_D2D_N3GTDO 0x0248 +#define CONTROL_PADCONF_D2D_N3GTMS 0x024A +#define CONTROL_PADCONF_D2D_N3GTCK 0x024C +#define CONTROL_PADCONF_D2D_N3GRTCK 0x024E +#define CONTROL_PADCONF_D2D_MSTDBY 0x0250 +#define CONTROL_PADCONF_D2D_SWAKEUP 0x0A4C +#define CONTROL_PADCONF_D2D_IDLEREQ 0x0252 +#define CONTROL_PADCONF_D2D_IDLEACK 0x0254 +#define CONTROL_PADCONF_D2D_MWRITE 0x0256 +#define CONTROL_PADCONF_D2D_SWRITE 0x0258 +#define CONTROL_PADCONF_D2D_MREAD 0x025A +#define CONTROL_PADCONF_D2D_SREAD 0x025C +#define CONTROL_PADCONF_D2D_MBUSFLAG 0x025E +#define CONTROL_PADCONF_D2D_SBUSFLAG 0x0260 +#define CONTROL_PADCONF_SDRC_CKE0 0x0262 +#define CONTROL_PADCONF_SDRC_CKE1 0x0264 + +#define MUX_VAL(OFFSET,VALUE)\ + writew((VALUE), OMAP34XX_CTRL_BASE + (OFFSET)); + +#define CP(x) (CONTROL_PADCONF_##x) + +#endif
diff --git a/x-loader/include/asm/arch-omap3/omap3.h b/x-loader/include/asm/arch-omap3/omap3.h new file mode 100644 index 0000000..0e392cc --- /dev/null +++ b/x-loader/include/asm/arch-omap3/omap3.h
@@ -0,0 +1,134 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <x0khasim@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 + */ + +#ifndef _OMAP3_SYS_H_ +#define _OMAP3_SYS_H_ + +#include <asm/arch/sizes.h> + +/* + * OMAP3 specific Section + */ + +/* Stuff on L3 Interconnect */ +#define SMX_APE_BASE 0x68000000 + +/* L3 Firewall */ +#define A_REQINFOPERM0 (SMX_APE_BASE + 0x05048) +#define A_READPERM0 (SMX_APE_BASE + 0x05050) +#define A_WRITEPERM0 (SMX_APE_BASE + 0x05058) + +/* GPMC */ +#define OMAP34XX_GPMC_BASE (0x6E000000) + +/* SMS */ +#define OMAP34XX_SMS_BASE 0x6C000000 + +/* SDRC */ +#define OMAP34XX_SDRC_BASE 0x6D000000 + +/* + * L4 Peripherals - L4 Wakeup and L4 Core now + */ +#define OMAP34XX_CORE_L4_IO_BASE 0x48000000 + +#define OMAP34XX_WAKEUP_L4_IO_BASE 0x48300000 + +#define OMAP34XX_L4_PER 0x49000000 + +#define OMAP34XX_L4_IO_BASE OMAP34XX_CORE_L4_IO_BASE + +/* CONTROL */ +#define OMAP34XX_CTRL_BASE (OMAP34XX_L4_IO_BASE+0x2000) + +/* TAP information dont know for 3430*/ +#define OMAP34XX_TAP_BASE (0x49000000) /*giving some junk for virtio */ + +/* UART */ +#define OMAP34XX_UART1 (OMAP34XX_L4_IO_BASE+0x6a000) +#define OMAP34XX_UART2 (OMAP34XX_L4_IO_BASE+0x6c000) +#define OMAP34XX_UART3 (OMAP34XX_L4_PER+0x20000) + +/* General Purpose Timers */ +#define OMAP34XX_GPT1 0x48318000 +#define OMAP34XX_GPT2 0x49032000 +#define OMAP34XX_GPT3 0x49034000 +#define OMAP34XX_GPT4 0x49036000 +#define OMAP34XX_GPT5 0x49038000 +#define OMAP34XX_GPT6 0x4903A000 +#define OMAP34XX_GPT7 0x4903C000 +#define OMAP34XX_GPT8 0x4903E000 +#define OMAP34XX_GPT9 0x49040000 +#define OMAP34XX_GPT10 0x48086000 +#define OMAP34XX_GPT11 0x48088000 +#define OMAP34XX_GPT12 0x48304000 + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE (0x4830C000) +#define WD2_BASE (0x48314000) +#define WD3_BASE (0x49030000) + +/* 32KTIMER */ +#define SYNC_32KTIMER_BASE (0x48320000) +#define S32K_CR (SYNC_32KTIMER_BASE+0x10) + +/* + * SDP3430 specific Section + */ + +/* + * The 343x's chip selects are programmable. The mask ROM + * does configure CS0 to 0x08000000 before dispatch. So, if + * you want your code to live below that address, you have to + * be prepared to jump though hoops, to reset the base address. + * Same as in SDP3430 + */ +/* base address for indirect vectors (internal boot mode) */ +#define SRAM_OFFSET0 0x40000000 +#define SRAM_OFFSET1 0x00200000 +#define SRAM_OFFSET2 0x0000F800 +#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) + +#define LOW_LEVEL_SRAM_STACK 0x4020FFFC + +/* + * TODO: Are they required for AM3517? + */ +#if defined(CONFIG_3430SDP) || defined(CONFIG_OMAP3EVM) +/* FPGA on Debug board.*/ +#define ETH_CONTROL_REG (DEBUG_BASE+0x30b) +#define LAN_RESET_REGISTER (DEBUG_BASE+0x1c) + +#define DIP_SWITCH_INPUT_REG2 (DEBUG_BASE+0x60) +#define LED_REGISTER (DEBUG_BASE+0x40) +#define FPGA_REV_REGISTER (DEBUG_BASE+0x10) +#define EEPROM_MAIN_BRD (DEBUG_BASE+0x10000+0x1800) +#define EEPROM_CONN_BRD (DEBUG_BASE+0x10000+0x1900) +#define EEPROM_UI_BRD (DEBUG_BASE+0x10000+0x1A00) +#define EEPROM_MCAM_BRD (DEBUG_BASE+0x10000+0x1B00) +#define ENHANCED_UI_EE_NAME "750-2075" +#endif + +#endif /* _OMAP3430_SYS_H_ */
diff --git a/x-loader/include/asm/arch-omap3/omap3430.h b/x-loader/include/asm/arch-omap3/omap3430.h new file mode 100644 index 0000000..16cde63 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/omap3430.h
@@ -0,0 +1,171 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <x0khasim@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 + */ + +#ifndef _OMAP3430_SYS_H_ +#define _OMAP3430_SYS_H_ + +#include <asm/arch/sizes.h> + +/* + * 3430 specific Section + */ + +/* Stuff on L3 Interconnect */ +#define SMX_APE_BASE 0x68000000 + +/* L3 Firewall */ +#define A_REQINFOPERM0 (SMX_APE_BASE + 0x05048) +#define A_READPERM0 (SMX_APE_BASE + 0x05050) +#define A_WRITEPERM0 (SMX_APE_BASE + 0x05058) + +/* GPMC */ +#define OMAP34XX_GPMC_BASE (0x6E000000) + +/* SMS */ +#define OMAP34XX_SMS_BASE 0x6C000000 + +/* SDRC */ +#define OMAP34XX_SDRC_BASE 0x6D000000 + +/* + * L4 Peripherals - L4 Wakeup and L4 Core now + */ +#define OMAP34XX_CORE_L4_IO_BASE 0x48000000 + +#define OMAP34XX_WAKEUP_L4_IO_BASE 0x48300000 + +#define OMAP34XX_L4_PER 0x49000000 + +#define OMAP34XX_L4_IO_BASE OMAP34XX_CORE_L4_IO_BASE + +/* CONTROL */ +#define OMAP34XX_CTRL_BASE (OMAP34XX_L4_IO_BASE+0x2000) + +/* TAP information dont know for 3430*/ +#define OMAP34XX_TAP_BASE (0x49000000) /*giving some junk for virtio */ + +/* UART */ +#define OMAP34XX_UART1 (OMAP34XX_L4_IO_BASE+0x6a000) +#define OMAP34XX_UART2 (OMAP34XX_L4_IO_BASE+0x6c000) +#define OMAP34XX_UART3 (OMAP34XX_L4_PER+0x20000) + +/* General Purpose Timers */ +#define OMAP34XX_GPT1 0x48318000 +#define OMAP34XX_GPT2 0x49032000 +#define OMAP34XX_GPT3 0x49034000 +#define OMAP34XX_GPT4 0x49036000 +#define OMAP34XX_GPT5 0x49038000 +#define OMAP34XX_GPT6 0x4903A000 +#define OMAP34XX_GPT7 0x4903C000 +#define OMAP34XX_GPT8 0x4903E000 +#define OMAP34XX_GPT9 0x49040000 +#define OMAP34XX_GPT10 0x48086000 +#define OMAP34XX_GPT11 0x48088000 +#define OMAP34XX_GPT12 0x48304000 + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE (0x4830C000) +#define WD2_BASE (0x48314000) +#define WD3_BASE (0x49030000) + +/* 32KTIMER */ +#define SYNC_32KTIMER_BASE (0x48320000) +#define S32K_CR (SYNC_32KTIMER_BASE+0x10) + +/* + * SDP3430 specific Section + */ + +/* + * The 343x's chip selects are programmable. The mask ROM + * does configure CS0 to 0x08000000 before dispatch. So, if + * you want your code to live below that address, you have to + * be prepared to jump though hoops, to reset the base address. + * Same as in SDP3430 + */ +#ifdef CONFIG_OMAP34XX +/* base address for indirect vectors (internal boot mode) */ +#define SRAM_OFFSET0 0x40000000 +#define SRAM_OFFSET1 0x00200000 +#define SRAM_OFFSET2 0x0000F800 +#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) + +#define LOW_LEVEL_SRAM_STACK 0x4020FFFC +#endif + +#if defined(CONFIG_3430SDP) || defined(CONFIG_OMAP3EVM) +/* FPGA on Debug board.*/ +#define ETH_CONTROL_REG (DEBUG_BASE+0x30b) +#define LAN_RESET_REGISTER (DEBUG_BASE+0x1c) + +#define DIP_SWITCH_INPUT_REG2 (DEBUG_BASE+0x60) +#define LED_REGISTER (DEBUG_BASE+0x40) +#define FPGA_REV_REGISTER (DEBUG_BASE+0x10) +#define EEPROM_MAIN_BRD (DEBUG_BASE+0x10000+0x1800) +#define EEPROM_CONN_BRD (DEBUG_BASE+0x10000+0x1900) +#define EEPROM_UI_BRD (DEBUG_BASE+0x10000+0x1A00) +#define EEPROM_MCAM_BRD (DEBUG_BASE+0x10000+0x1B00) +#define ENHANCED_UI_EE_NAME "750-2075" +#endif + +#if defined (CONFIG_AM3517EVM) || defined (CONFIG_AM3517TEB) +/* EMIF 4 replaces SDRC in AM3517 for DDR */ +#define EMIF4_MOD_ID 0x00 +#define EMIF4_STATUS 0x04 +#define EMIF4_SDR_CONFIG 0x08 +#define EMIF4_LPDDR2_CONFIF 0x0C +#define EMIF4_SDR_REF_CTRL 0x10 +#define EMIF4_SDR_REF_CTRL_SHDW 0x14 +#define EMIF4_SDR_TIM1 0x18 +#define EMIF4_SDR_TIM1_SHDW 0x1C +#define EMIF4_SDR_TIM2 0x20 +#define EMIF4_SDR_TIM2_SHDW 0x24 +#define EMIF4_SDR_TIM3 0x28 +#define EMIF4_SDR_TIM3_SHDW 0x2C +#define EMIF4_LPDDR2_NVM_TIM 0x30 +#define EMIF4_LPDDR2_NVM_TIM_SHDW 0x34 +#define EMIF4_PWR_MGMT_CTRL 0x38 +#define EMIF4_PWR_MGMT_CTRL_SHDW 0x3C +#define EMIF4_LPDDR2_REG_DATA 0x40 +#define EMIF4_LPDDR2_REG_CFG 0x50 +#define EMIF4_OCP_CONFIG 0x54 +#define EMIF4_OCP_CFG_VAL1 0x58 +#define EMIF4_OCP_CFG_VAL2 0x5C +#define EMIF4_PERF_CNT1 0x80 +#define EMIF4_PERF_CNT2 0x84 +#define EMIF4_PERF_CNT_CFG 0x88 +#define EMIF4_PERF_CNT_SEL 0x8C +#define EMIF4_PERF_CNT_TIM 0x90 +#define EMIF4_IRQ_EOI 0xA0 +#define EMIF4_IRQSTS_RAW 0xA4 +#define EMIF4_IRQSTS 0xAC +#define EMIF4_IRQEN_SET 0xB4 +#define EMIF4_IRQEN_CLR 0xBC +#define EMIF4_DDR_PHY_CTRL1 0xE4 +#define EMIF4_DDR_PHY_CTRL1_SHDW 0xE8 +#define EMIF4_DDR_PHY_CTRL2 0xEC +#endif + +#endif /* _OMAP3430_SYS_H_ */
diff --git a/x-loader/include/asm/arch-omap3/prcm.h b/x-loader/include/asm/arch-omap3/prcm.h new file mode 100644 index 0000000..d00fdae --- /dev/null +++ b/x-loader/include/asm/arch-omap3/prcm.h
@@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines register and register field constants and + * macros for the Texas Instruments Open Multimedia Application + * Platform (OMAP) 3 Power, Reset and Clock Management (PRCM) + * module. + */ + +#ifndef _OMAP3_PRCM_H +#define _OMAP3_PRCM_H + +#include <asm/arch/bits.h> + +#define PRCM_BASE 0x48000000 + +#define PRCM_CM_BASE (PRCM_BASE + 0x00004000) + +#define PRCM_PRM_BASE (PRCM_BASE + 0x00306000) + +#define PRCM_PRM_CCR_BASE (PRCM_PRM_BASE + 0x00000D00) + +#define PRCM_PRM_CCR_CLKSEL (PRCM_PRM_CCR_BASE + 0x00000040) +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_START 0 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS 3 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_MASK ARM_REG_VAL(0, ARM_REG_MASK(PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_BITS)) +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_ENCODE(v) ARM_REG_VAL_ENCODE(0, PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_MASK, v) +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_DECODE(v) ARM_REG_VAL_DECODE(0, PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_MASK, v) +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_12_0_MHZ 0x0 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_13_0_MHZ 0x1 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_19_2_MHZ 0x2 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_26_0_MHZ 0x3 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_38_4_MHZ 0x4 +#define PRCM_PRM_CCR_CLKSEL_SYS_CLKIN_SEL_16_8_MHZ 0x5 + +#define PRCM_PRM_CCR_CLKOUT_CTRL (PRCM_PRM_CCR_BASE + 0x00000070) + +#define PRCM_PRM_GR_BASE (PRCM_PRM_BASE + 0x00001200) + +#define PRCM_PRM_GR_CLKSRC_CTRL (PRCM_PRM_GR_BASE + 0x00000070) +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_START 6 +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS 2 +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_MASK ARM_REG_VAL(0, ARM_REG_MASK(PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BITS)) +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_ENCODE(v) ARM_REG_VAL_ENCODE(0, PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_MASK, v) +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_DECODE(v) ARM_REG_VAL_DECODE(0, PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_MASK, v) +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_1 1 +#define PRCM_PRM_GR_CLKSRC_CTRL_SYSCLKDIV_BY_2 2 + +#define PRCM_SR_BASE (PRCM_BASE + 0x000C9000) + +#define PRM_CLKSEL PRCM_PRM_CCR_CLKSEL +#define PRM_RSTCTRL 0x48307250 +#define PRM_CLKSRC_CTRL PRCM_PRM_GR_CLKSRC_CTRL + +#endif /* _OMAP3_PRCM_H */
diff --git a/x-loader/include/asm/arch-omap3/rev.h b/x-loader/include/asm/arch-omap3/rev.h new file mode 100755 index 0000000..c0e95d4 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/rev.h
@@ -0,0 +1,43 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <x0khasim@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 + */ + +#ifndef _OMAP34XX_REV_H_ +#define _OMAP34XX_REV_H_ + +#define CDB_DDR_COMBO /* combo part on cpu daughter card */ +#define CDB_DDR_IPDB /* 2x16 parts on daughter card */ + +#define DDR_100 100 /* type found on most mem d-boards */ +#define DDR_111 111 /* some combo parts */ +#define DDR_133 133 /* most combo, some mem d-boards */ +#define DDR_165 165 /* future parts */ + +#define CPU_3430 0x3430 + +#define CPU_3430_ES1 1 +#define CPU_3430_ES2 1 + +#endif
diff --git a/x-loader/include/asm/arch-omap3/sdrc.h b/x-loader/include/asm/arch-omap3/sdrc.h new file mode 100644 index 0000000..fc5201c --- /dev/null +++ b/x-loader/include/asm/arch-omap3/sdrc.h
@@ -0,0 +1,366 @@ +/* + * Copyright (c) 2010 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines register and register field constants and + * macros for the Texas Instruments Open Multimedia Application + * Platform (OMAP) 3 SDRAM Controller (SDRC). + */ + +#ifndef _OMAP3_SDRC_H +#define _OMAP3_SDRC_H + +#include <asm/arch/bits.h> + +/* + * SDRAM Controller Revision + */ +#define SDRC_REVISION_REV_MASK ARM_REG_VAL(0, 0xFF) +#define SDRC_REVISION_REV_MAJOR_MASK ARM_REG_VAL(4, 0xF) +#define SDRC_REVISION_REV_MINOR_MASK ARM_REG_VAL(0, 0xF) +#define SDRC_REVISION_REV_MAJOR_DECODE(x) ARM_REG_VAL_DECODE(4, SDRC_REVISION_REV_MAJOR_MASK, x) +#define SDRC_REVISION_REV_MINOR_DECODE(x) ARM_REG_VAL_DECODE(0, SDRC_REVISION_REV_MINOR_MASK), x) + +/* + * SDRAM Controller System Configuration + */ +#define SDRC_SYSCONFIG_NOMEMORYMRS_DISABLE ARM_REG_VAL(8, 0) +#define SDRC_SYSCONFIG_NOMEMORYMRS_ENABLE ARM_REG_VAL(8, 1) +#define SDRC_SYSCONFIG_IDLEMODE_SMART ARM_REG_VAL(3, 0x2) +#define SDRC_SYSCONFIG_SOFTRESET_CLEAR ARM_REG_VAL(1, 0x0) +#define SDRC_SYSCONFIG_SOFTRESET_SET ARM_REG_VAL(1, 0x1) + +/* + * SDRAM Controller System Status + */ +#define SDRC_SYSSTATUS_RESETDONE ARM_REG_VAL(0, 1) + +/* + * SDRAM Controller Chip Select Configuration + */ + +/* + * SDRAM Controller Multiplexing + */ +#define SDRC_SHARING_LOCK_OFF ARM_REG_VAL(30, 0) +#define SDRC_SHARING_LOCK_ON ARM_REG_VAL(30, 1) +#define SDRC_SHARING_CS1MUXCFG_MASK ARM_REG_VAL(12, 0x7) +#define SDRC_SHARING_CS1MUXCFG_ENCODE(v) ARM_REG_VAL_ENCODE(12, SDRC_SHARING_CS1MUXCFG_MASK, v) +#define SDRC_SHARING_CS1MUXCFG_DECODE(v) ARM_REG_VAL_DECODE(12, SDRC_SHARING_CS1MUXCFG_MASK, v) +#define SDRC_SHARING_CS1MUXCFG_32_BIT_31_0 0x0 +#define SDRC_SHARING_CS1MUXCFG_16_BIT_31_16 0x2 +#define SDRC_SHARING_CS1MUXCFG_16_BIT_16_0 0x3 +#define SDRC_SHARING_CS0MUXCFG_MASK ARM_REG_VAL(9, 0x7) +#define SDRC_SHARING_CS0MUXCFG_ENCODE(v) ARM_REG_VAL_ENCODE(9, SDRC_SHARING_CS0MUXCFG_MASK, v) +#define SDRC_SHARING_CS0MUXCFG_DECODE(v) ARM_REG_VAL_DECODE(9, SDRC_SHARING_CS0MUXCFG_MASK), v) +#define SDRC_SHARING_CS0MUXCFG_32_BIT_31_0 0x0 +#define SDRC_SHARING_CS0MUXCFG_16_BIT_31_16 0x2 +#define SDRC_SHARING_CS0MUXCFG_16_BIT_16_0 0x3 +#define SDRC_SHARING_SDRCTRISTATE_ON ARM_REG_VAL(8, 0) +#define SDRC_SHARING_SDRCTRISTATE_OFF ARM_REG_VAL(8, 1) + +/* + * SDRAM Controller Error Address + */ + +/* + * SDRAM Controller Error Type + */ + +/* + * SDRAM Controller DDR A Fine Tuning Control + */ +#define SDRC_DLLA_CTRL_FIXED_DELAY_MASK ARM_REG_VAL(24, 0xFF) +#define SDRC_DLLA_CTRL_FIXED_DELAY_ENCODE(v) ARM_REG_VAL_ENCODE(24, SDRC_DLLA_CTRL_FIXED_DELAY_MASK, v) +#define SDRC_DLLA_CTRL_FIXED_DELAY_DECODE(v) ARM_REG_VAL_DECODE(24, SDRC_DLLA_CTRL_FIXED_DELAY_MASK, v) + +#define SDRC_DLLA_CTRL_INIT_LAT_MASK ARM_REG_VAL(16, 0xFF) +#define SDRC_DLLA_CTRL_INIT_LAT_ENCODE(v) ARM_REG_VAL_ENCODE(16, SDRC_DLLA_CTRL_INIT_LAT_MASK, v / 2) +#define SDRC_DLLA_CTRL_INIT_LAT_DECODE(v) (ARM_REG_VAL_DECODE(16, SDRC_DLLA_CTRL_INIT_LAT_MASK, v) * 2) + +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_MASK ARM_REG_VAL(5, 0x3) +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_ENCODE(v) ARM_REG_VAL_ENCODE(5, SDRC_DLLA_CTRL_MODE_ON_IDLE_MASK, v) +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_DECODE(v) ARM_REG_VAL_DECODE(5, SDRC_DLLA_CTRL_MODE_ON_IDLE_MASK, v) +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_PWD 0x0 +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_IDLE 0x1 +#define SDRC_DLLA_CTRL_MODE_ON_IDLE_IGNORE 0x2 + +#define SDRC_DLLA_CTRL_IDLE_DISABLE ARM_REG_VAL(4, 0) +#define SDRC_DLLA_CTRL_IDLE_ENABLE ARM_REG_VAL(4, 1) + +#define SDRC_DLLA_CTRL_DLL_DISABLE ARM_REG_VAL(3, 0) +#define SDRC_DLLA_CTRL_DLL_ENABLE ARM_REG_VAL(3, 1) + +#define SDRC_DLLA_CTRL_LOCK_TRACKINGDELAY ARM_REG_VAL(2, 0) +#define SDRC_DLLA_CTRL_LOCK_FIXEDDELAY ARM_REG_VAL(2, 1) + +/* + * SDRAM Controller DDR A Fine Tuning Status + */ + +/* + * SDRAM Controller Power Management Policy + */ + +#define SDRC_POWER_REG_WAKEUP_DELAYED ARM_REG_VAL(26, 0) +#define SDRC_POWER_REG_WAKEUP_IMMED ARM_REG_VAL(26, 1) + +#define SDRC_POWER_REG_AUTOCOUNT_MASK ARM_REG_VAL(8, 0xFFFF) +#define SDRC_POWER_REG_AUTOCOUNT_ENCODE(v) ARM_REG_VAL_ENCODE(8, SDRC_POWER_REG_AUTOCOUNT_MASK, v) +#define SDRC_POWER_REG_AUTOCOUNT_DECODE(v) ARM_REG_VAL_DECODE(8, SDRC_POWER_REG_AUTOCOUNT_MASK), v) + +#define SDRC_POWER_REG_SRFR_ON_RST_DISABLE ARM_REG_VAL(7, 0) +#define SDRC_POWER_REG_SRFR_ON_RST_ENABLE ARM_REG_VAL(7, 1) + +#define SDRC_POWER_REG_SRFR_ON_IDLE_DISABLE ARM_REG_VAL(6, 0) +#define SDRC_POWER_REG_SRFR_ON_IDLE_ENABLE ARM_REG_VAL(6, 1) + +#define SDRC_POWER_REG_CLKCTRL_MASK ARM_REG_VAL(4, 0x3) +#define SDRC_POWER_REG_CLKCTRL_ENCODE(v) ARM_REG_VAL_ENCODE(4, SDRC_POWER_REG_CLKCTRL_MASK, v) +#define SDRC_POWER_REG_CLKCTRL_DECODE(v) ARM_REG_VAL_DECODE(4, SDRC_POWER_REG_CLKCTRL_MASK), v) +#define SDRC_POWER_REG_CLKCTRL_NONE 0x0 +#define SDRC_POWER_REG_CLKCTRL_SELF_GATE 0x1 +#define SDRC_POWER_REG_CLKCTRL_SELF_REFRESH 0x2 + +#define SDRC_POWER_REG_EXTCLKDIS_ON ARM_REG_VAL(3, 1) +#define SDRC_POWER_REG_EXTCLKDIS_ON ARM_REG_VAL(3, 1) + +#define SDRC_POWER_REG_PWD_DISABLE ARM_REG_VAL(2, 0) +#define SDRC_POWER_REG_PWD_ENABLE ARM_REG_VAL(2, 1) + +#define SDRC_POWER_REG_PAGEPOLICY_HPHB ARM_REG_VAL(0, 1) + +/* + * SDRAM Controller Memory Configuration + */ +#define SDRC_MCFG_LOCKSTATUS_RW ARM_REG_VAL(30, 0) +#define SDRC_MCFG_LOCKSTATUS_RO ARM_REG_VAL(30, 1) + +#define SDRC_MCFG_RASWIDTH_MASK ARM_REG_VAL(24, 0x7) +#define SDRC_MCFG_RASWIDTH_ENCODE(v) ARM_REG_VAL_ENCODE(24, SDRC_MCFG_RASWIDTH_MASK, v) +#define SDRC_MCFG_RASWIDTH_DECODE(v) ARM_REG_VAL_DECODE(24, SDRC_MCFG_RASWIDTH_MASK), v) +#define SDRC_MCFG_RASWIDTH_11_BITS 0x0 +#define SDRC_MCFG_RASWIDTH_12_BITS 0x1 +#define SDRC_MCFG_RASWIDTH_13_BITS 0x2 +#define SDRC_MCFG_RASWIDTH_14_BITS 0x3 +#define SDRC_MCFG_RASWIDTH_15_BITS 0x4 +#define SDRC_MCFG_RASWIDTH_16_BITS 0x5 +#define SDRC_MCFG_RASWIDTH_17_BITS 0x6 +#define SDRC_MCFG_RASWIDTH_18_BITS 0x7 + +#define SDRC_MCFG_CASWIDTH_MASK ARM_REG_VAL(20, 0x7) +#define SDRC_MCFG_CASWIDTH_ENCODE(v) ARM_REG_VAL_ENCODE(20, SDRC_MCFG_CASWIDTH_MASK, v) +#define SDRC_MCFG_CASWIDTH_DECODE(v) ARM_REG_VAL_DECODE(20, SDRC_MCFG_CASWIDTH_MASK), v) +#define SDRC_MCFG_CASWIDTH_5_BITS 0x0 +#define SDRC_MCFG_CASWIDTH_6_BITS 0x1 +#define SDRC_MCFG_CASWIDTH_7_BITS 0x2 +#define SDRC_MCFG_CASWIDTH_8_BITS 0x3 +#define SDRC_MCFG_CASWIDTH_9_BITS 0x4 +#define SDRC_MCFG_CASWIDTH_10_BITS 0x5 +#define SDRC_MCFG_CASWIDTH_11_BITS 0x6 +#define SDRC_MCFG_CASWIDTH_12_BITS 0x7 + +#define SDRC_MCFG_ADDRMUX_MASK ARM_REG_VAL(20, 0x1F) +#define SDRC_MCFG_ADDRMUX_ENCODE(v) ARM_REG_VAL_ENCODE(20, SDRC_MCFG_ADDRMUX_MASK, v) +#define SDRC_MCFG_ADDRMUX_DECODE(v) ARM_REG_VAL_DECODE(20, SDRC_MCFG_ADDRMUX_MASK, v) +#define SDRC_MCFG_ADDRMUX_SCHEME_1 0x0 +#define SDRC_MCFG_ADDRMUX_SCHEME_2 0x1 +#define SDRC_MCFG_ADDRMUX_SCHEME_3 0x2 +#define SDRC_MCFG_ADDRMUX_SCHEME_4 0x3 +#define SDRC_MCFG_ADDRMUX_SCHEME_5 0x4 +#define SDRC_MCFG_ADDRMUX_SCHEME_6 0x5 +#define SDRC_MCFG_ADDRMUX_SCHEME_7 0x6 +#define SDRC_MCFG_ADDRMUX_SCHEME_8 0x7 +#define SDRC_MCFG_ADDRMUX_SCHEME_9 0x8 +#define SDRC_MCFG_ADDRMUX_SCHEME_10 0x9 +#define SDRC_MCFG_ADDRMUX_SCHEME_11 0xA +#define SDRC_MCFG_ADDRMUX_SCHEME_12 0xB +#define SDRC_MCFG_ADDRMUX_SCHEME_13 0xC +#define SDRC_MCFG_ADDRMUX_SCHEME_14 0xD +#define SDRC_MCFG_ADDRMUX_SCHEME_15 0xE +#define SDRC_MCFG_ADDRMUX_SCHEME_16 0xF +#define SDRC_MCFG_ADDRMUX_SCHEME_23 0x16 +#define SDRC_MCFG_ADDRMUX_SCHEME_24 0x17 +#define SDRC_MCFG_ADDRMUX_SCHEME_25 0x18 +#define SDRC_MCFG_ADDRMUX_SCHEME_26 0x19 +#define SDRC_MCFG_ADDRMUX_SCHEME_27 0x1A +#define SDRC_MCFG_ADDRMUX_SCHEME_28 0x1B +#define SDRC_MCFG_ADDRMUX_SCHEME_29 0x1C + +#define SDRC_MCFG_ADDRMUXLEGACY_FIXED ARM_REG_VAL(19, 0) +#define SDRC_MCFG_ADDRMUXLEGACY_FLEXIBLE ARM_REG_VAL(19, 1) + +#define SDRC_MCFG_RAMSIZE_MASK ARM_REG_VAL(8, 0x3FF) +#define SDRC_MCFG_RAMSIZE_ENCODE(v) ARM_REG_VAL_ENCODE(8, SDRC_MCFG_RAMSIZE_MASK, ((v) / 2)) +#define SDRC_MCFG_RAMSIZE_DECODE(v) (ARM_REG_VAL_DECODE(8, SDRC_MCFG_RAMSIZE_MASK, v) * 2) + +#define SDRC_MCFG_BANKALLOCATION_MASK ARM_REG_VAL(6, 0x3) +#define SDRC_MCFG_BANKALLOCATION_ENCODE(v) ARM_REG_VAL_ENCODE(6, SDRC_MCFG_BANKALLOCATION_MASK, v) +#define SDRC_MCFG_BANKALLOCATION_DECODE(v) ARM_REG_VAL_DECODE(6, SDRC_MCFG_BANKALLOCATION_MASK), v) +#define SDRC_MCFG_BANKALLOCATION_B_R_C 0x0 +#define SDRC_MCFG_BANKALLOCATION_B1_R_B0_C 0x1 +#define SDRC_MCFG_BANKALLOCATION_R_B_C 0x2 + +#define SDRC_MCFG_B32NOT16_OFF ARM_REG_VAL(4, 0) +#define SDRC_MCFG_B32NOT16_ON ARM_REG_VAL(4, 1) + +#define SDRC_MCFG_DEEPPD_UNSUPPORTED ARM_REG_VAL(3, 0) +#define SDRC_MCFG_DEEPPD_SUPPORTED ARM_REG_VAL(3, 1) + +#define SDRC_MCFG_DDRTYPE_MASK ARM_REG_VAL(2, 0x1) +#define SDRC_MCFG_DDRTYPE_ENCODE(v) ARM_REG_VAL_ENCODE(2, SDRC_MCFG_DDRTYPE_MASK, v) +#define SDRC_MCFG_DDRTYPE_DECODE(v) ARM_REG_VAL_DECODE(2, SDRC_MCFG_DDRTYPE_MASK, v) +#define SDRC_MCFG_DDRTYPE_MOBILE_DDR 0 + +#define SDRC_MCFG_RAMTYPE_MASK ARM_REG_VAL(0, 0x3) +#define SDRC_MCFG_RAMTYPE_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_MCFG_RAMTYPE_MASK, v) +#define SDRC_MCFG_RAMTYPE_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_MCFG_RAMTYPE_MASK, v) +#define SDRC_MCFG_RAMTYPE_SDR 0x0 +#define SDRC_MCFG_RAMTYPE_DDR 0x1 + +/* + * SDRAM Controller DDR Mode Register (Corresponds 1:1 w/ JEDEC Mode + * Register) + */ + +#define SDRC_MR_ZERO_1 ARM_REG_VAL(10, 0) + +#define SDRC_MR_WBST_ENABLE ARM_REG_VAL(9, 0) +#define SDRC_MR_WBST_DISABLE ARM_REG_VAL(9, 1) + +#define SDRC_MR_ZERO_0 ARM_REG_VAL(7, 0) + +#define SDRC_MR_CASL_MASK ARM_REG_VAL(4, 0x7) +#define SDRC_MR_CASL_ENCODE(v) ARM_REG_VAL_ENCODE(4, SDRC_MR_CASL_MASK, v) +#define SDRC_MR_CASL_DECODE(v) ARM_REG_VAL_DECODE(4, SDRC_MR_CASL_MASK, v) +#define SDRC_MR_CASL_1 0x1 +#define SDRC_MR_CASL_2 0x2 +#define SDRC_MR_CASL_3 0x3 +#define SDRC_MR_CASL_4 0x4 +#define SDRC_MR_CASL_5 0x5 + +#define SDRC_MR_SIL_SERIAL ARM_REG_VAL(3, 0) +#define SDRC_MR_SIL_INTERLEAVED ARM_REG_VAL(3, 1) + +#define SDRC_MR_BL_MASK ARM_REG_VAL(0, 0x7) +#define SDRC_MR_BL_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_MR_BL_MASK, v) +#define SDRC_MR_BL_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_MR_BL_MASK, v) +#define SDRC_MR_BL_1 0x0 +#define SDRC_MR_BL_2 0x1 +#define SDRC_MR_BL_4 0x2 +#define SDRC_MR_BL_8 0x3 +#define SDRC_MR_BL_FULL_PAGE 0x7 + +/* + * SDRAM Controller DDR Extended Mode Register (Corresponds 1:1 w/ + * JEDEC Mode Register) + */ + +/* + * SDRAM Controller AC Timing Control A + */ +#define SDRC_ACTIM_CTRLA_TRFC_MASK ARM_REG_VAL(27, 0x1F) +#define SDRC_ACTIM_CTRLA_TRFC_ENCODE(v) ARM_REG_VAL_ENCODE(27, SDRC_ACTIM_CTRLA_TRFC_MASK, v) +#define SDRC_ACTIM_CTRLA_TRFC_DECODE(v) ARM_REG_VAL_DECODE(27, SDRC_ACTIM_CTRLA_TRFC_MASK), v) + +#define SDRC_ACTIM_CTRLA_TRC_MASK ARM_REG_VAL(22, 0x1F) +#define SDRC_ACTIM_CTRLA_TRC_ENCODE(v) ARM_REG_VAL_ENCODE(22, SDRC_ACTIM_CTRLA_TRC_MASK, v) +#define SDRC_ACTIM_CTRLA_TRC_DECODE(v) ARM_REG_VAL_DECODE(22, SDRC_ACTIM_CTRLA_TRC_MASK), v) + +#define SDRC_ACTIM_CTRLA_TRAS_MASK ARM_REG_VAL(18, 0xF) +#define SDRC_ACTIM_CTRLA_TRAS_ENCODE(v) ARM_REG_VAL_ENCODE(18, SDRC_ACTIM_CTRLA_TRAS_MASK, v) +#define SDRC_ACTIM_CTRLA_TRAS_DECODE(v) ARM_REG_VAL_DECODE(18, SDRC_ACTIM_CTRLA_TRAS_MASK), v) + +#define SDRC_ACTIM_CTRLA_TRP_MASK ARM_REG_VAL(15, 0x7) +#define SDRC_ACTIM_CTRLA_TRP_ENCODE(v) ARM_REG_VAL_ENCODE(15, SDRC_ACTIM_CTRLA_TRP_MASK, v) +#define SDRC_ACTIM_CTRLA_TRP_DECODE(v) ARM_REG_VAL_DECODE(15, SDRC_ACTIM_CTRLA_TRP_MASK), v) + +#define SDRC_ACTIM_CTRLA_TRCD_MASK ARM_REG_VAL(12, 0x7) +#define SDRC_ACTIM_CTRLA_TRCD_ENCODE(v) ARM_REG_VAL_ENCODE(12, SDRC_ACTIM_CTRLA_TRCD_MASK, v) +#define SDRC_ACTIM_CTRLA_TRCD_DECODE(v) ARM_REG_VAL_DECODE(12, SDRC_ACTIM_CTRLA_TRCD_MASK), v) + +#define SDRC_ACTIM_CTRLA_TRRD_MASK ARM_REG_VAL(9, 0x7) +#define SDRC_ACTIM_CTRLA_TRRD_ENCODE(v) ARM_REG_VAL_ENCODE(9, SDRC_ACTIM_CTRLA_TRRD_MASK, v) +#define SDRC_ACTIM_CTRLA_TRRD_DECODE(v) ARM_REG_VAL_DECODE(9, SDRC_ACTIM_CTRLA_TRRD_MASK), v) + +#define SDRC_ACTIM_CTRLA_TDPL_MASK ARM_REG_VAL(6, 0x7) +#define SDRC_ACTIM_CTRLA_TDPL_ENCODE(v) ARM_REG_VAL_ENCODE(6, SDRC_ACTIM_CTRLA_TDPL_MASK, v) +#define SDRC_ACTIM_CTRLA_TDPL_DECODE(v) ARM_REG_VAL_DECODE(6, SDRC_ACTIM_CTRLA_TDPL_MASK), v) + +#define SDRC_ACTIM_CTRLA_TDAL_MASK ARM_REG_VAL(0, 0x1F) +#define SDRC_ACTIM_CTRLA_TDAL_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_ACTIM_CTRLA_TDAL_MASK, v) +#define SDRC_ACTIM_CTRLA_TDAL_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_ACTIM_CTRLA_TDAL_MASK), v) + +/* + * SDRAM Controller AC Timing Control B + */ +#define SDRC_ACTIM_CTRLB_TWTR_MASK ARM_REG_VAL(16, 0x3) +#define SDRC_ACTIM_CTRLB_TWTR_ENCODE(v) ARM_REG_VAL_ENCODE(16, SDRC_ACTIM_CTRLB_TWTR_MASK, v) +#define SDRC_ACTIM_CTRLB_TWTR_DECODE(v) ARM_REG_VAL_DECODE(16, SDRC_ACTIM_CTRLB_TWTR_MASK), v) + +#define SDRC_ACTIM_CTRLB_TCKE_MASK ARM_REG_VAL(12, 0x7) +#define SDRC_ACTIM_CTRLB_TCKE_ENCODE(v) ARM_REG_VAL_ENCODE(12, SDRC_ACTIM_CTRLB_TCKE_MASK, v) +#define SDRC_ACTIM_CTRLB_TCKE_DECODE(v) ARM_REG_VAL_DECODE(12, SDRC_ACTIM_CTRLB_TCKE_MASK), v) + +#define SDRC_ACTIM_CTRLB_TXP_MASK ARM_REG_VAL(8, 0x7) +#define SDRC_ACTIM_CTRLB_TXP_ENCODE(v) ARM_REG_VAL_ENCODE(8, SDRC_ACTIM_CTRLB_TXP_MASK, v) +#define SDRC_ACTIM_CTRLB_TXP_DECODE(v) ARM_REG_VAL_DECODE(8, SDRC_ACTIM_CTRLB_TXP_MASK), v) + +#define SDRC_ACTIM_CTRLB_TXSR_MASK ARM_REG_VAL(0, 0xFF) +#define SDRC_ACTIM_CTRLB_TXSR_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_ACTIM_CTRLB_TXSR_MASK, v) +#define SDRC_ACTIM_CTRLB_TXSR_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_ACTIM_CTRLB_TXSR_MASK), v) + +/* + * SDRAM Controller Autorefresh Control + */ +#define SDRC_RFR_CTRL_ARCV_MASK ARM_REG_VAL(8, 0xFFFF) +#define SDRC_RFR_CTRL_ARCV_ENCODE(v) ARM_REG_VAL_ENCODE(8, SDRC_RFR_CTRL_ARCV_MASK, v) +#define SDRC_RFR_CTRL_ARCV_DECODE(v) ARM_REG_VAL_DECODE(8, SDRC_RFR_CTRL_ARCV_MASK), v) + +#define SDRC_RFR_CTRL_ARE_MASK ARM_REG_VAL(0, 0x3) +#define SDRC_RFR_CTRL_ARE_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_RFR_CTRL_ARE_MASK, v) +#define SDRC_RFR_CTRL_ARE_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_RFR_CTRL_ARE_MASK), v) +#define SDRC_RFR_CTRL_ARE_DISABLED 0x0 +#define SDRC_RFR_CTRL_ARE_1_ARCV 0x1 +#define SDRC_RFR_CTRL_ARE_4_ARCV 0x2 +#define SDRC_RFR_CTRL_ARE_8_ARCV 0x3 + +/* + * SDRAM Controller Manual Control + */ +#define SDRC_MANUAL_CMDPARAM_MASK ARM_REG_VAL(16, 0xFFFF) +#define SDRC_MANUAL_CMDPARAM_ENCODE(v) ARM_REG_VAL_ENCODE(16, SDRC_MANUAL_CMDPARAM_MASK, v) +#define SDRC_MANUAL_CMDPARAM_DECODE(v) ARM_REG_VAL_DECODE(16, SDRC_MANUAL_CMDPARAM_MASK), v) + +#define SDRC_MANUAL_CMDCODE_MASK ARM_REG_VAL(0, 0x7) +#define SDRC_MANUAL_CMDCODE_ENCODE(v) ARM_REG_VAL_ENCODE(0, SDRC_MANUAL_CMDCODE_MASK, v) +#define SDRC_MANUAL_CMDCODE_DECODE(v) ARM_REG_VAL_DECODE(0, SDRC_MANUAL_CMDCODE_MASK), v) +#define SDRC_MANUAL_CMDCODE_NOP 0x0 +#define SDRC_MANUAL_CMDCODE_PRECHARGE_ALL 0x1 +#define SDRC_MANUAL_CMDCODE_AUTOREFRESH 0x2 +#define SDRC_MANUAL_CMDCODE_ENTER_PWD 0x3 +#define SDRC_MANUAL_CMDCODE_EXIT_PWD 0x4 +#define SDRC_MANUAL_CMDCODE_ENTER_SELFREFRESH 0x5 +#define SDRC_MANUAL_CMDCODE_EXIT_SELFREFRESH 0x6 +#define SDRC_MANUAL_CMDCODE_SET_CKE_HIGH 0x7 +#define SDRC_MANUAL_CMDCODE_SET_CKE_LOW 0x8 + +#endif /* _OMAP3_SDRC_H */
diff --git a/x-loader/include/asm/arch-omap3/sizes.h b/x-loader/include/asm/arch-omap3/sizes.h new file mode 100644 index 0000000..aaba18f --- /dev/null +++ b/x-loader/include/asm/arch-omap3/sizes.h
@@ -0,0 +1,49 @@ +/* + * 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 + */ +/* Size defintions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_32K 0x00008000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_31M 0x01F00000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif /* __sizes_h */
diff --git a/x-loader/include/asm/arch-omap3/sys_info.h b/x-loader/include/asm/arch-omap3/sys_info.h new file mode 100644 index 0000000..19a5dd0 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/sys_info.h
@@ -0,0 +1,93 @@ +/* + * (C) Copyright 2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP34XX_SYS_INFO_H_ +#define _OMAP34XX_SYS_INFO_H_ + +#define XDR_POP 5 /* package on package part */ +#define SDR_DISCRETE 4 /* 128M memory SDR module*/ +#define DDR_STACKED 3 /* stacked part on 2422 */ +#define DDR_COMBO 2 /* combo part on cpu daughter card (menalaeus) */ +#define DDR_DISCRETE 1 /* 2x16 parts on daughter card */ + +#define DDR_100 100 /* type found on most mem d-boards */ +#define DDR_111 111 /* some combo parts */ +#define DDR_133 133 /* most combo, some mem d-boards */ +#define DDR_165 165 /* future parts */ + +#define CPU_3430 0x3430 + +/* 343x real hardware: + * ES1 = rev 0 + */ + +/* 343x code defines: + * ES1 = 0+1 = 1 + * ES1 = 1+1 = 1 + */ +#define CPU_3430_ES1 1 +#define CPU_3430_ES2 2 + +/* + * Hawkeye values + */ +#define HAWKEYE_OMAP34XX 0xb7ae +#define HAWKEYE_AM35XX 0xb868 +#define HAWKEYE_OMAP36XX 0xb891 + +#define HAWKEYE_SHIFT 12 + +/* + * Define CPU families + */ +#define CPU_OMAP34XX 0x3400 /* OMAP34xx/OMAP35 devices */ +#define CPU_AM35XX 0x3500 /* AM35xx devices */ +#define CPU_OMAP36XX 0x3600 /* OMAP36xx devices */ + +/* Currently Virtio models this one */ +#define CPU_3430_CHIPID 0x0B68A000 + +#define GPMC_MUXED 1 +#define GPMC_NONMUXED 0 + +#define TYPE_NAND 0x800 /* bit pos for nand in gpmc reg */ +#define TYPE_NOR 0x000 +#define TYPE_ONENAND 0x800 + +#define WIDTH_8BIT 0x0000 +#define WIDTH_16BIT 0x1000 /* bit pos for 16 bit in gpmc */ + +#define I2C_MENELAUS 0x72 /* i2c id for companion chip */ +#define I2C_TRITON2 0x4B /* addres of power group */ + +#define BOOT_FAST_XIP 0x1f + +/* SDP definitions according to FPGA Rev. Is this OK?? */ +#define SDP_3430_V1 0x1 +#define SDP_3430_V2 0x2 + +#define BOARD_3430_LABRADOR 0x80 +#define BOARD_3430_LABRADOR_V1 0x1 + +#endif
diff --git a/x-loader/include/asm/arch-omap3/sys_proto.h b/x-loader/include/asm/arch-omap3/sys_proto.h new file mode 100644 index 0000000..980fb20 --- /dev/null +++ b/x-loader/include/asm/arch-omap3/sys_proto.h
@@ -0,0 +1,59 @@ +/* + * (C) Copyright 2004-2006 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _OMAP34XX_SYS_PROTO_H_ +#define _OMAP34XX_SYS_PROTO_H_ + +void prcm_init(void); +void per_clocks_enable(void); + +void memif_init(void); +void sdrc_init(void); +void do_sdrc_init(u32,u32); +void gpmc_init(void); + +void ether_init(void); +void watchdog_init(void); +void set_muxconf_regs(void); +u32 is_cpu_family(void); +u32 get_cpu_type(void); +u32 get_cpu_rev(void); +u32 cpu_is_3410(void); +u32 get_mem_type(void); +u32 get_sysboot_value(void); +u32 get_gpmc0_base(void); +u32 is_gpmc_muxed(void); +u32 get_gpmc0_type(void); +u32 get_gpmc0_width(void); +u32 get_board_type(void); +void display_board_info(u32); +void update_mux(u32,u32); +u32 get_sdr_cs_size(u32 offset); +u32 running_in_sdram(void); +u32 running_in_sram(void); +u32 running_in_flash(void); +u32 running_from_internal_boot(void); +u32 get_device_type(void); + +void sr32(u32 addr, u32 start_bit, u32 num_bits, u32 value); +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound); +void sdelay(unsigned long loops); + +#endif
diff --git a/x-loader/include/asm/atomic.h b/x-loader/include/asm/atomic.h new file mode 100644 index 0000000..ba9e4b7 --- /dev/null +++ b/x-loader/include/asm/atomic.h
@@ -0,0 +1,113 @@ +/* + * linux/include/asm-arm/atomic.h + * + * Copyright (c) 1996 Russell King. + * + * 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. + * + * Changelog: + * 27-06-1996 RMK Created + * 13-04-1997 RMK Made functions atomic! + * 07-12-1997 RMK Upgraded for v2.1. + * 26-08-1998 PJB Added #ifdef __KERNEL__ + */ +#ifndef __ASM_ARM_ATOMIC_H +#define __ASM_ARM_ATOMIC_H + +#include <linux/config.h> + +#ifdef CONFIG_SMP +#error SMP not supported +#endif + +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ +#include <asm/proc/system.h> + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +static inline void atomic_add(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +} + +static inline void atomic_sub(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); +} + +static inline void atomic_inc(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += 1; + local_irq_restore(flags); +} + +static inline void atomic_dec(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= 1; + local_irq_restore(flags); +} + +static inline int atomic_dec_and_test(volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val -= 1; + local_irq_restore(flags); + + return val == 0; +} + +static inline int atomic_add_negative(int i, volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val += i; + local_irq_restore(flags); + + return val < 0; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + local_irq_save(flags); + *addr &= ~mask; + local_irq_restore(flags); +} + +/* Atomic operations are already serializing on ARM */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#endif +#endif
diff --git a/x-loader/include/asm/byteorder.h b/x-loader/include/asm/byteorder.h new file mode 100755 index 0000000..c3489f1 --- /dev/null +++ b/x-loader/include/asm/byteorder.h
@@ -0,0 +1,32 @@ +/* + * linux/include/asm-arm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM_BYTEORDER_H +#define __ASM_ARM_BYTEORDER_H + + +#include <asm/types.h> + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#ifdef __ARMEB__ +#include <linux/byteorder/big_endian.h> +#else +#include <linux/byteorder/little_endian.h> +#endif + +#endif
diff --git a/x-loader/include/asm/config.h b/x-loader/include/asm/config.h new file mode 100644 index 0000000..04f98f9 --- /dev/null +++ b/x-loader/include/asm/config.h
@@ -0,0 +1,22 @@ +/* + * 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_CONFIG_H_ +#define _ASM_CONFIG_H_ + +#endif
diff --git a/x-loader/include/asm/io.h b/x-loader/include/asm/io.h new file mode 100644 index 0000000..ff1518e --- /dev/null +++ b/x-loader/include/asm/io.h
@@ -0,0 +1,429 @@ +/* + * linux/include/asm-arm/io.h + * + * Copyright (C) 1996-2000 Russell King + * + * 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. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + */ +#ifndef __ASM_ARM_IO_H +#define __ASM_ARM_IO_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/byteorder.h> +#include <asm/memory.h> +#if 0 /* XXX###XXX */ +#include <asm/arch/hardware.h> +#endif /* XXX###XXX */ + +static inline void sync(void) +{ +} + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ + +} + +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + +/* + * Generic virtual read/write. Note that we don't support half-word + * read/writes. We define __arch_*[bl] here, and leave __arch_*w + * to the architecture specific code. + */ +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +extern inline void __raw_writesb(unsigned int addr, const void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + __arch_putb(*buf++, addr); +} + +extern inline void __raw_writesw(unsigned int addr, const void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + __arch_putw(*buf++, addr); +} + +extern inline void __raw_writesl(unsigned int addr, const void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + __arch_putl(*buf++, addr); +} + +extern inline void __raw_readsb(unsigned int addr, void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + *buf++ = __arch_getb(addr); +} + +extern inline void __raw_readsw(unsigned int addr, void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + *buf++ = __arch_getw(addr); +} + +extern inline void __raw_readsl(unsigned int addr, void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + *buf++ = __arch_getl(addr); +} + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) + +#define writeb(v,a) __arch_putb(v,a) +#define writew(v,a) __arch_putw(v,a) +#define writel(v,a) __arch_putl(v,a) + +#define readb(a) __arch_getb(a) +#define readw(a) __arch_getw(a) +#define readl(a) __arch_getl(a) + +/* + * The compiler seems to be incapable of optimising constants + * properly. Spell it out to the compiler in some cases. + * These are only valid for small values of "off" (< 1<<12) + */ +#define __raw_base_writeb(val,base,off) __arch_base_putb(val,base,off) +#define __raw_base_writew(val,base,off) __arch_base_putw(val,base,off) +#define __raw_base_writel(val,base,off) __arch_base_putl(val,base,off) + +#define __raw_base_readb(base,off) __arch_base_getb(base,off) +#define __raw_base_readw(base,off) __arch_base_getw(base,off) +#define __raw_base_readl(base,off) __arch_base_getl(base,off) + +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a) +#define in_arch(type,endian,a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a,v) out_arch(l,le32,a,v) +#define out_le16(a,v) out_arch(w,le16,a,v) + +#define in_le32(a) in_arch(l,le32,a) +#define in_le16(a) in_arch(w,le16,a) + +#define out_be32(a,v) out_arch(l,be32,a,v) +#define out_be16(a,v) out_arch(w,be16,a,v) + +#define in_be32(a) in_arch(l,be32,a) +#define in_be16(a) in_arch(w,be16,a) + +#define out_8(a,v) __raw_writeb(v,a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + +/* + * Now, pick up the machine-defined IO definitions + */ +#if 0 /* XXX###XXX */ +#include <asm/arch/io.h> +#endif /* XXX###XXX */ + +/* + * IO port access primitives + * ------------------------- + * + * The ARM doesn't have special IO access instructions; all IO is memory + * mapped. Note that these are defined to perform little endian accesses + * only. Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place, as described by numerous + * ARM documents: + * + * PCI: D0-D7 D8-D15 D16-D23 D24-D31 + * ARM: D24-D31 D16-D23 D8-D15 D0-D7 + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address. + * + * Note that we prevent GCC re-ordering or caching values in expressions + * by introducing sequence points into the in*() definitions. Note that + * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. + */ +#ifdef __io +#define outb(v,p) __raw_writeb(v,__io(p)) +#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p)) +#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p)) + +#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) +#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) +#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) + +#define outsb(p,d,l) __raw_writesb(__io(p),d,l) +#define outsw(p,d,l) __raw_writesw(__io(p),d,l) +#define outsl(p,d,l) __raw_writesl(__io(p),d,l) + +#define insb(p,d,l) __raw_readsb(__io(p),d,l) +#define insw(p,d,l) __raw_readsw(__io(p),d,l) +#define insl(p,d,l) __raw_readsl(__io(p),d,l) +#endif + +#define outb_p(val,port) outb((val),(port)) +#define outw_p(val,port) outw((val),(port)) +#define outl_p(val,port) outl((val),(port)) +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) + +#define outsb_p(port,from,len) outsb(port,from,len) +#define outsw_p(port,from,len) outsw(port,from,len) +#define outsl_p(port,from,len) outsl(port,from,len) +#define insb_p(port,to,len) insb(port,to,len) +#define insw_p(port,to,len) insw(port,to,len) +#define insl_p(port,to,len) insl(port,to,len) + +/* + * ioremap and friends. + * + * ioremap takes a PCI memory address, as specified in + * linux/Documentation/IO-mapping.txt. If you want a + * physical address, use __ioremap instead. + */ +extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags); +extern void __iounmap(void *addr); + +/* + * Generic ioremap support. + * + * Define: + * iomem_valid_addr(off,size) + * iomem_to_phys(off) + */ +#ifdef iomem_valid_addr +#define __arch_ioremap(off,sz,nocache) \ + ({ \ + unsigned long _off = (off), _size = (sz); \ + void *_ret = (void *)0; \ + if (iomem_valid_addr(_off, _size)) \ + _ret = __ioremap(iomem_to_phys(_off),_size,nocache); \ + _ret; \ + }) + +#define __arch_iounmap __iounmap +#endif + +#define ioremap(off,sz) __arch_ioremap((off),(sz),0) +#define ioremap_nocache(off,sz) __arch_ioremap((off),(sz),1) +#define iounmap(_addr) __arch_iounmap(_addr) + +/* + * DMA-consistent mapping functions. These allocate/free a region of + * uncached, unwrite-buffered mapped memory space for use with DMA + * devices. This is the "generic" version. The PCI specific version + * is in pci.h + */ +extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle); +extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); +extern void consistent_sync(void *vaddr, size_t size, int rw); + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, unsigned long, size_t); +extern void _memcpy_toio(unsigned long, const void *, size_t); +extern void _memset_io(unsigned long, int, size_t); + +extern void __readwrite_bug(const char *fn); + +/* + * If this architecture has PCI memory IO, then define the read/write + * macros. These should only be used with the cookie passed from + * ioremap. + */ +#ifdef __mem_pci + +#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) +#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) + +#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) +#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) +#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) + +#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) +#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) + +#define eth_io_copy_and_sum(s,c,l,b) \ + eth_copy_and_sum((s),__mem_pci(c),(l),(b)) + +static inline int +check_signature(unsigned long io_addr, const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#elif !defined(readb) + +#define readb(addr) (__readwrite_bug("readb"),0) +#define readw(addr) (__readwrite_bug("readw"),0) +#define readl(addr) (__readwrite_bug("readl"),0) +#define writeb(v,addr) __readwrite_bug("writeb") +#define writew(v,addr) __readwrite_bug("writew") +#define writel(v,addr) __readwrite_bug("writel") + +#define eth_io_copy_and_sum(a,b,c,d) __readwrite_bug("eth_io_copy_and_sum") + +#define check_signature(io,sig,len) (0) + +#endif /* __mem_pci */ + +/* + * If this architecture has ISA IO, then define the isa_read/isa_write + * macros. + */ +#ifdef __mem_isa + +#define isa_readb(addr) __raw_readb(__mem_isa(addr)) +#define isa_readw(addr) __raw_readw(__mem_isa(addr)) +#define isa_readl(addr) __raw_readl(__mem_isa(addr)) +#define isa_writeb(val,addr) __raw_writeb(val,__mem_isa(addr)) +#define isa_writew(val,addr) __raw_writew(val,__mem_isa(addr)) +#define isa_writel(val,addr) __raw_writel(val,__mem_isa(addr)) +#define isa_memset_io(a,b,c) _memset_io(__mem_isa(a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_isa(b),(c)) +#define isa_memcpy_toio(a,b,c) _memcpy_toio(__mem_isa((a)),(b),(c)) + +#define isa_eth_io_copy_and_sum(a,b,c,d) \ + eth_copy_and_sum((a),__mem_isa(b),(c),(d)) + +static inline int +isa_check_signature(unsigned long io_addr, const unsigned char *signature, + int length) +{ + int retval = 0; + do { + if (isa_readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#else /* __mem_isa */ + +#define isa_readb(addr) (__readwrite_bug("isa_readb"),0) +#define isa_readw(addr) (__readwrite_bug("isa_readw"),0) +#define isa_readl(addr) (__readwrite_bug("isa_readl"),0) +#define isa_writeb(val,addr) __readwrite_bug("isa_writeb") +#define isa_writew(val,addr) __readwrite_bug("isa_writew") +#define isa_writel(val,addr) __readwrite_bug("isa_writel") +#define isa_memset_io(a,b,c) __readwrite_bug("isa_memset_io") +#define isa_memcpy_fromio(a,b,c) __readwrite_bug("isa_memcpy_fromio") +#define isa_memcpy_toio(a,b,c) __readwrite_bug("isa_memcpy_toio") + +#define isa_eth_io_copy_and_sum(a,b,c,d) \ + __readwrite_bug("isa_eth_io_copy_and_sum") + +#define isa_check_signature(io,sig,len) (0) + +#endif /* __mem_isa */ +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_IO_H */
diff --git a/x-loader/include/asm/memory.h b/x-loader/include/asm/memory.h new file mode 100644 index 0000000..c3b2afd --- /dev/null +++ b/x-loader/include/asm/memory.h
@@ -0,0 +1,137 @@ +/* + * linux/include/asm-arm/memory.h + * + * Copyright (C) 2000-2002 Russell King + * + * 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. + * + * Note: this file should not be included by non-asm/.h files + */ +#ifndef __ASM_ARM_MEMORY_H +#define __ASM_ARM_MEMORY_H + +#if 0 /* XXX###XXX */ + +#include <linux/config.h> +#include <asm/arch/memory.h> + +/* + * PFNs are used to describe any physical page; this means + * PFN 0 == physical address 0. + * + * This is the PFN of the first RAM page in the kernel + * direct-mapped view. We assume this is the first page + * of RAM in the mem_map as well. + */ +#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) + +/* + * These are *only* valid on the kernel direct mapped RAM memory. + */ +static inline unsigned long virt_to_phys(void *x) +{ + return __virt_to_phys((unsigned long)(x)); +} + +static inline void *phys_to_virt(unsigned long x) +{ + return (void *)(__phys_to_virt((unsigned long)(x))); +} + +#define __pa(x) __virt_to_phys((unsigned long)(x)) +#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) + +/* + * Virtual <-> DMA view memory address translations + * Again, these are *only* valid on the kernel direct mapped RAM + * memory. Use of these is *depreciated*. + */ +#define virt_to_bus(x) (__virt_to_bus((unsigned long)(x))) +#define bus_to_virt(x) ((void *)(__bus_to_virt((unsigned long)(x)))) + +/* + * Conversion between a struct page and a physical address. + * + * Note: when converting an unknown physical address to a + * struct page, the resulting pointer must be validated + * using VALID_PAGE(). It must return an invalid struct page + * for any physical address not corresponding to a system + * RAM address. + * + * page_to_pfn(page) convert a struct page * to a PFN number + * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * + * pfn_valid(pfn) indicates whether a PFN number is valid + * + * virt_to_page(k) convert a _valid_ virtual address to struct page * + * virt_addr_valid(k) indicates whether a virtual address is valid + */ +#ifndef CONFIG_DISCONTIGMEM + +#define page_to_pfn(page) (((page) - mem_map) + PHYS_PFN_OFFSET) +#define pfn_to_page(pfn) ((mem_map + (pfn)) - PHYS_PFN_OFFSET) +#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) + +#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +#define virt_addr_valid(kaddr) ((kaddr) >= PAGE_OFFSET && (kaddr) < (unsigned long)high_memory) + +#define PHYS_TO_NID(addr) (0) + +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) + +#else + +/* + * This is more complex. We have a set of mem_map arrays spread + * around in memory. + */ +#define page_to_pfn(page) \ + (((page) - page_zone(page)->zone_mem_map) \ + + (page_zone(page)->zone_start_paddr >> PAGE_SHIFT)) + +#define pfn_to_page(pfn) \ + (PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT)) + +#define pfn_valid(pfn) \ + ({ \ + unsigned int node = PFN_TO_NID(pfn); \ + struct pglist_data *nd = NODE_DATA(node); \ + ((node < NR_NODES) && \ + ((pfn - (nd->node_start_paddr >> PAGE_SHIFT)) < nd->node_size));\ + }) + +#define virt_to_page(kaddr) \ + (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) + +#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < NR_NODES) + +/* + * Common discontigmem stuff. + * PHYS_TO_NID is used by the ARM kernel/setup.c + */ +#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT) + +/* + * 2.4 compatibility + * + * VALID_PAGE returns a non-zero value if given page pointer is valid. + * This assumes all node's mem_maps are stored within the node they + * refer to. This is actually inherently buggy. + */ +#define VALID_PAGE(page) \ +({ unsigned int node = KVADDR_TO_NID(page); \ + ((node < NR_NODES) && \ + ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size)); \ +}) + +#endif + +/* + * We should really eliminate virt_to_bus() here - it's depreciated. + */ +#define page_to_bus(page) (virt_to_bus(page_address(page))) + +#endif /* XXX###XXX */ + +#endif /* __ASM_ARM_MEMORY_H */
diff --git a/x-loader/include/asm/posix_types.h b/x-loader/include/asm/posix_types.h new file mode 100644 index 0000000..c412486 --- /dev/null +++ b/x-loader/include/asm/posix_types.h
@@ -0,0 +1,79 @@ +/* + * linux/include/asm-arm/posix_types.h + * + * Copyright (C) 1996-1998 Russell King. + * + * 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. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp))) + +#endif + +#endif
diff --git a/x-loader/include/asm/setup.h b/x-loader/include/asm/setup.h new file mode 100644 index 0000000..89df4dc --- /dev/null +++ b/x-loader/include/asm/setup.h
@@ -0,0 +1,269 @@ +/* + * linux/include/asm/setup.h + * + * Copyright (C) 1997-1999 Russell King + * + * 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. + * + * Structure passed to kernel to tell it about the + * hardware it's running on. See linux/Documentation/arm/Setup + * for more info. + * + * NOTE: + * This file contains two ways to pass information from the boot + * loader to the kernel. The old struct param_struct is deprecated, + * but it will be kept in the kernel for 5 years from now + * (2001). This will allow boot loaders to convert to the new struct + * tag way. + */ +#ifndef __ASMARM_SETUP_H +#define __ASMARM_SETUP_H + +/* + * Usage: + * - do not go blindly adding fields, add them at the end + * - when adding fields, don't rely on the address until + * a patch from me has been released + * - unused fields should be zero (for future expansion) + * - this structure is relatively short-lived - only + * guaranteed to contain useful data in setup_arch() + */ +#define COMMAND_LINE_SIZE 1024 + +/* This is the old deprecated way to pass parameters to the kernel */ +struct param_struct { + union { + struct { + unsigned long page_size; /* 0 */ + unsigned long nr_pages; /* 4 */ + unsigned long ramdisk_size; /* 8 */ + unsigned long flags; /* 12 */ +#define FLAG_READONLY 1 +#define FLAG_RDLOAD 4 +#define FLAG_RDPROMPT 8 + unsigned long rootdev; /* 16 */ + unsigned long video_num_cols; /* 20 */ + unsigned long video_num_rows; /* 24 */ + unsigned long video_x; /* 28 */ + unsigned long video_y; /* 32 */ + unsigned long memc_control_reg; /* 36 */ + unsigned char sounddefault; /* 40 */ + unsigned char adfsdrives; /* 41 */ + unsigned char bytes_per_char_h; /* 42 */ + unsigned char bytes_per_char_v; /* 43 */ + unsigned long pages_in_bank[4]; /* 44 */ + unsigned long pages_in_vram; /* 60 */ + unsigned long initrd_start; /* 64 */ + unsigned long initrd_size; /* 68 */ + unsigned long rd_start; /* 72 */ + unsigned long system_rev; /* 76 */ + unsigned long system_serial_low; /* 80 */ + unsigned long system_serial_high; /* 84 */ + unsigned long mem_fclk_21285; /* 88 */ + } s; + char unused[256]; + } u1; + union { + char paths[8][128]; + struct { + unsigned long magic; + char n[1024 - sizeof(unsigned long)]; + } s; + } u2; + char commandline[COMMAND_LINE_SIZE]; +}; + + +/* + * The new way of passing information: a list of tagged entries + */ + +/* The list ends with an ATAG_NONE node. */ +#define ATAG_NONE 0x00000000 + +struct tag_header { + u32 size; + u32 tag; +}; + +/* The list must start with an ATAG_CORE node */ +#define ATAG_CORE 0x54410001 + +struct tag_core { + u32 flags; /* bit 0 = read-only */ + u32 pagesize; + u32 rootdev; +}; + +/* it is allowed to have multiple ATAG_MEM nodes */ +#define ATAG_MEM 0x54410002 + +struct tag_mem32 { + u32 size; + u32 start; /* physical start address */ +}; + +/* VGA text type displays */ +#define ATAG_VIDEOTEXT 0x54410003 + +struct tag_videotext { + u8 x; + u8 y; + u16 video_page; + u8 video_mode; + u8 video_cols; + u16 video_ega_bx; + u8 video_lines; + u8 video_isvga; + u16 video_points; +}; + +/* describes how the ramdisk will be used in kernel */ +#define ATAG_RAMDISK 0x54410004 + +struct tag_ramdisk { + u32 flags; /* bit 0 = load, bit 1 = prompt */ + u32 size; /* decompressed ramdisk size in _kilo_ bytes */ + u32 start; /* starting block of floppy-based RAM disk image */ +}; + +/* describes where the compressed ramdisk image lives (virtual address) */ +/* + * this one accidentally used virtual addresses - as such, + * its depreciated. + */ +#define ATAG_INITRD 0x54410005 + +/* describes where the compressed ramdisk image lives (physical address) */ +#define ATAG_INITRD2 0x54420005 + +struct tag_initrd { + u32 start; /* physical start address */ + u32 size; /* size of compressed ramdisk image in bytes */ +}; + +/* board serial number. "64 bits should be enough for everybody" */ +#define ATAG_SERIAL 0x54410006 + +struct tag_serialnr { + u32 low; + u32 high; +}; + +/* board revision */ +#define ATAG_REVISION 0x54410007 + +struct tag_revision { + u32 rev; +}; + +/* initial values for vesafb-type framebuffers. see struct screen_info + * in include/linux/tty.h + */ +#define ATAG_VIDEOLFB 0x54410008 + +struct tag_videolfb { + u16 lfb_width; + u16 lfb_height; + u16 lfb_depth; + u16 lfb_linelength; + u32 lfb_base; + u32 lfb_size; + u8 red_size; + u8 red_pos; + u8 green_size; + u8 green_pos; + u8 blue_size; + u8 blue_pos; + u8 rsvd_size; + u8 rsvd_pos; +}; + +/* command line: \0 terminated string */ +#define ATAG_CMDLINE 0x54410009 + +struct tag_cmdline { + char cmdline[1]; /* this is the minimum size */ +}; + +/* acorn RiscPC specific information */ +#define ATAG_ACORN 0x41000101 + +struct tag_acorn { + u32 memc_control_reg; + u32 vram_pages; + u8 sounddefault; + u8 adfsdrives; +}; + +/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ +#define ATAG_MEMCLK 0x41000402 + +struct tag_memclk { + u32 fmemclk; +}; + +struct tag { + struct tag_header hdr; + union { + struct tag_core core; + struct tag_mem32 mem; + struct tag_videotext videotext; + struct tag_ramdisk ramdisk; + struct tag_initrd initrd; + struct tag_serialnr serialnr; + struct tag_revision revision; + struct tag_videolfb videolfb; + struct tag_cmdline cmdline; + + /* + * Acorn specific + */ + struct tag_acorn acorn; + + /* + * DC21285 specific + */ + struct tag_memclk memclk; + } u; +}; + +struct tagtable { + u32 tag; + int (*parse)(const struct tag *); +}; + +#define __tag __attribute__((unused, __section__(".taglist"))) +#define __tagtable(tag, fn) \ +static struct tagtable __tagtable_##fn __tag = { tag, fn } + +#define tag_member_present(tag,member) \ + ((unsigned long)(&((struct tag *)0L)->member + 1) \ + <= (tag)->hdr.size * 4) + +#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) +#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) + +#define for_each_tag(t,base) \ + for (t = base; t->hdr.size; t = tag_next(t)) + +/* + * Memory map description + */ +#define NR_BANKS 8 + +struct meminfo { + int nr_banks; + unsigned long end; + struct { + unsigned long start; + unsigned long size; + int node; + } bank[NR_BANKS]; +}; + +extern struct meminfo meminfo; + +#endif
diff --git a/x-loader/include/asm/sizes.h b/x-loader/include/asm/sizes.h new file mode 100644 index 0000000..f8d92ca --- /dev/null +++ b/x-loader/include/asm/sizes.h
@@ -0,0 +1,52 @@ +/* + * 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 + */ +/* DO NOT EDIT!! - this file automatically generated + * from .s file by awk -f s2h.awk + */ +/* Size defintions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h 1 + +/* handy sizes */ +#define SZ_1K 0x00000400 +#define SZ_4K 0x00001000 +#define SZ_8K 0x00002000 +#define SZ_16K 0x00004000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 +#define SZ_512K 0x00080000 + +#define SZ_1M 0x00100000 +#define SZ_2M 0x00200000 +#define SZ_4M 0x00400000 +#define SZ_8M 0x00800000 +#define SZ_16M 0x01000000 +#define SZ_32M 0x02000000 +#define SZ_64M 0x04000000 +#define SZ_128M 0x08000000 +#define SZ_256M 0x10000000 +#define SZ_512M 0x20000000 + +#define SZ_1G 0x40000000 +#define SZ_2G 0x80000000 + +#endif + +/* END */
diff --git a/x-loader/include/asm/string.h b/x-loader/include/asm/string.h new file mode 100644 index 0000000..c3ea582 --- /dev/null +++ b/x-loader/include/asm/string.h
@@ -0,0 +1,47 @@ +#ifndef __ASM_ARM_STRING_H +#define __ASM_ARM_STRING_H + +/* + * We don't do inline string functions, since the + * optimised inline asm versions are not small. + */ + +#undef __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#undef __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#undef __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +#undef __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +#if 0 +extern void __memzero(void *ptr, __kernel_size_t n); + +#define memset(p,v,n) \ + ({ \ + if ((n) != 0) { \ + if (__builtin_constant_p((v)) && (v) == 0) \ + __memzero((p),(n)); \ + else \ + memset((p),(v),(n)); \ + } \ + (p); \ + }) + +#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); }) +#else +extern void memzero(void *ptr, __kernel_size_t n); +#endif + +#endif
diff --git a/x-loader/include/asm/types.h b/x-loader/include/asm/types.h new file mode 100644 index 0000000..ba79923 --- /dev/null +++ b/x-loader/include/asm/types.h
@@ -0,0 +1,53 @@ +#ifndef __ASM_ARM_TYPES_H +#define __ASM_ARM_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +typedef unsigned long phys_addr_t; +typedef unsigned long phys_size_t; + +#endif /* __KERNEL__ */ + +#endif
diff --git a/x-loader/include/asm/x-load-arm.h b/x-loader/include/asm/x-load-arm.h new file mode 100644 index 0000000..eef268e --- /dev/null +++ b/x-loader/include/asm/x-load-arm.h
@@ -0,0 +1,40 @@ +/* + * (C) Copyright 2004 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.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 + */ + +#ifndef _X_LOAD_ARM_H_ +#define _X_LOAD_ARM_H_ 1 + +/* for the following variables, see start.S */ +extern ulong _armboot_start; /* code start */ +extern ulong _bss_start; /* code + data end == BSS start */ +extern ulong _bss_end; /* BSS end */ + +#endif /* _X_LOAD_ARM_H_ */
diff --git a/x-loader/include/bcd.h b/x-loader/include/bcd.h new file mode 100644 index 0000000..af4aa9c --- /dev/null +++ b/x-loader/include/bcd.h
@@ -0,0 +1,25 @@ +/* Permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ + +/* inline functions to translate to/from binary and binary-coded decimal + * (frequently found in RTC chips). + */ + +#ifndef _BCD_H +#define _BCD_H + +#include <linux/types.h> + +static inline unsigned int bcd2bin(u8 val) +{ + return ((val) & 0x0f) + ((val) >> 4) * 10; +} + +static inline u8 bin2bcd (unsigned int val) +{ + return (((val / 10) << 4) | (val % 10)); +} + +#endif /* _BCD_H */
diff --git a/x-loader/include/bootm.h b/x-loader/include/bootm.h new file mode 100644 index 0000000..705d259 --- /dev/null +++ b/x-loader/include/bootm.h
@@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010 Grant Erickson <marathon96@gmail.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 + */ + +#ifndef __BOOTM_H__ +#define __BOOTM_H__ + +#include "compiler.h" + +#include <image.h> + +#define BOOTM_STATUS_FAILURE 0 +#define BOOTM_STATUS_SUCCESS 1 + +#define BOOTM_INDEX_START 0 +#define BOOTM_INDEX_STOP -1 + +typedef struct boot_extent { + ulong start; + ulong size; +} boot_extent_t; + +typedef int (*device_load)(uint8_t *buffer, int *index); + +static inline int bootm_load_successful(int status) +{ + return (status == BOOTM_STATUS_SUCCESS); +} + +static inline int bootm_load_continue(int status, int index) +{ + return ((status != BOOTM_STATUS_SUCCESS) && (index != BOOTM_INDEX_STOP)); +} + +extern int bootm(const uint8_t *buffer); +extern int bootm_binary(const uint8_t *buffer); +#if defined(CONFIG_BOOTM_IMAGE) +extern int bootm_image(const image_header_t *image); +#endif + +#endif /* __BOOTM_H__ */
diff --git a/x-loader/include/command.h b/x-loader/include/command.h new file mode 100644 index 0000000..a2936ad --- /dev/null +++ b/x-loader/include/command.h
@@ -0,0 +1,107 @@ +/* + * (C) Copyright 2000 + * 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 + */ + +/* + * Definitions for Command Processor + */ +#ifndef __COMMAND_H +#define __COMMAND_H + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef __ASSEMBLY__ +/* + * Monitor Command Table + */ + +struct cmd_tbl_s { + char *name; /* Command Name */ + int maxargs; /* maximum number of arguments */ + int repeatable; /* autorepeat allowed? */ + /* Implementation function */ + int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); + char *usage; /* Usage message (short) */ +#ifdef CFG_LONGHELP + char *help; /* Help message (long) */ +#endif +#ifdef CONFIG_AUTO_COMPLETE + /* do auto completion on the arguments */ + int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]); +#endif +}; + +typedef struct cmd_tbl_s cmd_tbl_t; + +extern cmd_tbl_t __u_boot_cmd_start; +extern cmd_tbl_t __u_boot_cmd_end; + + +/* common/command.c */ +cmd_tbl_t *find_cmd(const char *cmd); + +#ifdef CONFIG_AUTO_COMPLETE +extern void install_auto_complete(void); +extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp); +#endif + +/* + * Monitor Command + * + * All commands use a common argument format: + * + * void function (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + */ + +typedef void command_t (cmd_tbl_t *, int, int, char *[]); + +#endif /* __ASSEMBLY__ */ + +/* + * Command Flags: + */ +#define CMD_FLAG_REPEAT 0x0001 /* repeat last command */ +#define CMD_FLAG_BOOTD 0x0002 /* command is from bootd */ + +/* + * Configurable monitor commands definitions have been moved + * to include/cmd_confdefs.h + */ + + +#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd"))) + +#ifdef CFG_LONGHELP + +#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \ +cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help} + +#else /* no long help info */ + +#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \ +cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage} + +#endif /* CFG_LONGHELP */ + +#endif /* __COMMAND_H */
diff --git a/x-loader/include/common.h b/x-loader/include/common.h new file mode 100644 index 0000000..7218ac8 --- /dev/null +++ b/x-loader/include/common.h
@@ -0,0 +1,212 @@ +/* + * (C) Copyright 2004 + * Texas Instruments + * + * (C) Copyright 2000-2009 + * 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 + */ + +#ifndef __COMMON_H_ +#define __COMMON_H_ 1 + +#undef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#ifndef __ASSEMBLY__ /* put C only stuff in this section */ + +typedef unsigned char uchar; +typedef volatile unsigned long vu_long; +typedef volatile unsigned short vu_short; +typedef volatile unsigned char vu_char; + +#include <config.h> +#include <linux/types.h> +#include <stdarg.h> + +#ifdef CONFIG_ARM +#define asmlinkage /* nothing */ +#endif + +#ifdef CONFIG_ARM +# include <asm/setup.h> +# include <asm/x-load-arm.h> /* ARM version to be fixed! */ +#endif /* CONFIG_ARM */ + +#ifdef CFG_PRINTF +#define printf(fmt,args...) serial_printf (fmt ,##args) +#define getc() serial_getc() +#else +#define printf(fmt,args...) +#define getc() ' ' +#endif /* CFG_PRINTF */ + +#define DUMP_REG(tag, reg, type, op, format) do { \ + register u32 _regvar = reg; \ + register type _datavar = op(_regvar); \ + printf(" %-30s @ 0x%08x = " #format "\n", \ + tag, _regvar, _datavar); \ +} while (0) + +#define DUMP_REGB(mnemonic) \ + DUMP_REG(#mnemonic, mnemonic, u8, __raw_readb, 0x%02x) + +#define DUMP_REGW(mnemonic) \ + DUMP_REG(#mnemonic, mnemonic, u16, __raw_readw, 0x%04x) + +#define DUMP_REGL(mnemonic) \ + DUMP_REG(#mnemonic, mnemonic, u32, __raw_readl, 0x%08x) + +#ifdef DEBUG +#define debug(fmt,args...) printf (fmt ,##args) +#define debugX(level,fmt,args...) if (DEBUG>=level) printf(fmt,##args); +#else +#define debug(fmt,args...) +#define debugX(level,fmt,args...) +#endif /* DEBUG */ + +#define error(fmt, args...) do { \ + printf("ERROR: " fmt "\nat %s:%d/%s()\n", \ + ##args, __FILE__, __LINE__, __func__); \ +} while (0) + +#ifndef BUG +#define BUG() do { \ + printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ + panic("BUG!"); \ +} while (0) +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) +#endif /* BUG */ + +/* + * General Purpose Utilities + */ +#define min(X, Y) \ + ({ typeof (X) __x = (X), __y = (Y); \ + (__x < __y) ? __x : __y; }) + +#define max(X, Y) \ + ({ typeof (X) __x = (X), __y = (Y); \ + (__x > __y) ? __x : __y; }) + +#define MIN(x, y) min(x, y) +#define MAX(x, y) max(x, y) + + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* */ +int display_options (void); +void print_size(unsigned long long, const char *); +int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen); + +/* board/$(BOARD)/$(BOARD).c */ +int board_init (void); +int nand_init (void); +int mmc_boot (unsigned char *buf); +void board_hang (void); +void do_usb(void); + + +/* cpu/$(CPU)/cpu.c */ +int cpu_init (void); +#ifdef CFG_UDELAY +void udelay (unsigned long usec); +#endif + +/* nand driver */ +#define NAND_CMD_READ0 0 +#define NAND_CMD_READ1 1 +#define NAND_CMD_READOOB 0x50 +#define NAND_CMD_STATUS 0x70 +#define NAND_CMD_READID 0x90 +#define NAND_CMD_RESET 0xff + +/* Extended Commands for Large page devices */ +#define NAND_CMD_READSTART 0x30 + +/* Return codes for nand reads */ +#define NAND_READ_SUCCESS 0 +#define NAND_READ_SKIPPED_BAD_BLOCK 1 +#define NAND_READ_ECC_FAILURE 2 + +int nand_chip(void); +int nand_read_block(uchar *buf, ulong block_addr); + +int onenand_chip(void); +int onenand_read_block(unsigned char *buf, ulong block); + + +#ifdef CFG_PRINTF + +/* serial driver */ +int serial_init (void); +void serial_setbrg (void); +void serial_putc (const char); +void serial_puts (const char *); +int serial_getc (void); +int serial_tstc (void); + +/* lib/printf.c */ +void serial_printf (const char *fmt, ...); +#endif + +/* lib/crc.c */ +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); + +/* lib/vsprintf.c */ + +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); + +/* lib/board.c */ +void hang (void) __attribute__ ((noreturn)); + +/* stdout */ +void puts(const char *s); + +/* + * Board-specific Platform code can reimplement show_boot_progress () if needed + */ +void show_boot_progress(int val); + +#endif /* __ASSEMBLY__ */ + +/* Put only stuff here that the assembler can digest */ + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define ROUND(a,b) (((a) + (b)) & ~((b) - 1)) +#define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d)) +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) + +#define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1) +#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) + +#endif /* __COMMON_H_ */
diff --git a/x-loader/include/compiler.h b/x-loader/include/compiler.h new file mode 100644 index 0000000..23f4b83 --- /dev/null +++ b/x-loader/include/compiler.h
@@ -0,0 +1,130 @@ +/* + * Keep all the ugly #ifdef for system stuff here + */ + +#ifndef __COMPILER_H__ +#define __COMPILER_H__ + +#include <stddef.h> + +#ifdef USE_HOSTCC + +#if defined(__BEOS__) || \ + defined(__NetBSD__) || \ + defined(__FreeBSD__) || \ + defined(__sun__) || \ + defined(__APPLE__) +# include <inttypes.h> +#elif defined(__linux__) || defined(__WIN32__) || defined(__MINGW32__) +# include <stdint.h> +#endif + +#include <errno.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#if !defined(__WIN32__) && !defined(__MINGW32__) +# include <sys/mman.h> +#endif + +/* Not all systems (like Windows) has this define, and yes + * we do replace/emulate mmap() on those systems ... + */ +#ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +#endif + +#include <fcntl.h> +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif + +#ifdef __linux__ +# include <endian.h> +# include <byteswap.h> +#elif defined(__MACH__) +# include <machine/endian.h> +typedef unsigned long ulong; +typedef unsigned int uint; +#endif + +typedef uint8_t __u8; +typedef uint16_t __u16; +typedef uint32_t __u32; +typedef unsigned int uint; + +#define uswap_16(x) \ + ((((x) & 0xff00) >> 8) | \ + (((x) & 0x00ff) << 8)) +#define uswap_32(x) \ + ((((x) & 0xff000000) >> 24) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24)) +#define _uswap_64(x, sfx) \ + ((((x) & 0xff00000000000000##sfx) >> 56) | \ + (((x) & 0x00ff000000000000##sfx) >> 40) | \ + (((x) & 0x0000ff0000000000##sfx) >> 24) | \ + (((x) & 0x000000ff00000000##sfx) >> 8) | \ + (((x) & 0x00000000ff000000##sfx) << 8) | \ + (((x) & 0x0000000000ff0000##sfx) << 24) | \ + (((x) & 0x000000000000ff00##sfx) << 40) | \ + (((x) & 0x00000000000000ff##sfx) << 56)) +#if defined(__GNUC__) +# define uswap_64(x) _uswap_64(x, ull) +#else +# define uswap_64(x) _uswap_64(x, ) +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define cpu_to_le16(x) (x) +# define cpu_to_le32(x) (x) +# define cpu_to_le64(x) (x) +# define le16_to_cpu(x) (x) +# define le32_to_cpu(x) (x) +# define le64_to_cpu(x) (x) +# define cpu_to_be16(x) uswap_16(x) +# define cpu_to_be32(x) uswap_32(x) +# define cpu_to_be64(x) uswap_64(x) +# define be16_to_cpu(x) uswap_16(x) +# define be32_to_cpu(x) uswap_32(x) +# define be64_to_cpu(x) uswap_64(x) +#else +# define cpu_to_le16(x) uswap_16(x) +# define cpu_to_le32(x) uswap_32(x) +# define cpu_to_le64(x) uswap_64(x) +# define le16_to_cpu(x) uswap_16(x) +# define le32_to_cpu(x) uswap_32(x) +# define le64_to_cpu(x) uswap_64(x) +# define cpu_to_be16(x) (x) +# define cpu_to_be32(x) (x) +# define cpu_to_be64(x) (x) +# define be16_to_cpu(x) (x) +# define be32_to_cpu(x) (x) +# define be64_to_cpu(x) (x) +#endif + +#else /* !USE_HOSTCC */ + +#include <linux/string.h> +#include <linux/types.h> +#include <asm/byteorder.h> + +/* Types for `void *' pointers. */ +#if __WORDSIZE == 64 +typedef unsigned long int uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif + +#endif + +/* compiler options */ +#define uninitialized_var(x) x = x + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#endif
diff --git a/x-loader/include/config_defaults.h b/x-loader/include/config_defaults.h new file mode 100644 index 0000000..c0f048a --- /dev/null +++ b/x-loader/include/config_defaults.h
@@ -0,0 +1,9 @@ +/* + * config_defaults.h - sane defaults for everyone + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _CONFIG_DEFAULTS_H_ +#define _CONFIG_DEFAULTS_H_ +#endif
diff --git a/x-loader/include/configs/am3517evm.h b/x-loader/include/configs/am3517evm.h new file mode 100644 index 0000000..4b6b926 --- /dev/null +++ b/x-loader/include/configs/am3517evm.h
@@ -0,0 +1,195 @@ +/* + * (C) Copyright 2009 + * Texas Instruments, <www.ti.com> + * Manikandan Pillai<mani.pillai@ti.com> + * X-Loader Configuation settings for the AM3517EVM board. + * + * Derived from /include/configs/omap3evm.h + * + * 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ + +#define CONFIG_AM3517EVM 1 /* working with AM3517 EVM */ +//#define CONFIG_AM3517TEB 1 /* working with AM3517 TEB */ + +/* Enable the below macro if MMC boot support is required */ +#define CONFIG_MMC 1 +#if defined(CONFIG_MMC) + #define CFG_CMD_MMC 1 + #define CFG_CMD_FAT 1 +#endif + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ + +#if (V_OSCK > 19200000) +#define V_SCLK (V_OSCK >> 1) +#else +#define V_SCLK V_OSCK +#endif + +//#define PRCM_CLK_CFG2_266MHZ 1 /* VDD2=1.15v - 133MHz DDR */ +#define PRCM_CLK_CFG2_332MHZ 1 /* VDD2=1.15v - 166MHz DDR */ +#define PRCM_PCLK_OPP2 1 /* ARM=381MHz - VDD1=1.20v */ + +# define NAND_BASE_ADR NAND_BASE /* NAND flash */ +# define ONENAND_BASE ONENAND_MAP /* OneNand flash */ + +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define ONENAND_ADDR ONENAND_BASE /* physical address of OneNAND at CS0*/ + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) +#define CFG_NS16550_COM3 OMAP34XX_UART3 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL3 3 /* UART1 on OMAP3EVM */ +#define CONFIG_CONS_INDEX 3 + +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80008000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ + +#define CFG_NAND_K9F1G08R0A /* Samsung 8-bit 128MB chip large page NAND chip*/ +#define NAND_16BIT + +/* NAND is partitioned: + * 0x00000000 - 0x0007FFFF Booting Image + * 0x00080000 - 0x0023FFFF U-Boot Image + * 0x00240000 - 0x0027FFFF U-Boot Env Data (X-loader doesn't care) + * 0x00280000 - 0x0077FFFF Kernel Image + * 0x00780000 - 0x08000000 depends on application + */ +#define NAND_UBOOT_START 0x0080000 /* Leaving first 4 blocks for x-load */ +#define NAND_UBOOT_END 0x0240000 /* Giving a space of 2 blocks = 256KB */ +#define NAND_BLOCK_SIZE 0x20000 + +#define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) + +#if defined (CONFIG_AM3517EVM) +#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) +#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) +#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) +#elif defined (CONFIG_AM3517TEB) +#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0xDC) +#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0xE0) +#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0xE4) +#endif + +#ifdef NAND_16BIT +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#else /* to support 8-bit NAND devices */ +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u8 *)GPMC_NAND_DATA_0); +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#endif + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +/*----------------------------------------------------------------------- + * Board oneNAND Info. + */ +#define CFG_SYNC_BURST_READ 1 + +/* OneNAND is partitioned: + * 0x0000000 - 0x0080000 X-Loader + * 0x0080000 - 0x0240000 U-boot Image + * 0x0240000 - 0x0280000 U-Boot Env Data (X-loader doesn't care) + * 0x0280000 - 0x0780000 Kernel Image + * 0x0780000 - 0x8000000 depends on application + */ + +#define ONENAND_START_BLOCK 4 +#define ONENAND_END_BLOCK 18 +#define ONENAND_PAGE_SIZE 2048 /* 2KB */ +#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ + +#endif /* __CONFIG_H */ +
diff --git a/x-loader/include/configs/diamond-usb-loader.h b/x-loader/include/configs/diamond-usb-loader.h new file mode 100644 index 0000000..d592741 --- /dev/null +++ b/x-loader/include/configs/diamond-usb-loader.h
@@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines the x-loader configuration settings for the + * Nest Learning Thermostat board. + * + * SDRAM Controller (SDRC): + * - Samsung K4X51163PI-FCG6 64 MiB DDR SDRAM + * + * General Purpose Memory Controller (GPMC): + * - Micron MT29F2G16ABDHC-ET 256 MiB SLC NAND Flash (Development) + * - Micron MT29F2G16ABBEAH4 256 MiB SLC NAND Flash (Non-development) + * - Samsung K9F4G08U0C 512 MiB SLC NAND Flash (Development) + * - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development) + * + * Multimedia Card (MMC) Interface: + * - Molex 500998-0900 Secure Digital (SD) Connector + * - TI WL1270 Wireless LAN (WLAN) Module + * + * Display Subsystem (DSS): + * - Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype) + * - Tianma TM025ZDZ01 (320 x 320) LCM (Production) + * + * Camera Image Signal Processor: + * - Unused + * + * UART Controller: + * - Channel 1: + * * Head Unit Serial Console + * + * - Channel 2: + * * ZigBee Wireless Module + * + * Multichannel Buffered Serial Port (McBSP): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * - Channel 4: + * - Channel 5: + * + * Multichannel Serial Peripheral Interface (McSPI): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * + * GPIO Controller: + * - Backplate Detect + * - ZigBee + */ + +#ifndef __DIAMOND_USB_LOADER_CONFIG_H +#define __DIAMOND_USB_LOADER_CONFIG_H + +#include "diamond.h" + +#define CONFIG_USB 1 + +#endif /* __DIAMOND_USB_LOADER_CONFIG_H */ +
diff --git a/x-loader/include/configs/diamond.h b/x-loader/include/configs/diamond.h new file mode 100644 index 0000000..d16fe12 --- /dev/null +++ b/x-loader/include/configs/diamond.h
@@ -0,0 +1,462 @@ +/* + * Copyright (c) 2010-2011 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines the x-loader configuration settings for the + * Nest Learning Thermostat board. + * + * The file was originally derived from omap3evm.h. + * + * SDRAM Controller (SDRC): + * - Samsung K4X51163PI-FCG6 64 MiB DDR SDRAM + * + * General Purpose Memory Controller (GPMC): + * - Micron MT29F2G16ABDHC-ET 256 MiB SLC NAND Flash (Development) + * - Micron MT29F2G16ABBEAH4 256 MiB SLC NAND Flash (Non-development) + * - Samsung K9F4G08U0C 512 MiB SLC NAND Flash (Development) + * - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development) + * + * Multimedia Card (MMC) Interface: + * - Molex 500998-0900 Secure Digital (SD) Connector + * - TI WL1270 Wireless LAN (WLAN) Module + * + * Display Subsystem (DSS): + * - Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype) + * - Tianma TM025ZDZ01 (320 x 320) LCM (Production) + * + * Camera Image Signal Processor: + * - Unused + * + * UART Controller: + * - Channel 1: + * * Head Unit Serial Console + * + * - Channel 2: + * * ZigBee Wireless Module + * + * Multichannel Buffered Serial Port (McBSP): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * - Channel 4: + * - Channel 5: + * + * Multichannel Serial Peripheral Interface (McSPI): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * + * GPIO Controller: + * - Backplate Detect + * - ZigBee + */ + +#ifndef __DIAMOND_CONFIG_H +#define __DIAMOND_CONFIG_H + +/* + * ARM Processor Architecture, Family and Product Configuration + */ +#define CONFIG_ARMCORTEXA8 1 +#define CONFIG_OMAP 1 +#define CONFIG_OMAP34XX 1 +#define CONFIG_OMAP3430 1 + +/* + * With the architecture, family and product configuration defined, + * include the appropriate CPU header file. + */ + +#include <asm/arch/cpu.h> + +/* + * Assert the board type(s) we are building for. + * + */ +#undef CONFIG_DIAMOND_BOARD_DEVELOPMENT +#undef CONFIG_DIAMOND_BOARD_PROTOTYPE +#undef CONFIG_DIAMOND_BOARD_EVT +#undef CONFIG_DIAMOND_BOARD_DVT +#undef CONFIG_DIAMOND_BOARD_PVT +#undef CONFIG_DIAMOND_BOARD_MP +#define CONFIG_DIAMOND_BOARD_MULTI 1 + +/* + * Enable serial console printf facility (consumes about 3.5 KiB) + */ +#define CFG_PRINTF + +/* + * CONFIG_BOOTM_IMAGE - This can be used to specify whether X-Loader + * supports booting from 'mkimage' u-boot image files rather than just + * raw, u-boot binaries. + * + * Enabling this adds support for attempting to boot from one or more + * images because it allows an image to be sanity-checked before + * attempting to boot it. + */ +#define CONFIG_BOOTM_IMAGE + +/* + * Display image information with timestamps + */ +#ifdef CONFIG_BOOTM_IMAGE +#define CONFIG_TIMESTAMP +#endif + +#if defined(CFG_PRINTF) +/* + * Use a printf buffer size of 256 B + */ +# define CFG_PBSIZE 256 + +/* + * Indicate that we want to use CFG_NS16550_COM1 (see below) at a baud + * rate of 115,200 bps for the serial console. + */ +# define CONFIG_CONS_INDEX 1 +# define CONFIG_BAUDRATE 115200 + +/* + * NS16550-compatible serial driver configuration + */ +# define CFG_NS16550 +# define CFG_NS16550_SERIAL +# define CFG_NS16550_REG_SIZE (-4) +# define CFG_NS16550_CLK (48000000) +# define CFG_NS16550_COM1 OMAP34XX_UART1 +#endif /* defined(CFG_PRINTF) */ + +/* + * Disable timer-based delay (consumes about 250 B) since this is only + * available at present on the ARM926EJS. + */ +#undef CFG_UDELAY + +/* + * The Nest Learning Thermostat development board has an SD/MMC + * connector, so enable support for it, which implicitly enables + * rudimentary support for MS-DOS (MBR) partitions and FAT file + * systems. + */ +#define CONFIG_MMC 1 + +#if defined(CONFIG_MMC) +# define CFG_CMD_MMC 1 +# define CFG_CMD_FAT 1 +#endif /* defined(CONFIG_MMC) */ + +/* + * Clock Configuration + * + * Choose PRCM Configuration 2 which subselects a L3 interconnect + * clock of 166 MHz for SDRAM. + */ + +#undef CFG_PRCM_DEBUG + +#define PRCM_CLK_CFG2_332MHZ 1 + +#define CONFIG_SYS_MPU_DPLL_300MHZ 1 +#undef CONFIG_SYS_MPU_DPLL_600MHZ + +#define CONFIG_SYS_CORE_DPLL_332MHZ 1 +#undef CONFIG_SYS_CORE_DPLL_200MHZ +#undef CONFIG_SYS_CORE_DPLL_400MHZ + +#define CFG_SDRAM_SIZE_MB 64 +#undef CFG_SDRAM_DEBUG + +/* + * The Nest Learning Thermostat may have one of three SDRAMs + * 1a)Samsung I-Die 64MB + * 32Mbx16 + * VDD=1.8V + * 6ns cycle time + * CL=3 + * + * 1b)Samsung K-Die 64MB + * 32Mbx16 + * VDD=1.8V + * 6ns cycle time + * CL=3 + * + * 2) Nanya NT6DM 64MB + * 32Mbx16 + * VDD=1.8V + * 6ns cycle time + * CL=3 + * + */ + +#undef CFG_SDRAM_SMG_K4X +#undef CFG_SDRAM_NYA_NTD6 +#define CFG_SDRAM_COMBINED +/* + * These values are based on the Samsung K4X51163PK-FGC6 datasheet + * (applicable to the I-die and the K-die) and the TI spreadsheet + * at http://processors.wiki.ti.com/index.php?title= + * Setting_up_AM37x_SDRC_registers. + */ +#if defined(CFG_SDRAM_SMG_K4X) +#define CFG_SDRC_ACTIM_CTRLA_TRFC 12 +#define CFG_SDRC_ACTIM_CTRLA_TRC 10 +#define CFG_SDRC_ACTIM_CTRLA_TRAS 7 +#define CFG_SDRC_ACTIM_CTRLA_TRP 3 +#define CFG_SDRC_ACTIM_CTRLA_TRCD 3 +#define CFG_SDRC_ACTIM_CTRLA_TRRD 2 +#define CFG_SDRC_ACTIM_CTRLA_TDPL 2 +#define CFG_SDRC_ACTIM_CTRLA_TDAL 5 + +#define CFG_SDRC_ACTIM_CTRLB_TWTR 1 +#define CFG_SDRC_ACTIM_CTRLB_TCKE 2 +#define CFG_SDRC_ACTIM_CTRLB_TXP 1 +#define CFG_SDRC_ACTIM_CTRLB_TXSR 20 +#endif + +/* + * These values are based on the Nanya NT6DM datasheet and the TI + * spreadsheet at http://processors.wiki.ti.com/index.php?title= + * Setting_up_AM37x_SDRC_registers. + */ +#if defined(CFG_SDRAM_NYA_NTD6) +#define CFG_SDRC_ACTIM_CTRLA_TRFC 12 +#define CFG_SDRC_ACTIM_CTRLA_TRC 10 +#define CFG_SDRC_ACTIM_CTRLA_TRAS 7 +#define CFG_SDRC_ACTIM_CTRLA_TRP 3 +#define CFG_SDRC_ACTIM_CTRLA_TRCD 3 +#define CFG_SDRC_ACTIM_CTRLA_TRRD 2 +#define CFG_SDRC_ACTIM_CTRLA_TDPL 3 +#define CFG_SDRC_ACTIM_CTRLA_TDAL 6 + +#define CFG_SDRC_ACTIM_CTRLB_TWTR 1 +#define CFG_SDRC_ACTIM_CTRLB_TCKE 1 +#define CFG_SDRC_ACTIM_CTRLB_TXP 1 +#define CFG_SDRC_ACTIM_CTRLB_TXSR 19 +#endif + + +#if defined(CFG_SDRAM_COMBINED) +#define CFG_SDRC_ACTIM_CTRLA_TRFC 12 +#define CFG_SDRC_ACTIM_CTRLA_TRC 10 +#define CFG_SDRC_ACTIM_CTRLA_TRAS 7 +#define CFG_SDRC_ACTIM_CTRLA_TRP 3 +#define CFG_SDRC_ACTIM_CTRLA_TRCD 3 +#define CFG_SDRC_ACTIM_CTRLA_TRRD 2 +#define CFG_SDRC_ACTIM_CTRLA_TDPL 3 +#define CFG_SDRC_ACTIM_CTRLA_TDAL 6 + +#define CFG_SDRC_ACTIM_CTRLB_TWTR 1 +#define CFG_SDRC_ACTIM_CTRLB_TCKE 2 +#define CFG_SDRC_ACTIM_CTRLB_TXP 1 +#define CFG_SDRC_ACTIM_CTRLB_TXSR 20 +#endif + + + +/* + * NAND Configuration + * + * The Nest Learning Thermostat board may have two NAND devices: + * + * 1a) Micron MT29F2G16ABDHC-ET @ GPMC CS0 + * + * - 2 Gb x 16 (256 MiB) + * - 2 KiB page size + * - 128 KiB erase size + * - 1.8V + * - SLC + * - 1-bit ECC + * + * 1b) Micron MT29F2G16ABBEAH4 @ GPMC CS0 + * + * - 2 Gb x 16 (256 MiB) + * - 2 KiB page size + * - 128 KiB erase size + * - 1.8V + * - SLC + * - 4-bit ECC + * + * 2) Samsung K9F4G08U0C @ GPMC CS3 + * + * - 4 Gb x 8 (512 MiB) + * - 2 KiB page size + * - 128 KiB erase size + * - 3.3V + * - SLC + */ + +#define CFG_GPMC_NAND +#define CFG_MMC_NAND +#undef CFG_GPMC_ONENAND +#undef CFG_MMC_ONENAND + +#undef CFG_GPMC_DEBUG + +#undef CFG_NAND_K9F4G08U0C // Samsung K9F4G08U0C +#define CFG_NAND_MT29F2G16 // Micron MT29F2G16 + +#undef CFG_NAND_ECC_1BIT +#define CFG_NAND_ECC_4BIT 1 +#undef CFG_NAND_ECC_8BIT + +#define CFG_GPMC_NAND_BASE NAND_BASE +#define CFG_GPMC_NAND_SIZE GPMC_SIZE_128M + +#if defined(CFG_NAND_MT29F2G16) +#define CFG_GPMC_CONFIG1_0 M_NAND_GPMC_CONFIG1 +#define CFG_GPMC_CONFIG2_0 M_NAND_GPMC_CONFIG2 +#define CFG_GPMC_CONFIG3_0 M_NAND_GPMC_CONFIG3 +#define CFG_GPMC_CONFIG4_0 M_NAND_GPMC_CONFIG4 +#define CFG_GPMC_CONFIG5_0 M_NAND_GPMC_CONFIG5 +#define CFG_GPMC_CONFIG6_0 M_NAND_GPMC_CONFIG6 +#define CFG_GPMC_CONFIG7_0 \ + (GPMC_CONFIG7_MASKADDRESS_ENCODE(CFG_GPMC_NAND_SIZE) | \ + GPMC_CONFIG7_BASEADDRESS_ENCODE(CFG_GPMC_NAND_BASE)) +#endif /* defined(CFG_NAND_MT29F2G16) */ + +#if defined(CFG_NAND_K9F4G08U0C) +#define CFG_GPMC_CONFIG1_3 M_NAND_GPMC_CONFIG1 //SMNAND_GPMC_CONFIG1 +#define CFG_GPMC_CONFIG2_3 M_NAND_GPMC_CONFIG2 //SMNAND_GPMC_CONFIG2 +#define CFG_GPMC_CONFIG3_3 M_NAND_GPMC_CONFIG3 //SMNAND_GPMC_CONFIG3 +#define CFG_GPMC_CONFIG4_3 M_NAND_GPMC_CONFIG4 //SMNAND_GPMC_CONFIG4 +#define CFG_GPMC_CONFIG5_3 M_NAND_GPMC_CONFIG5 //SMNAND_GPMC_CONFIG5 +#define CFG_GPMC_CONFIG6_3 M_NAND_GPMC_CONFIG6 //SMNAND_GPMC_CONFIG6 +#define CFG_GPMC_CONFIG7_3 \ + (GPMC_CONFIG7_MASKADDRESS_ENCODE(CFG_GPMC_NAND_SIZE) | \ + GPMC_CONFIG7_BASEADDRESS_ENCODE(CFG_GPMC_NAND_BASE)) +#endif /* defined(CFG_NAND_K9F4G08U0C) */ + +/* + * Architecture, processor and/or board-specific NAND access macros + * and driver parameters. + */ + +#if defined(CFG_NAND_MT29F2G16) +# define NAND_16BIT +# define NAND_BLOCK_SIZE (128 << 10) +#elif defined(CFG_NAND_K9F4G08U0C) +# undef NAND_16BIT +# define NAND_BLOCK_SIZE (128 << 10) +#endif /* defined(CFG_NAND_MT29F2G16) */ + +#ifdef NAND_16BIT +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= GPMC_WRITEPROTECT_HIGH;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~GPMC_WRITEPROTECT_HIGH;} while(0) + +#else /* to support 8-bit NAND devices */ +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u8 *)GPMC_NAND_DATA_0); +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= GPMC_WRITEPROTECT_HIGH;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~GPMC_WRITEPROTECT_HIGH;} while(0) +#endif /* NAND_16BIT */ + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +/* + * Location where we expect to find the second-stage boot loader in + * the boot NAND device. + * + * ------------------------------------------------------------------------ + * Offsets + * --------------------------- + * Alias Description Size Blocks Block Address Size + * ======================================================================== + * ipl X-Loader Image 256 KiB 2 0 0x00000000 0 B + * ------------------------------------------------------------------------ + * spl0 Primary U-Boot Image 1.5 MiB 12 2 0x00040000 256 KiB + * ------------------------------------------------------------------------ + * spl1 Reserved for Future 1.5 MiB 12 14 0x001C0000 1.75 MiB + * Secondary U-Boot + * Image + * ======================================================================== + * + */ + +#define CFG_NAND_BOOTEXTENT0_START 0x00040000 +#define CFG_NAND_BOOTEXTENT1_START 0x001C0000 +#define CFG_NAND_BOOTEXTENT_SIZE 0x180000 + +#ifdef CONFIG_BOOTM_IMAGE +#define CONFIG_NAND_BOOTEXTENT_LIST { { CFG_NAND_BOOTEXTENT0_START, \ + CFG_NAND_BOOTEXTENT_SIZE }, \ + { CFG_NAND_BOOTEXTENT1_START, \ + CFG_NAND_BOOTEXTENT_SIZE } } +#else +#define CONFIG_NAND_BOOTEXTENT { CFG_NAND_BOOTEXTENT0_START, \ + CFG_NAND_BOOTEXTENT_SIZE } +#endif + +/* + * Miscellaneous configurable options + */ + +/* + * CONFIG_BOOTFILE - This can be used to set a default value for the + * second-stage boot file loaded from SD card if the system has been + * configured to boot as such. + * + * CONFIG_BOOTFILE_LIST - This can be used to a list of default values + * for the second-stage boot file loaded from SD card if the system has been + * configured to boot as such. + * + * Try to boot an 'mkimage' u-boot image first; otherwise, try to boot a + * raw u-boot binary if it exists as a fallback. + */ +#ifdef CONFIG_BOOTM_IMAGE +#define CONFIG_BOOTFILE_LIST { "u-boot.img", "u-boot.bin" } +#else +#define CONFIG_BOOTFILE "u-boot.img" +#endif + +/* + * Location in SDRAM where the second-stage boot loader will be loaded + * to and executed from. + */ +#define CFG_LOADADDR 0x80008000 + +#endif /* __DIAMOND_CONFIG_H */ +
diff --git a/x-loader/include/configs/j49-usb-loader.h b/x-loader/include/configs/j49-usb-loader.h new file mode 100644 index 0000000..4314c7b --- /dev/null +++ b/x-loader/include/configs/j49-usb-loader.h
@@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines the x-loader configuration settings for the + * Nest Learning Thermostat J49 board. The items below should + * be updated as the hardware settles. + * + * SDRAM Controller (SDRC): + * - Samsung K4X51163PI-FCG6 64 MiB DDR SDRAM + * + * General Purpose Memory Controller (GPMC): + * - Micron MT29F2G16ABDHC-ET 256 MiB SLC NAND Flash (Development) + * - Micron MT29F2G16ABBEAH4 256 MiB SLC NAND Flash (Non-development) + * - Samsung K9F4G08U0C 512 MiB SLC NAND Flash (Development) + * - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development) + * + * Multimedia Card (MMC) Interface: + * - Molex 500998-0900 Secure Digital (SD) Connector + * - TI WL1270 Wireless LAN (WLAN) Module + * + * Display Subsystem (DSS): + * - Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype) + * - Tianma TM025ZDZ01 (320 x 320) LCM (Production) + * + * Camera Image Signal Processor: + * - Unused + * + * UART Controller: + * - Channel 1: + * * Head Unit Serial Console + * + * - Channel 2: + * * ZigBee Wireless Module + * + * Multichannel Buffered Serial Port (McBSP): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * - Channel 4: + * - Channel 5: + * + * Multichannel Serial Peripheral Interface (McSPI): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * + * GPIO Controller: + * - Backplate Detect + * - ZigBee + */ + +#ifndef __J49_CONFIG_H +#define __J49_CONFIG_H + +#include "diamond.h" + +/* + * Assert the board type(s) we are building for. + * + */ +#undef CONFIG_J49_BOARD_PROTOTYPE +#undef CONFIG_J49_BOARD_EVT +#undef CONFIG_J49_BOARD_DVT +#undef CONFIG_J49_BOARD_PRE_PVT +#define CONFIG_J49_BOARD_MULTI 1 + +#define CONFIG_USB 1 + +#endif /* __J49_CONFIG_H */ +
diff --git a/x-loader/include/configs/j49.h b/x-loader/include/configs/j49.h new file mode 100644 index 0000000..68658dc --- /dev/null +++ b/x-loader/include/configs/j49.h
@@ -0,0 +1,87 @@ +/* + * Copyright (c) 2012 Nest Labs, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Description: + * This file defines the x-loader configuration settings for the + * Nest Learning Thermostat J49 board. The items below should + * be updated as the hardware settles. + * + * SDRAM Controller (SDRC): + * - Samsung K4X51163PI-FCG6 64 MiB DDR SDRAM + * + * General Purpose Memory Controller (GPMC): + * - Micron MT29F2G16ABDHC-ET 256 MiB SLC NAND Flash (Development) + * - Micron MT29F2G16ABBEAH4 256 MiB SLC NAND Flash (Non-development) + * - Samsung K9F4G08U0C 512 MiB SLC NAND Flash (Development) + * - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development) + * + * Multimedia Card (MMC) Interface: + * - Molex 500998-0900 Secure Digital (SD) Connector + * - TI WL1270 Wireless LAN (WLAN) Module + * + * Display Subsystem (DSS): + * - Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype) + * - Tianma TM025ZDZ01 (320 x 320) LCM (Production) + * + * Camera Image Signal Processor: + * - Unused + * + * UART Controller: + * - Channel 1: + * * Head Unit Serial Console + * + * - Channel 2: + * * ZigBee Wireless Module + * + * Multichannel Buffered Serial Port (McBSP): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * - Channel 4: + * - Channel 5: + * + * Multichannel Serial Peripheral Interface (McSPI): + * - Channel 1: + * - Channel 2: + * - Channel 3: + * + * GPIO Controller: + * - Backplate Detect + * - ZigBee + */ + +#ifndef __J49_CONFIG_H +#define __J49_CONFIG_H + +#include "diamond.h" + +/* + * Assert the board type(s) we are building for. + * + */ +#undef CONFIG_J49_BOARD_PROTOTYPE +#undef CONFIG_J49_BOARD_EVT +#undef CONFIG_J49_BOARD_DVT +#undef CONFIG_J49_BOARD_PRE_PVT +#define CONFIG_J49_BOARD_MULTI 1 + +#endif /* __J49_CONFIG_H */ +
diff --git a/x-loader/include/configs/omap1510.h b/x-loader/include/configs/omap1510.h new file mode 100644 index 0000000..40deace --- /dev/null +++ b/x-loader/include/configs/omap1510.h
@@ -0,0 +1,698 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * OMAP hardware map + * + * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com) + * Author: RidgeRun, Inc. + * Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <asm/arch/sizes.h> + +/* + There are 2 sets of general I/O --> + 1. GPIO (shared between ARM & DSP, configured by ARM) + 2. MPUIO which can be used only by the ARM. + + Base address FFFB:5000 is where the ARM accesses the MPUIO control registers + (see 7.2.2 of the TRM for MPUIO reg definitions). + + Base address E101:5000 is reserved for ARM access of the same MPUIO control + regs, but via the DSP I/O map. This address is unavailable on 1510. + + Base address FFFC:E000 is where the ARM accesses the GPIO config registers + directly via its own peripheral bus. + + Base address E101:E000 is where the ARM can access the same GPIO config + registers, but the access takes place through the ARM port interface (called + API or MPUI) via the DSP's peripheral bus (DSP I/O space). + + Therefore, the ARM should setup the GPIO regs thru the FFFC:E000 addresses + instead of the E101:E000 addresses. The DSP has only read access of the pin + control register, so this may explain the inability to write to E101:E018. + Try accessing pin control reg at FFFC:E018. + */ +#define OMAP1510_GPIO_BASE 0xfffce000 +#define OMAP1510_GPIO_START OMAP1510_GPIO_BASE +#define OMAP1510_GPIO_SIZE SZ_4K + +#define OMAP1510_MCBSP1_BASE 0xE1011000 +#define OMAP1510_MCBSP1_SIZE SZ_4K +#define OMAP1510_MCBSP1_START 0xE1011000 + +#define OMAP1510_MCBSP2_BASE 0xFFFB1000 + +#define OMAP1510_MCBSP3_BASE 0xE1017000 +#define OMAP1510_MCBSP3_SIZE SZ_4K +#define OMAP1510_MCBSP3_START 0xE1017000 + +/* + * Where's the flush address (for flushing D and I cache?) + */ +#define FLUSH_BASE 0xdf000000 +#define FLUSH_BASE_PHYS 0x00000000 + +#ifndef __ASSEMBLER__ + +#define PCIO_BASE 0 + +/* + * RAM definitions + */ +#define MAPTOPHYS(a) ((unsigned long)(a) - PAGE_OFFSET) +#define KERNTOPHYS(a) ((unsigned long)(&a)) +#define KERNEL_BASE (0x10008000) +#endif + +/* macro to get at IO space when running virtually */ +#define IO_ADDRESS(x) ((x)) + +/* ---------------------------------------------------------------------------- + * OMAP1510 system registers + * ---------------------------------------------------------------------------- + */ + +#define OMAP1510_UART1_BASE 0xfffb0000 /* "BLUETOOTH-UART" */ +#define OMAP1510_UART2_BASE 0xfffb0800 /* "MODEM-UART" */ +#define OMAP1510_RTC_BASE 0xfffb4800 /* RTC */ +#define OMAP1510_UART3_BASE 0xfffb9800 /* Shared MPU/DSP UART */ +#define OMAP1510_COM_MCBSP2_BASE 0xffff1000 /* Com McBSP2 */ +#define OMAP1510_AUDIO_MCBSP_BASE 0xffff1800 /* Audio McBSP2 */ +#define OMAP1510_ARMIO_BASE 0xfffb5000 /* keyboard/gpio */ + +/* + * OMAP1510 UART3 Registers + */ + +#define OMAP_MPU_UART3_BASE 0xFFFB9800 /* UART3 through MPU bus */ + +/* UART3 Registers Maping through MPU bus */ + +#define UART3_RHR (OMAP_MPU_UART3_BASE + 0) +#define UART3_THR (OMAP_MPU_UART3_BASE + 0) +#define UART3_DLL (OMAP_MPU_UART3_BASE + 0) +#define UART3_IER (OMAP_MPU_UART3_BASE + 4) +#define UART3_DLH (OMAP_MPU_UART3_BASE + 4) +#define UART3_IIR (OMAP_MPU_UART3_BASE + 8) +#define UART3_FCR (OMAP_MPU_UART3_BASE + 8) +#define UART3_EFR (OMAP_MPU_UART3_BASE + 8) +#define UART3_LCR (OMAP_MPU_UART3_BASE + 0x0C) +#define UART3_MCR (OMAP_MPU_UART3_BASE + 0x10) +#define UART3_XON1_ADDR1 (OMAP_MPU_UART3_BASE + 0x10) +#define UART3_XON2_ADDR2 (OMAP_MPU_UART3_BASE + 0x14) +#define UART3_LSR (OMAP_MPU_UART3_BASE + 0x14) +#define UART3_TCR (OMAP_MPU_UART3_BASE + 0x18) +#define UART3_MSR (OMAP_MPU_UART3_BASE + 0x18) +#define UART3_XOFF1 (OMAP_MPU_UART3_BASE + 0x18) +#define UART3_XOFF2 (OMAP_MPU_UART3_BASE + 0x1C) +#define UART3_SPR (OMAP_MPU_UART3_BASE + 0x1C) +#define UART3_TLR (OMAP_MPU_UART3_BASE + 0x1C) +#define UART3_MDR1 (OMAP_MPU_UART3_BASE + 0x20) +#define UART3_MDR2 (OMAP_MPU_UART3_BASE + 0x24) +#define UART3_SFLSR (OMAP_MPU_UART3_BASE + 0x28) +#define UART3_TXFLL (OMAP_MPU_UART3_BASE + 0x28) +#define UART3_RESUME (OMAP_MPU_UART3_BASE + 0x2C) +#define UART3_TXFLH (OMAP_MPU_UART3_BASE + 0x2C) +#define UART3_SFREGL (OMAP_MPU_UART3_BASE + 0x30) +#define UART3_RXFLL (OMAP_MPU_UART3_BASE + 0x30) +#define UART3_SFREGH (OMAP_MPU_UART3_BASE + 0x34) +#define UART3_RXFLH (OMAP_MPU_UART3_BASE + 0x34) +#define UART3_BLR (OMAP_MPU_UART3_BASE + 0x38) +#define UART3_ACREG (OMAP_MPU_UART3_BASE + 0x3C) +#define UART3_DIV16 (OMAP_MPU_UART3_BASE + 0x3C) +#define UART3_SCR (OMAP_MPU_UART3_BASE + 0x40) +#define UART3_SSR (OMAP_MPU_UART3_BASE + 0x44) +#define UART3_EBLR (OMAP_MPU_UART3_BASE + 0x48) +#define UART3_OSC_12M_SEL (OMAP_MPU_UART3_BASE + 0x4C) +#define UART3_MVR (OMAP_MPU_UART3_BASE + 0x50) + +/* + * Configuration Registers + */ +#define FUNC_MUX_CTRL_0 0xfffe1000 +#define FUNC_MUX_CTRL_1 0xfffe1004 +#define FUNC_MUX_CTRL_2 0xfffe1008 +#define COMP_MODE_CTRL_0 0xfffe100c +#define FUNC_MUX_CTRL_3 0xfffe1010 +#define FUNC_MUX_CTRL_4 0xfffe1014 +#define FUNC_MUX_CTRL_5 0xfffe1018 +#define FUNC_MUX_CTRL_6 0xfffe101C +#define FUNC_MUX_CTRL_7 0xfffe1020 +#define FUNC_MUX_CTRL_8 0xfffe1024 +#define FUNC_MUX_CTRL_9 0xfffe1028 +#define FUNC_MUX_CTRL_A 0xfffe102C +#define FUNC_MUX_CTRL_B 0xfffe1030 +#define FUNC_MUX_CTRL_C 0xfffe1034 +#define FUNC_MUX_CTRL_D 0xfffe1038 +#define PULL_DWN_CTRL_0 0xfffe1040 +#define PULL_DWN_CTRL_1 0xfffe1044 +#define PULL_DWN_CTRL_2 0xfffe1048 +#define PULL_DWN_CTRL_3 0xfffe104c +#define GATE_INH_CTRL_0 0xfffe1050 +#define VOLTAGE_CTRL_0 0xfffe1060 +#define TEST_DBG_CTRL_0 0xfffe1070 + +#define MOD_CONF_CTRL_0 0xfffe1080 + +/* 1610 Configuration Register */ +#if defined(CONFIG_OMAP1610) || defined(CONFIG_OMAP1710) +#define USB_OTG_CTRL 0xFFFB040C +#define USB_TRANSCEIVER_CTRL 0xFFFE1064 +#define PULL_DWN_CTRL_4 0xFFFE10AC +#define PU_PD_SEL_0 0xFFFE10B4 +#define PU_PD_SEL_1 0xFFFE10B8 +#define PU_PD_SEL_2 0xFFFE10BC +#define PU_PD_SEL_3 0xFFFE10C0 +#define PU_PD_SEL_4 0xFFFE10C4 + +#endif +/* + * Traffic Controller Memory Interface Registers + */ +#define TCMIF_BASE 0xfffecc00 +#define IMIF_PRIO (TCMIF_BASE + 0x00) +#define EMIFS_PRIO_REG (TCMIF_BASE + 0x04) +#define EMIFF_PRIO_REG (TCMIF_BASE + 0x08) +#define EMIFS_CONFIG_REG (TCMIF_BASE + 0x0c) +#define EMIFS_CS0_CONFIG (TCMIF_BASE + 0x10) +#define EMIFS_CS1_CONFIG (TCMIF_BASE + 0x14) +#define EMIFS_CS2_CONFIG (TCMIF_BASE + 0x18) +#define EMIFS_CS3_CONFIG (TCMIF_BASE + 0x1c) +#define EMIFF_SDRAM_CONFIG (TCMIF_BASE + 0x20) +#define EMIFF_MRS (TCMIF_BASE + 0x24) +#define TC_TIMEOUT1 (TCMIF_BASE + 0x28) +#define TC_TIMEOUT2 (TCMIF_BASE + 0x2c) +#define TC_TIMEOUT3 (TCMIF_BASE + 0x30) +#define TC_ENDIANISM (TCMIF_BASE + 0x34) +#define EMIFF_SDRAM_CONFIG_2 (TCMIF_BASE + 0x3c) +#define EMIF_CFG_DYNAMIC_WS (TCMIF_BASE + 0x40) + +/* + * LCD Panel + */ +#define TI925_LCD_BASE 0xFFFEC000 +#define TI925_LCD_CONTROL (TI925_LCD_BASE) +#define TI925_LCD_TIMING0 (TI925_LCD_BASE+0x4) +#define TI925_LCD_TIMING1 (TI925_LCD_BASE+0x8) +#define TI925_LCD_TIMING2 (TI925_LCD_BASE+0xc) +#define TI925_LCD_STATUS (TI925_LCD_BASE+0x10) +#define TI925_LCD_SUBPANEL (TI925_LCD_BASE+0x14) + +#define OMAP_LCD_CONTROL TI925_LCD_CONTROL + +/* + * MMC/SD Host Controller Registers + */ + +#define OMAP_MMC_CMD 0xFFFB7800 /* MMC Command */ +#define OMAP_MMC_ARGL 0xFFFB7804 /* MMC argument low */ +#define OMAP_MMC_ARGH 0xFFFB7808 /* MMC argument high */ +#define OMAP_MMC_CON 0xFFFB780C /* MMC system configuration */ +#define OMAP_MMC_STAT 0xFFFB7810 /* MMC status */ +#define OMAP_MMC_IE 0xFFFB7814 /* MMC system interrupt enable */ +#define OMAP_MMC_CTO 0xFFFB7818 /* MMC command time-out */ +#define OMAP_MMC_DTO 0xFFFB781C /* MMC data time-out */ +#define OMAP_MMC_DATA 0xFFFB7820 /* MMC TX/RX FIFO data */ +#define OMAP_MMC_BLEN 0xFFFB7824 /* MMC block length */ +#define OMAP_MMC_NBLK 0xFFFB7828 /* MMC number of blocks */ +#define OMAP_MMC_BUF 0xFFFB782C /* MMC buffer configuration */ +#define OMAP_MMC_SPI 0xFFFB7830 /* MMC serial port interface */ +#define OMAP_MMC_SDIO 0xFFFB7834 /* MMC SDIO mode configuration */ +#define OMAP_MMC_SYST 0xFFFB7838 /* MMC system test */ +#define OMAP_MMC_REV 0xFFFB783C /* MMC module version */ +#define OMAP_MMC_RSP0 0xFFFB7840 /* MMC command response 0 */ +#define OMAP_MMC_RSP1 0xFFFB7844 /* MMC command response 1 */ +#define OMAP_MMC_RSP2 0xFFFB7848 /* MMC command response 2 */ +#define OMAP_MMC_RSP3 0xFFFB784C /* MMC command response 3 */ +#define OMAP_MMC_RSP4 0xFFFB7850 /* MMC command response 4 */ +#define OMAP_MMC_RSP5 0xFFFB7854 /* MMC command response 5 */ +#define OMAP_MMC_RSP6 0xFFFB7858 /* MMC command response 6 */ +#define OMAP_MMC_RSP7 0xFFFB785C /* MMC command response 4 */ + +/* MMC masks */ + +#define OMAP_MMC_END_OF_CMD (1 << 0) /* End of command phase */ +#define OMAP_MMC_CARD_BUSY (1 << 2) /* Card enter busy state */ +#define OMAP_MMC_BLOCK_RS (1 << 3) /* Block received/sent */ +#define OMAP_MMC_EOF_BUSY (1 << 4) /* Card exit busy state */ +#define OMAP_MMC_DATA_TIMEOUT (1 << 5) /* Data response time-out */ +#define OMAP_MMC_DATA_CRC (1 << 6) /* Date CRC error */ +#define OMAP_MMC_CMD_TIMEOUT (1 << 7) /* Command response time-out */ +#define OMAP_MMC_CMD_CRC (1 << 8) /* Command CRC error */ +#define OMAP_MMC_A_FULL (1 << 10) /* Buffer almost full */ +#define OMAP_MMC_A_EMPTY (1 << 11) /* Buffer almost empty */ +#define OMAP_MMC_OCR_BUSY (1 << 12) /* OCR busy */ +#define OMAP_MMC_CARD_IRQ (1 << 13) /* Card IRQ received */ +#define OMAP_MMC_CARD_ERR (1 << 14) /* Card status error in response */ + +/* 2.9.2 MPUI Interface Registers FFFE:C900 */ + +#define MPUI_CTRL_REG (volatile __u32 *)(0xfffec900) +#define MPUI_DEBUG_ADDR (volatile __u32 *)(0xfffec904) +#define MPUI_DEBUG_DATA (volatile __u32 *)(0xfffec908) +#define MPUI_DEBUG_FLAG (volatile __u16 *)(0xfffec90c) +#define MPUI_STATUS_REG (volatile __u16 *)(0xfffec910) +#define MPUI_DSP_STATUS_REG (volatile __u16 *)(0xfffec914) +#define MPUI_DSP_BOOT_CONFIG (volatile __u16 *)(0xfffec918) +#define MPUI_DSP_API_CONFIG (volatile __u16 *)(0xfffec91c) + +/* 2.9.6 Traffic Controller Memory Interface Registers: */ +#define OMAP_IMIF_PRIO_REG 0xfffecc00 +#define OMAP_EMIFS_PRIO_REG 0xfffecc04 +#define OMAP_EMIFF_PRIO_REG 0xfffecc08 +#define OMAP_EMIFS_CONFIG_REG 0xfffecc0c +#define OMAP_EMIFS_CS0_CONFIG 0xfffecc10 +#define OMAP_EMIFS_CS1_CONFIG 0xfffecc14 +#define OMAP_EMIFS_CS2_CONFIG 0xfffecc18 +#define OMAP_EMIFS_CS3_CONFIG 0xfffecc1c +#define OMAP_EMIFF_SDRAM_CONFIG 0xfffecc20 +#define OMAP_EMIFF_MRS 0xfffecc24 +#define OMAP_TIMEOUT1 0xfffecc28 +#define OMAP_TIMEOUT2 0xfffecc2c +#define OMAP_TIMEOUT3 0xfffecc30 +#define OMAP_ENDIANISM 0xfffecc34 + +/* 2.9.10 EMIF Slow Interface Configuration Register (EMIFS_CONFIG_REG): */ +#define OMAP_EMIFS_CONFIG_FR (1 << 4) +#define OMAP_EMIFS_CONFIG_PDE (1 << 3) +#define OMAP_EMIFS_CONFIG_PWD_EN (1 << 2) +#define OMAP_EMIFS_CONFIG_BM (1 << 1) +#define OMAP_EMIFS_CONFIG_WP (1 << 0) + +/* + * Memory chunk set aside for the Framebuffer in SRAM + */ +#define SRAM_FRAMEBUFFER_MEMORY OMAP1510_SRAM_BASE + + +/* + * DMA + */ + +#define OMAP1510_DMA_BASE 0xFFFED800 +#define OMAP_DMA_BASE OMAP1510_DMA_BASE + +/* Global Register selection */ +#define NO_GLOBAL_DMA_ACCESS 0 + +/* Channel select field + * NOTE: all other channels are linear, chan0 is 0, chan1 is 1, etc... + */ +#define LCD_CHANNEL 0xc + +/* Register Select Field (LCD) */ +#define DMA_LCD_CTRL 0 +#define DMA_LCD_TOP_F1_L 1 +#define DMA_LCD_TOP_F1_U 2 +#define DMA_LCD_BOT_F1_L 3 +#define DMA_LCD_BOT_F1_U 4 + +#define LCD_FRAME_MODE (1<<0) +#define LCD_FRAME_IT_IE (1<<1) +#define LCD_BUS_ERROR_IT_IE (1<<2) +#define LCD_FRAME_1_IT_COND (1<<3) +#define LCD_FRAME_2_IT_COND (1<<4) +#define LCD_BUS_ERROR_IT_COND (1<<5) +#define LCD_SOURCE_IMIF (1<<6) + +/* + * Real-Time Clock + */ + +#define RTC_SECONDS (volatile __u8 *)(OMAP1510_RTC_BASE + 0x00) +#define RTC_MINUTES (volatile __u8 *)(OMAP1510_RTC_BASE + 0x04) +#define RTC_HOURS (volatile __u8 *)(OMAP1510_RTC_BASE + 0x08) +#define RTC_DAYS (volatile __u8 *)(OMAP1510_RTC_BASE + 0x0C) +#define RTC_MONTHS (volatile __u8 *)(OMAP1510_RTC_BASE + 0x10) +#define RTC_YEARS (volatile __u8 *)(OMAP1510_RTC_BASE + 0x14) +#define RTC_CTRL (volatile __u8 *)(OMAP1510_RTC_BASE + 0x40) + + +/* --------------------------------------------------------------------------- + * OMAP1510 Interrupt Handlers + * --------------------------------------------------------------------------- + * + */ +#define OMAP_IH1_BASE 0xfffecb00 +#define OMAP_IH2_BASE 0xfffe0000 +#define OMAP1510_ITR 0x0 +#define OMAP1510_MASK 0x4 + +#define INTERRUPT_HANDLER_BASE OMAP_IH1_BASE +#define INTERRUPT_INPUT_REGISTER OMAP1510_ITR +#define INTERRUPT_MASK_REGISTER OMAP1510_MASK + + +/* --------------------------------------------------------------------------- + * OMAP1510 TIMERS + * --------------------------------------------------------------------------- + * + */ + +#define OMAP1510_32kHz_TIMER_BASE 0xfffb9000 + +/* 32k Timer Registers */ +#define TIMER32k_CR 0x08 +#define TIMER32k_TVR 0x00 +#define TIMER32k_TCR 0x04 + +/* 32k Timer Control Register definition */ +#define TIMER32k_TSS (1<<0) +#define TIMER32k_TRB (1<<1) +#define TIMER32k_INT (1<<2) +#define TIMER32k_ARL (1<<3) + +/* MPU Timer base addresses */ +#define OMAP1510_MPUTIMER_BASE 0xfffec500 +#define OMAP1510_MPUTIMER_OFF 0x00000100 + +#define OMAP1510_TIMER1_BASE 0xfffec500 +#define OMAP1510_TIMER2_BASE 0xfffec600 +#define OMAP1510_TIMER3_BASE 0xfffec700 + +/* MPU Timer Registers */ +#define CNTL_TIMER 0 +#define LOAD_TIM 4 +#define READ_TIM 8 + +/* CNTL_TIMER register bits */ +#define MPUTIM_FREE (1<<6) +#define MPUTIM_CLOCK_ENABLE (1<<5) +#define MPUTIM_PTV_MASK (0x7<<PTV_BIT) +#define MPUTIM_PTV_BIT 2 +#define MPUTIM_AR (1<<1) +#define MPUTIM_ST (1<<0) + +/* --------------------------------------------------------------------------- + * OMAP1510 GPIO (SHARED) + * --------------------------------------------------------------------------- + * + */ +#define GPIO_DATA_INPUT_REG (OMAP1510_GPIO_BASE + 0x0) +#define GPIO_DATA_OUTPUT_REG (OMAP1510_GPIO_BASE + 0x4) +#define GPIO_DIR_CONTROL_REG (OMAP1510_GPIO_BASE + 0x8) +#define GPIO_INT_CONTROL_REG (OMAP1510_GPIO_BASE + 0xc) +#define GPIO_INT_MASK_REG (OMAP1510_GPIO_BASE + 0x10) +#define GPIO_INT_STATUS_REG (OMAP1510_GPIO_BASE + 0x14) +#define GPIO_PIN_CONTROL_REG (OMAP1510_GPIO_BASE + 0x18) + + +/* --------------------------- + * OMAP1510 MPUIO (ARM only) + *---------------------------- + */ +#define OMAP1510_MPUIO_BASE 0xFFFB5000 +#define MPUIO_DATA_INPUT_REG (OMAP1510_MPUIO_BASE + 0x0) +#define MPUIO_DATA_OUTPUT_REG (OMAP1510_MPUIO_BASE + 0x4) +#define MPUIO_DIR_CONTROL_REG (OMAP1510_MPUIO_BASE + 0x8) + +/* --------------------------------------------------------------------------- + * OMAP1510 TIPB (only) + * --------------------------------------------------------------------------- + * + */ +#define TIPB_PUBLIC_CNTL_BASE 0xfffed300 +#define MPU_PUBLIC_TIPB_CNTL_REG (TIPB_PUBLIC_CNTL_BASE + 0x8) +#define TIPB_PRIVATE_CNTL_BASE 0xfffeca00 +#define MPU_PRIVATE_TIPB_CNTL_REG (TIPB_PRIVATE_CNTL_BASE + 0x8) + +/* + * --------------------------------------------------------------------------- + * OMAP1510 Camera Interface + * --------------------------------------------------------------------------- + */ +#define CAMERA_BASE (IO_BASE + 0x6800) +#define CAM_CTRLCLOCK_REG (CAMERA_BASE + 0x00) +#define CAM_IT_STATUS_REG (CAMERA_BASE + 0x04) +#define CAM_MODE_REG (CAMERA_BASE + 0x08) +#define CAM_STATUS_REG (CAMERA_BASE + 0x0C) +#define CAM_CAMDATA_REG (CAMERA_BASE + 0x10) +#define CAM_GPIO_REG (CAMERA_BASE + 0x14) +#define CAM_PEAK_CTR_REG (CAMERA_BASE + 0x18) + +#if 0 +#ifndef __ASSEMBLY__ +typedef struct { + __u32 ctrlclock; + __u32 it_status; + __u32 mode; + __u32 status; + __u32 camdata; + __u32 gpio; + __u32 peak_counter; +} camera_regs_t; +#endif +#endif + +/* CTRLCLOCK bit shifts */ +#define FOSCMOD_BIT 0 +#define FOSCMOD_MASK (0x7 << FOSCMOD_BIT) +#define FOSCMOD_12MHz 0x0 +#define FOSCMOD_6MHz 0x2 +#define FOSCMOD_9_6MHz 0x4 +#define FOSCMOD_24MHz 0x5 +#define FOSCMOD_8MHz 0x6 +#define POLCLK (1<<3) +#define CAMEXCLK_EN (1<<4) +#define MCLK_EN (1<<5) +#define DPLL_EN (1<<6) +#define LCLK_EN (1<<7) + +/* IT_STATUS bit shifts */ +#define V_UP (1<<0) +#define V_DOWN (1<<1) +#define H_UP (1<<2) +#define H_DOWN (1<<3) +#define FIFO_FULL (1<<4) +#define DATA_XFER (1<<5) + +/* MODE bit shifts */ +#define CAMOSC (1<<0) +#define IMGSIZE_BIT 1 +#define IMGSIZE_MASK (0x3 << IMGSIZE_BIT) +#define IMGSIZE_CIF (0x0 << IMGSIZE_BIT) /* 352x288 */ +#define IMGSIZE_QCIF (0x1 << IMGSIZE_BIT) /* 176x144 */ +#define IMGSIZE_VGA (0x2 << IMGSIZE_BIT) /* 640x480 */ +#define IMGSIZE_QVGA (0x3 << IMGSIZE_BIT) /* 320x240 */ +#define ORDERCAMD (1<<3) +#define EN_V_UP (1<<4) +#define EN_V_DOWN (1<<5) +#define EN_H_UP (1<<6) +#define EN_H_DOWN (1<<7) +#define EN_DMA (1<<8) +#define THRESHOLD (1<<9) +#define THRESHOLD_BIT 9 +#define THRESHOLD_MASK (0x7f<<9) +#define EN_NIRQ (1<<16) +#define EN_FIFO_FULL (1<<17) +#define RAZ_FIFO (1<<18) + +/* STATUS bit shifts */ +#define VSTATUS (1<<0) +#define HSTATUS (1<<1) + +/* GPIO bit shifts */ +#define CAM_RST (1<<0) + + +/********************* + * Watchdog timer. + *********************/ +#define WDTIM_BASE 0xfffec800 +#define WDTIM_CONTROL (WDTIM_BASE+0x00) +#define WDTIM_LOAD (WDTIM_BASE+0x04) +#define WDTIM_READ (WDTIM_BASE+0x04) +#define WDTIM_MODE (WDTIM_BASE+0x08) + +/* Values to write to mode register to disable the watchdog function. */ +#define DISABLE_SEQ1 0xF5 +#define DISABLE_SEQ2 0xA0 + +/* WDTIM_CONTROL bit definitions. */ +#define WDTIM_CONTROL_ST BIT7 + + +/* --------------------------------------------------------------------------- + * Differentiating processor versions for those who care. + * --------------------------------------------------------------------------- + * + */ +#define OMAP1509 0 +#define OMAP1510 1 + +#define OMAP1510_ID_CODE_REG 0xfffed404 + +#ifndef __ASSEMBLY__ +int cpu_type(void); +#endif + +/* + * EVM Implementation Specifics. + * + * *** NOTE *** + * Any definitions in these files should be prefixed by an identifier - + * eg. OMAP1510P1_FLASH0_BASE . + * + */ +#ifdef CONFIG_OMAP_INNOVATOR +#include "innovator.h" +#endif + +#ifdef CONFIG_OMAP_1510P1 +#include "omap1510p1.h" +#endif + +/*****************************************************************************/ + +#define CLKGEN_RESET_BASE (0xfffece00) +#define ARM_CKCTL (volatile __u16 *)(CLKGEN_RESET_BASE + 0x0) +#define ARM_IDLECT1 (volatile __u16 *)(CLKGEN_RESET_BASE + 0x4) +#define ARM_IDLECT2 (volatile __u16 *)(CLKGEN_RESET_BASE + 0x8) +#define ARM_EWUPCT (volatile __u16 *)(CLKGEN_RESET_BASE + 0xC) +#define ARM_RSTCT1 (volatile __u16 *)(CLKGEN_RESET_BASE + 0x10) +#define ARM_RSTCT2 (volatile __u16 *)(CLKGEN_RESET_BASE + 0x14) +#define ARM_SYSST (volatile __u16 *)(CLKGEN_RESET_BASE + 0x18) + + +#define CK_CLKIN 12 /* MHz */ +#define CK_RATEF 1 +#define CK_IDLEF 2 +#define CK_ENABLEF 4 +#define CK_SELECTF 8 +#ifndef __ASSEMBLER__ +#define CK_DPLL1 ((volatile __u16 *)0xfffecf00) +#else +#define CK_DPLL1 (0xfffecf00) +#endif +#define SETARM_IDLE_SHIFT + +/* ARM_CKCTL bit shifts */ +#define PERDIV 0 +#define LCDDIV 2 +#define ARMDIV 4 +#define DSPDIV 6 +#define TCDIV 8 +#define DSPMMUDIV 10 +#define ARM_TIMXO 12 +#define EN_DSPCK 13 +#define ARM_INTHCK_SEL 14 /* REVISIT -- where is this used? */ + +#define ARM_CKCTL_RSRVD_BIT15 (1 << 15) +#define ARM_CKCTL_ARM_INTHCK_SEL (1 << 14) +#define ARM_CKCTL_EN_DSPCK (1 << 13) +#define ARM_CKCTL_ARM_TIMXO (1 << 12) +#define ARM_CKCTL_DSPMMU_DIV1 (1 << 11) +#define ARM_CKCTL_DSPMMU_DIV2 (1 << 10) +#define ARM_CKCTL_TCDIV1 (1 << 9) +#define ARM_CKCTL_TCDIV2 (1 << 8) +#define ARM_CKCTL_DSPDIV1 (1 << 7) +#define ARM_CKCTL_DSPDIV0 (1 << 6) +#define ARM_CKCTL_ARMDIV1 (1 << 5) +#define ARM_CKCTL_ARMDIV0 (1 << 4) +#define ARM_CKCTL_LCDDIV1 (1 << 3) +#define ARM_CKCTL_LCDDIV0 (1 << 2) +#define ARM_CKCTL_PERDIV1 (1 << 1) +#define ARM_CKCTL_PERDIV0 (1 << 0) + +/* ARM_IDLECT1 bit shifts */ +#define IDLWDT_ARM 0 +#define IDLXORP_ARM 1 +#define IDLPER_ARM 2 +#define IDLLCD_ARM 3 +#define IDLLB_ARM 4 +#define IDLHSAB_ARM 5 +#define IDLIF_ARM 6 +#define IDLDPLL_ARM 7 +#define IDLAPI_ARM 8 +#define IDLTIM_ARM 9 +#define SETARM_IDLE 11 + +/* ARM_IDLECT2 bit shifts */ +#define EN_WDTCK 0 +#define EN_XORPCK 1 +#define EN_PERCK 2 +#define EN_LCDCK 3 +#define EN_LBCK 4 +#define EN_HSABCK 5 +#define EN_APICK 6 +#define EN_TIMCK 7 +#define DMACK_REQ 8 +#define EN_GPIOCK 9 +#define EN_LBFREECK 10 + +#define ARM_RSTCT1_SW_RST (1 << 3) +#define ARM_RSTCT1_DSP_RST (1 << 2) +#define ARM_RSTCT1_DSP_EN (1 << 1) +#define ARM_RSTCT1_ARM_RST (1 << 0) + +/* ARM_RSTCT2 bit shifts */ +#define EN_PER 0 + +#define ARM_SYSST_RSRVD_BIT15 (1 << 15) +#define ARM_SYSST_RSRVD_BIT14 (1 << 14) +#define ARM_SYSST_CLOCK_SELECT2 (1 << 13) +#define ARM_SYSST_CLOCK_SELECT1 (1 << 12) +#define ARM_SYSST_CLOCK_SELECT0 (1 << 11) +#define ARM_SYSST_RSRVD_BIT10 (1 << 10) +#define ARM_SYSST_RSRVD_BIT9 (1 << 9) +#define ARM_SYSST_RSRVD_BIT8 (1 << 8) +#define ARM_SYSST_RSRVD_BIT7 (1 << 7) +#define ARM_SYSST_IDLE_DSP (1 << 6) +#define ARM_SYSST_POR (1 << 5) +#define ARM_SYSST_EXT_RST (1 << 4) +#define ARM_SYSST_ARM_MCRST (1 << 3) +#define ARM_SYSST_ARM_WDRST (1 << 2) +#define ARM_SYSST_GLOB_SWRST (1 << 1) +#define ARM_SYSST_DSP_WDRST (1 << 0) + +/* Table 15-23. DPLL Control Registers: */ +#define DPLL_CTL_REG (volatile __u16 *)(0xfffecf00) + +/* Table 15-24. Control Register (CTL_REG): */ + +#define DPLL_CTL_REG_IOB (1 << 13) +#define DPLL_CTL_REG_PLL_MULT Fld(5,0) + +/*****************************************************************************/ + +/* OMAP INTERRUPT REGISTERS */ +#define IRQ_ITR 0x00 +#define IRQ_MIR 0x04 +#define IRQ_SIR_IRQ 0x10 +#define IRQ_SIR_FIQ 0x14 +#define IRQ_CONTROL_REG 0x18 +#define IRQ_ISR 0x9c +#define IRQ_ILR0 0x1c + +#define REG_IHL1_MIR (OMAP_IH1_BASE+IRQ_MIR) +#define REG_IHL2_MIR (OMAP_IH2_BASE+IRQ_MIR) + +/* INTERRUPT LEVEL REGISTER BITS */ +#define ILR_PRIORITY_MASK (0x3c) +#define ILR_PRIORITY_SHIFT (2) +#define ILR_LEVEL_TRIGGER (1<<1) +#define ILR_FIQ (1<<0) + +#define IRQ_LEVEL_INT 1 +#define IRQ_EDGE_INT 0
diff --git a/x-loader/include/configs/omap1710h3.h b/x-loader/include/configs/omap1710h3.h new file mode 100644 index 0000000..6a881bd --- /dev/null +++ b/x-loader/include/configs/omap1710h3.h
@@ -0,0 +1,128 @@ +/* + * (C) Copyright 2004 + * Texas Instruments. + * Jian Zhang <jzhang@ti.com>, Kshitij Gupta <kshitij@ti.com> + * X-Loader Configuation settings for the TI OMAP H3 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 + +/* exactly uncomment one */ +#define CFG_BOOT_CS0 /* ROM code -> signed X-Loader in NNAD */ +//#define CFG_BOOT_CS3 /* unsigned X-loader in NOR for development */ + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* + * 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_OMAP1710 1 /* which is in a 1710 */ +#define CONFIG_H3_OMAP1710 1 /* a H3 Board */ + +/* input clock of PLL */ +/* the OMAP1710 H3 has 12MHz input clock */ +#define CONFIG_SYS_CLK_FREQ 12000000 + + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) /* can be 12M/32Khz or 48Mhz */ +#define CFG_NS16550_COM1 0xfffb0000 /* uart1, bluetooth uart on helen */ + +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 + +#endif /* CFG_PRINTF */ + +#include <configs/omap1510.h> + +/* + * Miscellaneous configurable options + */ +#define CFG_PBSIZE 256 +#define CFG_LOADADDR 0x11000000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/* The 1710 has 6 timers, they can be driven by the RefClk (12Mhz) or by + * DPLL1. This time is further subdivided by a local divisor. + */ +#define CFG_TIMERBASE 0xFFFEC500 /* use timer 1 */ +#define CFG_PVT 7 /* 2^(pvt+1), divide by 256 */ +#define CFG_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CFG_PVT)) + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ +#define CFG_NAND_K9F5616 /* Samsung 16-bit 32MB chip */ + +#ifdef CFG_BOOT_CS0 +#define NAND_ADDR 0x0c000000 /* physical address to access nand at CS3*/ +#else +#define NAND_ADDR 0x0a000000 /* physical address to access nand at CS2B*/ +#endif + +/* H3 NAND is partitioned: + * 0x0000000 - 0x0010000 Booting Image + * 0x0010000 - 0x0050000 U-Boot Image + * 0x0050000 - 0x0080000 U-Boot Env Data (X-loader doesn't care) + * 0x0080000 - 0x2000000 depends on application + */ +#define NAND_UBOOT_START 0x0010000 +#define NAND_UBOOT_END 0x0050000 +#define NAND_BLOCK_SIZE 0x4000 + +#define WRITE_NAND_COMMAND(d, adr) do{ *(volatile __u8 *)((unsigned long)adr + 2) = (__u8)(d); } while(0) +#define WRITE_NAND_ADDRESS(d, adr) do{ *(volatile __u8 *)((unsigned long)adr + 4) = (__u8)(d); } while(0) +#define WRITE_NAND(d, adr) do{ *(volatile __u16 *)((unsigned long)adr) = (__u16)(d); } while(0) +#define READ_NAND(adr) ((volatile __u16)(*(volatile __u16 *)(unsigned long)adr)) + +#define GPIO1_DATAIN 0xfffbe42c +#define NAND_WAIT_READY() while(!((*(volatile __u16 *)(GPIO1_DATAIN) & 0x0400) == 0x0400)); + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + + +#endif /* __CONFIG_H */
diff --git a/x-loader/include/configs/omap2420h4.h b/x-loader/include/configs/omap2420h4.h new file mode 100644 index 0000000..7495d7f --- /dev/null +++ b/x-loader/include/configs/omap2420h4.h
@@ -0,0 +1,140 @@ +/* + * Copyright (C) 2004 - 2005 Texas Instruments. + * + * X-Loader Configuation settings for the TI OMAP H4 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* + * High Level Configuration Options + */ +#define CONFIG_ARM1136 1 /* This is an arm1136 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP2420 1 /* which is in a 2420 */ +#define CONFIG_OMAP2420H4 1 /* and on a H4 board */ + +#define CONFIG_OMAP242X + +#define PRCM_CONFIG_II 1 +//#define PRCM_CONFIG_III 1 +#define CONFIG_PARTIAL_SRAM 1 + +//#define CFG_SDRAM_DDR 1 +#define CFG_SDRAM_COMBO 2 +//#define CFG_SDRAM_SDR 3 +//#define CFG_SDRAM_STACKED 4 + +/* Chipselect and NAND information : + Since we share the mem.h from u-boot, we define few macros here + so as to pick the right gpmc values from there for the macros in mem.h +*/ +/* NAND fixed at CS5 */ +#define OMAP24XX_GPMC_CS0 SMNAND +#define OMAP24XX_GPMC_CS0_SIZE GPMC_SIZE_64M +#define OMAP24XX_GPMC_CS0_MAP CFG_FLASH_BASE +#define CFG_NAND_BOOT +#define NAND_LEGACY + +#include <asm/arch/omap2420.h> /* get chip and board defs */ + +#define V_SCLK 12000000 +/* input clock of PLL */ +/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */ +#define CONFIG_SYS_CLK_FREQ V_SCLK + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) /* can be 12M/32Khz or 48Mhz */ +#define CFG_NS16550_COM1 OMAP2420_UART1 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1 1 /* UART1 on H4 */ + +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80000000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ +#define CFG_NAND_K9K1216 /* Samsung 16-bit 64MB chip */ + +#define NAND_ADDR 0x04000000 /* physical address to access nand at CS0*/ + +/* H4 NAND is partitioned: + * 0x0000000 - 0x0010000 Booting Image + * 0x0010000 - 0x0050000 U-Boot Image + * 0x0050000 - 0x0080000 U-Boot Env Data (X-loader doesn't care) + * 0x0080000 - 0x4000000 depends on application + */ +#define NAND_UBOOT_START 0x0040000 +#define NAND_UBOOT_END 0x0080000 +#define NAND_BLOCK_SIZE 0x4000 + +#define WRITE_NAND_COMMAND(d, adr) do {*(volatile u16 *)0x6800A07C = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) do {*(volatile u16 *)0x6800A080 = d;} while(0) +#define WRITE_NAND(d, adr) do {*(volatile u16 *)0x6800A084 = d;} while(0) +#define READ_NAND(adr) (*(volatile u16 *)0x6800A084) + +#define NAND_WAIT_READY() + +#define NAND_WP_OFF() do {*(volatile u32 *)(0x6800A050) |= 0x00000010;} while(0) +#define NAND_WP_ON() do {*(volatile u32 *)(0x6800A050) &= ~0x00000010;} while(0) + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + + +#endif /* __CONFIG_H */
diff --git a/x-loader/include/configs/omap2430sdp.h b/x-loader/include/configs/omap2430sdp.h new file mode 100644 index 0000000..3fda61f --- /dev/null +++ b/x-loader/include/configs/omap2430sdp.h
@@ -0,0 +1,178 @@ +/* + * (C) Copyright 2004 Texas Instruments. + * + * X-Loader Configuation settings for the TI OMAP H4 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* + * High Level Configuration Options + */ +#define CONFIG_ARM1136 1 /* This is an arm1136 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP2430H4 1 /* and on a H4 board */ + +#define CONFIG_OMAP243X 1 + +//#define PRCM_CONFIG_5A 1 +#define PRCM_CONFIG_2 1 /* 2430 ES2+330ARM+DDR-165-PISMO */ + +#define OMAP2430_SQUARE_CLOCK_INPUT 1 + +/* Memory type */ +//#define CFG_SDRAM_DDR 1 /* not tested */ +//#define CFG_SDRAM_COMBO 2 /* not tested */ +#define CFG_2430SDRAM_DDR 3 +//#define CFG_SDRAM_STACKED 4 /* not tested */ + +/* The actual register values are defined in u-boot- mem.h */ +/* SDRAM Bank Allocation method */ +//#define SDRC_B_R_C 1 +//#define SDRC_B1_R_B0_C 1 +#define SDRC_R_B_C 1 + +/* Boot type */ +//#define CFG_NAND 1 +#define CFG_ONENAND 1 + +# define NAND_BASE 0x0C000000 /* NAND flash */ +# define ONENAND_BASE 0x20000000 /* OneNand flash */ + +#ifdef CFG_NAND +#define NAND_LEGACY +#define OMAP24XX_GPMC_CS0_SIZE GPMC_SIZE_64M +#define OMAP24XX_GPMC_CS0_MAP NAND_BASE +#else +#define OMAP24XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define OMAP24XX_GPMC_CS0_MAP ONENAND_BASE +#define ONENAND_ADDR ONENAND_BASE /* physical address to access OneNAND at CS0*/ +#endif + +/* Another dependency on u-boot */ +#define sdelay delay + +#include <asm/arch/omap2430.h> /* get chip and board defs */ + +#define V_SCLK 13000000 +/* input clock of PLL */ +/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */ +#define CONFIG_SYS_CLK_FREQ V_SCLK + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) /* can be 12M/32Khz or 48Mhz */ +#define CFG_NS16550_COM1 OMAP2430_UART1 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1 1 /* UART1 on 2430SDP */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80008000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +#ifdef CFG_NAND + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ +#define CFG_NAND_K9K1216 /* Samsung 16-bit 64MB chip */ + +/* NAND is partitioned: + * 0x0000000 - 0x0010000 Booting Image + * 0x0010000 - 0x0050000 U-Boot Image + * 0x0050000 - 0x0080000 U-Boot Env Data (X-loader doesn't care) + * 0x0080000 - 0x00B0000 Kernel Image + * 0x00B0000 - 0x4000000 depends on application + */ +#define NAND_UBOOT_START 0x0040000 +#define NAND_UBOOT_END 0x0080000 +#define NAND_BLOCK_SIZE 0x4000 + +#define GPMC_CONFIG (OMAP24XX_GPMC_BASE+0x50) +#define GPMC_NAND_COMMAND_0 (OMAP24XX_GPMC_BASE+0x7C) +#define GPMC_NAND_ADDRESS_0 (OMAP24XX_GPMC_BASE+0x80) +#define GPMC_NAND_DATA_0 (OMAP24XX_GPMC_BASE+0x84) + +#define WRITE_NAND_COMMAND(d, adr) do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +#else +/*----------------------------------------------------------------------- + * Board oneNAND Info. + */ +#define CFG_SYNC_BURST_READ 1 + +/* OneNAND is partitioned: + * 0x0000000 - 0x0080000 X-Loader + * 0x0080000 - 0x00c0000 U-boot Image + * 0x00c0000 - 0x00e0000 U-Boot Env Data (X-loader doesn't care) + * 0x00e0000 - 0x0120000 Kernel Image + * 0x0120000 - 0x4000000 depends on application + */ + +#define ONENAND_START_BLOCK 4 +#define ONENAND_END_BLOCK 6 +#define ONENAND_PAGE_SIZE 2048 /* 2KB */ +#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ + +#endif // oneNAND +#endif /* __CONFIG_H */
diff --git a/x-loader/include/configs/omap3430labrador.h b/x-loader/include/configs/omap3430labrador.h new file mode 100755 index 0000000..b608872 --- /dev/null +++ b/x-loader/include/configs/omap3430labrador.h
@@ -0,0 +1,207 @@ +/* + * (C) Copyright 2006 + * Texas Instruments <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * X-Loader Configuation settings for the TI OMAP SDP3430 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_3430LABRADOR 1 /* working on Labrador */ +//#define CONFIG_3430_AS_3410 1 /* true for 3430 in 3410 mode */ + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ + +#if (V_OSCK > 19200000) +#define V_SCLK (V_OSCK >> 1) +#else +#define V_SCLK V_OSCK +#endif + +#define PRCM_CLK_CFG2_266MHZ 1 /* VDD2=1.15v - 133MHz DDR */ +//#define PRCM_CLK_CFG2_332MHZ 1 /* VDD2=1.15v - 166MHz DDR */ +#define PRCM_PCLK_OPP2 1 /* ARM=500MHz - VDD1=1.20v */ + +/* Memory type */ +#define CFG_3430SDRAM_DDR 1 + +/* The actual register values are defined in u-boot- mem.h */ +/* SDRAM Bank Allocation method */ +//#define SDRC_B_R_C 1 +//#define SDRC_B1_R_B0_C 1 +#define SDRC_R_B_C 1 + +/* Boot type */ +#define CFG_NAND 1 +//#define CFG_ONENAND 1 + +# define NAND_BASE_ADR NAND_BASE /* NAND flash */ +# define ONENAND_BASE ONENAND_MAP /* OneNand flash */ + +#ifdef CFG_NAND +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M /* u = ofdon't need so much for nand port */ +#define OMAP34XX_GPMC_CS0_MAP NAND_BASE_ADR +#else +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define OMAP34XX_GPMC_CS0_MAP ONENAND_BASE +#define ONENAND_ADDR ONENAND_BASE /* physical address of OneNAND at CS0*/ +#endif + + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) +#define CFG_NS16550_COM3 OMAP34XX_UART3 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL3 3 /* UART3 on board */ +#define CONFIG_CONS_INDEX 3 + +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80008000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +#ifdef CFG_NAND + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ + + +#define CFG_NAND_K9F1G08R0A /* Micron 16-bit 256MB chip large page NAND chip*/ +#define NAND_16BIT + +/* NAND is partitioned: + * 0x00000000 - 0x0007FFFF Booting Image + * 0x00080000 - 0x000BFFFF U-Boot Image + * 0x000C0000 - 0x000FFFFF U-Boot Env Data (X-loader doesn't care) + * 0x00100000 - 0x002FFFFF Kernel Image + * 0x00300000 - 0x08000000 depends on application + */ +#define NAND_UBOOT_START 0x0080000 /* Leaving first 4 blocks for x-load */ +#define NAND_UBOOT_END 0x00C0000 /* Giving a space of 2 blocks = 256KB */ +#define NAND_BLOCK_SIZE 0x20000 + +#define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) +#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) +#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) +#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) + +#ifdef NAND_16BIT +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#else /* to support 8-bit NAND devices */ +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u8 *)GPMC_NAND_DATA_0); +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#endif + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +#else +/*----------------------------------------------------------------------- + * Board oneNAND Info. + */ +#define CFG_SYNC_BURST_READ 1 + +/* OneNAND is partitioned: + * 0x0000000 - 0x0080000 X-Loader + * 0x0080000 - 0x00c0000 U-boot Image + * 0x00c0000 - 0x00e0000 U-Boot Env Data (X-loader doesn't care) + * 0x00e0000 - 0x0120000 Kernel Image + * 0x0120000 - 0x4000000 depends on application + */ + +#define ONENAND_START_BLOCK 4 +#define ONENAND_END_BLOCK 6 +#define ONENAND_PAGE_SIZE 2048 /* 2KB */ +#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ + +#endif /* oneNAND */ +#endif /* __CONFIG_H */ +
diff --git a/x-loader/include/configs/omap3430sdp.h b/x-loader/include/configs/omap3430sdp.h new file mode 100644 index 0000000..ad880ed --- /dev/null +++ b/x-loader/include/configs/omap3430sdp.h
@@ -0,0 +1,213 @@ +/* + * (C) Copyright 2006 + * Texas Instruments <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * X-Loader Configuation settings for the TI OMAP SDP3430 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_3430SDP 1 /* working with SDP */ +//#define CONFIG_3430_AS_3410 1 /* true for 3430 in 3410 mode */ + +/* Enable the below macro if MMC boot support is required */ +//#define CONFIG_MMC 1 +#if defined(CONFIG_MMC) + #define CFG_CMD_MMC 1 + #define CFG_CMD_FAT 1 +#endif + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* Clock Defines */ +#define V_OSCK 19200000 /* Clock output from T2 */ + +#if (V_OSCK > 19200000) +#define V_SCLK (V_OSCK >> 1) +#else +#define V_SCLK V_OSCK +#endif + +//#define PRCM_CLK_CFG2_266MHZ 1 /* VDD2=1.15v - 133MHz DDR */ +#define PRCM_CLK_CFG2_332MHZ 1 /* VDD2=1.15v - 166MHz DDR */ +#define PRCM_PCLK_OPP2 1 /* ARM=381MHz - VDD1=1.20v */ + +/* Memory type */ +#define CFG_3430SDRAM_DDR 1 + +/* The actual register values are defined in u-boot- mem.h */ +/* SDRAM Bank Allocation method */ +//#define SDRC_B_R_C 1 +//#define SDRC_B1_R_B0_C 1 +#define SDRC_R_B_C 1 + +/* Boot type */ +#define CFG_NAND 1 +//#define CFG_ONENAND 1 + +# define NAND_BASE_ADR NAND_BASE /* NAND flash */ +# define ONENAND_BASE ONENAND_MAP /* OneNand flash */ + +#ifdef CFG_NAND +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define OMAP34XX_GPMC_CS0_MAP NAND_BASE_ADR +#else +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define OMAP34XX_GPMC_CS0_MAP ONENAND_BASE +#define ONENAND_ADDR ONENAND_BASE /* physical address of OneNAND at CS0*/ +#endif + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) +#define CFG_NS16550_COM1 OMAP34XX_UART1 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1 1 /* UART1 on 3430SDP */ +#define CONFIG_CONS_INDEX 1 + +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80008000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +#ifdef CFG_NAND + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ + + +#define CFG_NAND_K9F1G08R0A /* Samsung 8-bit 128MB chip large page NAND chip*/ +#define NAND_8BIT + +/* NAND is partitioned: + * 0x00000000 - 0x0007FFFF Booting Image + * 0x00080000 - 0x000BFFFF U-Boot Image + * 0x000C0000 - 0x000FFFFF U-Boot Env Data (X-loader doesn't care) + * 0x00100000 - 0x002FFFFF Kernel Image + * 0x00300000 - 0x08000000 depends on application + */ +#define NAND_UBOOT_START 0x0080000 /* Leaving first 4 blocks for x-load */ +#define NAND_UBOOT_END 0x00C0000 /* Giving a space of 2 blocks = 256KB */ +#define NAND_BLOCK_SIZE 0x20000 + +#define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) +#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) +#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) +#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) + +#ifdef NAND_16BIT +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#else /* to support 8-bit NAND devices */ +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u8 *)GPMC_NAND_DATA_0); +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#endif + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +#else +/*----------------------------------------------------------------------- + * Board oneNAND Info. + */ +#define CFG_SYNC_BURST_READ 1 + +/* OneNAND is partitioned: + * 0x0000000 - 0x0080000 X-Loader + * 0x0080000 - 0x00c0000 U-boot Image + * 0x00c0000 - 0x00e0000 U-Boot Env Data (X-loader doesn't care) + * 0x00e0000 - 0x0120000 Kernel Image + * 0x0120000 - 0x4000000 depends on application + */ + +#define ONENAND_START_BLOCK 4 +#define ONENAND_END_BLOCK 6 +#define ONENAND_PAGE_SIZE 2048 /* 2KB */ +#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ + +#endif /* oneNAND */ +#endif /* __CONFIG_H */ +
diff --git a/x-loader/include/configs/omap3evm.h b/x-loader/include/configs/omap3evm.h new file mode 100755 index 0000000..3810a17 --- /dev/null +++ b/x-loader/include/configs/omap3evm.h
@@ -0,0 +1,204 @@ +/* + * Copyright (C) 2007 Mistral Solutions Pvt Ltd. + * + * X-Loader Configuation settings for the OMAP3EVM board. + * + * Derived from /include/configs/omap3430sdp.h + * + * 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 + +/* serial printf facility takes about 3.5K */ +#define CFG_PRINTF +//#undef CFG_PRINTF + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +//#define CONFIG_3430SDP 1 /* working with SDP */ +//#define CONFIG_3430_AS_3410 1 /* true for 3430 in 3410 mode */ + +#define CONFIG_OMAP3EVM 1 /* working with EVM */ + +/* Enable the below macro if MMC boot support is required */ +#define CONFIG_MMC 1 +#if defined(CONFIG_MMC) + #define CFG_CMD_MMC 1 + #define CFG_CMD_FAT 1 +#endif + +#include <asm/arch/cpu.h> /* get chip and board defs */ + +/* uncomment it if you need timer based udelay(). it takes about 250 bytes */ +//#define CFG_UDELAY + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ + +#if (V_OSCK > 19200000) +#define V_SCLK (V_OSCK >> 1) +#else +#define V_SCLK V_OSCK +#endif + +//#define PRCM_CLK_CFG2_266MHZ 1 /* VDD2=1.15v - 133MHz DDR */ +#define PRCM_CLK_CFG2_332MHZ 1 /* VDD2=1.15v - 166MHz DDR */ +#define PRCM_PCLK_OPP2 1 /* ARM=381MHz - VDD1=1.20v */ + +/* Memory type */ +#define CFG_OMAPEVM_DDR 1 +#define CFG_3430SDRAM_DDR 1 +#define CONFIG_DDR_256MB_STACKED + +/* The actual register values are defined in u-boot- mem.h */ +/* SDRAM Bank Allocation method */ +//#define SDRC_B_R_C 1 +//#define SDRC_B1_R_B0_C 1 +#define SDRC_R_B_C 1 + + +# define NAND_BASE_ADR NAND_BASE /* NAND flash */ +# define ONENAND_BASE ONENAND_MAP /* OneNand flash */ + +#define OMAP34XX_GPMC_CS0_SIZE GPMC_SIZE_128M +#define ONENAND_ADDR ONENAND_BASE /* physical address of OneNAND at CS0*/ + +#ifdef CFG_PRINTF + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE (-4) +#define CFG_NS16550_CLK (48000000) +#define CFG_NS16550_COM1 OMAP34XX_UART1 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1 1 /* UART1 on OMAP3EVM */ +#define CONFIG_CONS_INDEX 1 + +#define CONFIG_BAUDRATE 115200 +#define CFG_PBSIZE 256 + +#endif /* CFG_PRINTF */ + +/* + * Miscellaneous configurable options + */ +#define CFG_LOADADDR 0x80008000 + +#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128*1024) /* regular stack */ + +/*----------------------------------------------------------------------- + * Board NAND Info. + */ + + +#define CFG_NAND_K9F1G08R0A /* Samsung 8-bit 128MB chip large page NAND chip*/ +#define NAND_16BIT + +/* NAND is partitioned: + * 0x00000000 - 0x0007FFFF Booting Image + * 0x00080000 - 0x0023FFFF U-Boot Image + * 0x00240000 - 0x0027FFFF U-Boot Env Data (X-loader doesn't care) + * 0x00280000 - 0x0077FFFF Kernel Image + * 0x00780000 - 0x08000000 depends on application + */ +#define NAND_UBOOT_START 0x0080000 /* Leaving first 4 blocks for x-load */ +#define NAND_UBOOT_END 0x0240000 /* Giving a space of 2 blocks = 256KB */ +#define NAND_BLOCK_SIZE 0x20000 + +#define GPMC_CONFIG (OMAP34XX_GPMC_BASE+0x50) +#define GPMC_NAND_COMMAND_0 (OMAP34XX_GPMC_BASE+0x7C) +#define GPMC_NAND_ADDRESS_0 (OMAP34XX_GPMC_BASE+0x80) +#define GPMC_NAND_DATA_0 (OMAP34XX_GPMC_BASE+0x84) + +#ifdef NAND_16BIT +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u16 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u16 *)GPMC_NAND_DATA_0) +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#else /* to support 8-bit NAND devices */ +#define WRITE_NAND_COMMAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_COMMAND_0 = d;} while(0) +#define WRITE_NAND_ADDRESS(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_ADDRESS_0 = d;} while(0) +#define WRITE_NAND(d, adr) \ + do {*(volatile u8 *)GPMC_NAND_DATA_0 = d;} while(0) +#define READ_NAND(adr) \ + (*(volatile u8 *)GPMC_NAND_DATA_0); +#define NAND_WAIT_READY() +#define NAND_WP_OFF() \ + do {*(volatile u32 *)(GPMC_CONFIG) |= 0x00000010;} while(0) +#define NAND_WP_ON() \ + do {*(volatile u32 *)(GPMC_CONFIG) &= ~0x00000010;} while(0) + +#endif + +#define NAND_CTL_CLRALE(adr) +#define NAND_CTL_SETALE(adr) +#define NAND_CTL_CLRCLE(adr) +#define NAND_CTL_SETCLE(adr) +#define NAND_DISABLE_CE() +#define NAND_ENABLE_CE() + +/*----------------------------------------------------------------------- + * Board oneNAND Info. + */ +#define CFG_SYNC_BURST_READ 1 + +/* OneNAND is partitioned: + * 0x0000000 - 0x0080000 X-Loader + * 0x0080000 - 0x0240000 U-boot Image + * 0x0240000 - 0x0280000 U-Boot Env Data (X-loader doesn't care) + * 0x0280000 - 0x0780000 Kernel Image + * 0x0780000 - 0x8000000 depends on application + */ + +#define ONENAND_START_BLOCK 4 +#define ONENAND_END_BLOCK 18 +#define ONENAND_PAGE_SIZE 2048 /* 2KB */ +#define ONENAND_BLOCK_SIZE 0x20000 /* 128KB */ + +#endif /* __CONFIG_H */ +
diff --git a/x-loader/include/fat.h b/x-loader/include/fat.h new file mode 100644 index 0000000..92573ba --- /dev/null +++ b/x-loader/include/fat.h
@@ -0,0 +1,215 @@ +/* + * R/O (V)FAT 12/16/32 filesystem implementation by Marcus Sundberg + * + * 2002-07-28 - rjones@nexus-tech.net - ported to ppcboot v1.1.6 + * 2003-03-10 - kharris@nexus-tech.net - ported to u-boot + * + * 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 _FAT_H_ +#define _FAT_H_ + +#include <asm/byteorder.h> + +#define CONFIG_SUPPORT_VFAT + +#define SECTOR_SIZE FS_BLOCK_SIZE + +#define FS_BLOCK_SIZE 512 + +#if FS_BLOCK_SIZE != SECTOR_SIZE +#error FS_BLOCK_SIZE != SECTOR_SIZE - This code needs to be fixed! +#endif + +#define MAX_CLUSTSIZE 65536 +#define DIRENTSPERBLOCK (FS_BLOCK_SIZE/sizeof(dir_entry)) +#define DIRENTSPERCLUST ((mydata->clust_size*SECTOR_SIZE)/sizeof(dir_entry)) + +#define FATBUFBLOCKS 6 +#define FATBUFSIZE (FS_BLOCK_SIZE*FATBUFBLOCKS) +#define FAT12BUFSIZE ((FATBUFSIZE*2)/3) +#define FAT16BUFSIZE (FATBUFSIZE/2) +#define FAT32BUFSIZE (FATBUFSIZE/4) + + +/* Filesystem identifiers */ +#define FAT12_SIGN "FAT12 " +#define FAT16_SIGN "FAT16 " +#define FAT32_SIGN "FAT32 " +#define SIGNLEN 7 + +/* File attributes */ +#define ATTR_RO 1 +#define ATTR_HIDDEN 2 +#define ATTR_SYS 4 +#define ATTR_VOLUME 8 +#define ATTR_DIR 16 +#define ATTR_ARCH 32 + +#define ATTR_VFAT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) + +#define DELETED_FLAG ((char)0xe5) /* Marks deleted files when in name[0] */ +#define aRING 0x05 /* Used to represent 'å' in name[0] */ + +/* Indicates that the entry is the last long entry in a set of long + * dir entries + */ +#define LAST_LONG_ENTRY_MASK 0x40 + +/* Flags telling whether we should read a file or list a directory */ +#define LS_NO 0 +#define LS_YES 1 +#define LS_DIR 1 +#define LS_ROOT 2 + +#ifdef DEBUG +#define FAT_DPRINT(args...) printf(args) +#else +#define FAT_DPRINT(args...) +#endif +#define FAT_ERROR(arg) printf(arg) + +#define ISDIRDELIM(c) ((c) == '/' || (c) == '\\') + +#define FSTYPE_NONE (-1) + +#if defined(__linux__) && defined(__KERNEL__) +#define FAT2CPU16 le16_to_cpu +#define FAT2CPU32 le32_to_cpu +#else +#if __LITTLE_ENDIAN +#define FAT2CPU16(x) (x) +#define FAT2CPU32(x) (x) +#else +#define FAT2CPU16(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8)) +#define FAT2CPU32(x) ((((x) & 0x000000ff) << 24) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0xff000000) >> 24)) +#endif +#endif + +#define TOLOWER(c) if((c) >= 'A' && (c) <= 'Z'){(c)+=('a' - 'A');} +#define START(dent) (FAT2CPU16((dent)->start) \ + + (mydata->fatsize != 32 ? 0 : \ + (FAT2CPU16((dent)->starthi) << 16))) + + +typedef struct boot_sector { + __u8 ignored[3]; /* Bootstrap code */ + char system_id[8]; /* Name of fs */ + __u8 sector_size[2]; /* Bytes/sector */ + __u8 cluster_size; /* Sectors/cluster */ + __u16 reserved; /* Number of reserved sectors */ + __u8 fats; /* Number of FATs */ + __u8 dir_entries[2]; /* Number of root directory entries */ + __u8 sectors[2]; /* Number of sectors */ + __u8 media; /* Media code */ + __u16 fat_length; /* Sectors/FAT */ + __u16 secs_track; /* Sectors/track */ + __u16 heads; /* Number of heads */ + __u32 hidden; /* Number of hidden sectors */ + __u32 total_sect; /* Number of sectors (if sectors == 0) */ + + /* FAT32 only */ + __u32 fat32_length; /* Sectors/FAT */ + __u16 flags; /* Bit 8: fat mirroring, low 4: active fat */ + __u8 version[2]; /* Filesystem version */ + __u32 root_cluster; /* First cluster in root directory */ + __u16 info_sector; /* Filesystem info sector */ + __u16 backup_boot; /* Backup boot sector */ + __u16 reserved2[6]; /* Unused */ +} boot_sector; + +typedef struct volume_info +{ + __u8 drive_number; /* BIOS drive number */ + __u8 reserved; /* Unused */ + __u8 ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */ + __u8 volume_id[4]; /* Volume ID number */ + char volume_label[11]; /* Volume label */ + char fs_type[8]; /* Typically FAT12, FAT16, or FAT32 */ + /* Boot code comes next, all but 2 bytes to fill up sector */ + /* Boot sign comes last, 2 bytes */ +} volume_info; + +typedef struct dir_entry { + char name[8],ext[3]; /* Name and extension */ + __u8 attr; /* Attribute bits */ + __u8 lcase; /* Case for base and extension */ + __u8 ctime_ms; /* Creation time, milliseconds */ + __u16 ctime; /* Creation time */ + __u16 cdate; /* Creation date */ + __u16 adate; /* Last access date */ + __u16 starthi; /* High 16 bits of cluster in FAT32 */ + __u16 time,date,start;/* Time, date and first cluster */ + __u32 size; /* File size in bytes */ +} dir_entry; + +typedef struct dir_slot { + __u8 id; /* Sequence number for slot */ + __u8 name0_4[10]; /* First 5 characters in name */ + __u8 attr; /* Attribute byte */ + __u8 reserved; /* Unused */ + __u8 alias_checksum;/* Checksum for 8.3 alias */ + __u8 name5_10[12]; /* 6 more characters in name */ + __u16 start; /* Unused */ + __u8 name11_12[4]; /* Last 2 characters in name */ +} dir_slot; + +/* Private filesystem parameters */ +typedef struct { + int fatsize; /* Size of FAT in bits */ + __u16 fatlength; /* Length of FAT in sectors */ + __u16 fat_sect; /* Starting sector of the FAT */ + __u16 rootdir_sect; /* Start sector of root directory */ + __u16 clust_size; /* Size of clusters in sectors */ + short data_begin; /* The sector of the first cluster, can be negative */ + __u32 fatbuf[FATBUFSIZE]; /* Current FAT buffer */ + int fatbufnum; /* Used by get_fatent, init to -1 */ +} fsdata; + +typedef int (file_detectfs_func)(void); +typedef int (file_ls_func)(const char *dir); +typedef long (file_read_func)(const char *filename, void *buffer, + unsigned long maxsize); + +struct filesystem { + file_detectfs_func *detect; + file_ls_func *ls; + file_read_func *read; + const char name[12]; +}; + +/* FAT tables */ +file_detectfs_func file_fat_detectfs; +file_ls_func file_fat_ls; +file_read_func file_fat_read; + +/* Currently this doesn't check if the dir exists or is valid... */ +int file_cd(const char *path); +int file_fat_detectfs(void); +int file_fat_ls(const char *dir); +long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); +const char *file_getfsname(int idx); +int fat_register_device(block_dev_desc_t *dev_desc, int part_no); + +#endif /* _FAT_H_ */
diff --git a/x-loader/include/ide.h b/x-loader/include/ide.h new file mode 100644 index 0000000..dfef32f --- /dev/null +++ b/x-loader/include/ide.h
@@ -0,0 +1,55 @@ +/* + * (C) Copyright 2000 + * 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 + */ + +#ifndef _IDE_H +#define _IDE_H + +#define IDE_BUS(dev) (dev >> 1) + +#ifdef CONFIG_IDE_LED + +/* + * LED Port + */ +#define LED_PORT ((uchar *)(PER8_BASE + 0x3000)) +#define LED_IDE1 0x01 +#define LED_IDE2 0x02 +#define DEVICE_LED(d) ((d & 2) | ((d & 2) == 0)) /* depends on bit positions! */ + +#endif /* CONFIG_IDE_LED */ + +#ifdef CFG_64BIT_LBA +typedef uint64_t lbaint_t; +#else +typedef ulong lbaint_t; +#endif + +/* + * Function Prototypes + */ + +void ide_init (void); +ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); +ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); + +#endif /* _IDE_H */
diff --git a/x-loader/include/image.h b/x-loader/include/image.h new file mode 100644 index 0000000..c278e90 --- /dev/null +++ b/x-loader/include/image.h
@@ -0,0 +1,679 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (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 + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef __IMAGE_H__ +#define __IMAGE_H__ + +#include "compiler.h" + +#ifdef USE_HOSTCC + +/* new uImage format support enabled on host */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + +#else + +#include <command.h> + +#endif /* USE_HOSTCC */ + +#if defined(CONFIG_FIT) +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> +#define CONFIG_MD5 /* FIT images need MD5 support */ +#define CONFIG_SHA1 /* and SHA1 */ +#endif + +/* + * Operating System Codes + */ +#define IH_OS_INVALID 0 /* Invalid OS */ +#define IH_OS_OPENBSD 1 /* OpenBSD */ +#define IH_OS_NETBSD 2 /* NetBSD */ +#define IH_OS_FREEBSD 3 /* FreeBSD */ +#define IH_OS_4_4BSD 4 /* 4.4BSD */ +#define IH_OS_LINUX 5 /* Linux */ +#define IH_OS_SVR4 6 /* SVR4 */ +#define IH_OS_ESIX 7 /* Esix */ +#define IH_OS_SOLARIS 8 /* Solaris */ +#define IH_OS_IRIX 9 /* Irix */ +#define IH_OS_SCO 10 /* SCO */ +#define IH_OS_DELL 11 /* Dell */ +#define IH_OS_NCR 12 /* NCR */ +#define IH_OS_LYNXOS 13 /* LynxOS */ +#define IH_OS_VXWORKS 14 /* VxWorks */ +#define IH_OS_PSOS 15 /* pSOS */ +#define IH_OS_QNX 16 /* QNX */ +#define IH_OS_U_BOOT 17 /* Firmware */ +#define IH_OS_RTEMS 18 /* RTEMS */ +#define IH_OS_ARTOS 19 /* ARTOS */ +#define IH_OS_UNITY 20 /* Unity OS */ +#define IH_OS_INTEGRITY 21 /* INTEGRITY */ + +/* + * CPU Architecture Codes (supported by Linux) + */ +#define IH_ARCH_INVALID 0 /* Invalid CPU */ +#define IH_ARCH_ALPHA 1 /* Alpha */ +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_I386 3 /* Intel x86 */ +#define IH_ARCH_IA64 4 /* IA64 */ +#define IH_ARCH_MIPS 5 /* MIPS */ +#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ +#define IH_ARCH_PPC 7 /* PowerPC */ +#define IH_ARCH_S390 8 /* IBM S390 */ +#define IH_ARCH_SH 9 /* SuperH */ +#define IH_ARCH_SPARC 10 /* Sparc */ +#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ +#define IH_ARCH_M68K 12 /* M68K */ +#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ +#define IH_ARCH_NIOS2 15 /* Nios-II */ +#define IH_ARCH_BLACKFIN 16 /* Blackfin */ +#define IH_ARCH_AVR32 17 /* AVR32 */ +#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ + +/* + * Image Types + * + * "Standalone Programs" are directly runnable in the environment + * provided by U-Boot; it is expected that (if they behave + * well) you can continue to work in U-Boot after return from + * the Standalone Program. + * "OS Kernel Images" are usually images of some Embedded OS which + * will take over control completely. Usually these programs + * will install their own set of exception handlers, device + * drivers, set up the MMU, etc. - this means, that you cannot + * expect to re-enter U-Boot except by resetting the CPU. + * "RAMDisk Images" are more or less just data blocks, and their + * parameters (address, size) are passed to an OS kernel that is + * being started. + * "Multi-File Images" contain several images, typically an OS + * (Linux) kernel image and one or more data images like + * RAMDisks. This construct is useful for instance when you want + * to boot over the network using BOOTP etc., where the boot + * server provides just a single image file, but you want to get + * for instance an OS kernel and a RAMDisk image. + * + * "Multi-File Images" start with a list of image sizes, each + * image size (in bytes) specified by an "uint32_t" in network + * byte order. This list is terminated by an "(uint32_t)0". + * Immediately after the terminating 0 follow the images, one by + * one, all aligned on "uint32_t" boundaries (size rounded up to + * a multiple of 4 bytes - except for the last file). + * + * "Firmware Images" are binary images containing firmware (like + * U-Boot or FPGA images) which usually will be programmed to + * flash memory. + * + * "Script files" are command sequences that will be executed by + * U-Boot's command interpreter; this feature is especially + * useful when you configure U-Boot to use a real shell (hush) + * as command interpreter (=> Shell Scripts). + */ + +#define IH_TYPE_INVALID 0 /* Invalid Image */ +#define IH_TYPE_STANDALONE 1 /* Standalone Program */ +#define IH_TYPE_KERNEL 2 /* OS Kernel Image */ +#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ +#define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Firmware Image */ +#define IH_TYPE_SCRIPT 6 /* Script file */ +#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */ +#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */ +#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */ +#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */ + +/* + * Compression Types + */ +#define IH_COMP_NONE 0 /* No Compression Used */ +#define IH_COMP_GZIP 1 /* gzip Compression Used */ +#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */ +#define IH_COMP_LZMA 3 /* lzma Compression Used */ +#define IH_COMP_LZO 4 /* lzo Compression Used */ + +#define IH_MAGIC 0x27051956 /* Image Magic Number */ +#define IH_NMLEN 32 /* Image Name Length */ + +/* + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). + */ +typedef struct image_header { + uint32_t ih_magic; /* Image Header Magic Number */ + uint32_t ih_hcrc; /* Image Header CRC Checksum */ + uint32_t ih_time; /* Image Creation Timestamp */ + uint32_t ih_size; /* Image Data Size */ + uint32_t ih_load; /* Data Load Address */ + uint32_t ih_ep; /* Entry Point Address */ + uint32_t ih_dcrc; /* Image Data CRC Checksum */ + uint8_t ih_os; /* Operating System */ + uint8_t ih_arch; /* CPU architecture */ + uint8_t ih_type; /* Image Type */ + uint8_t ih_comp; /* Compression Type */ + uint8_t ih_name[IH_NMLEN]; /* Image Name */ +} image_header_t; + +typedef struct image_info { + ulong start, end; /* start/end of blob */ + ulong image_start, image_len; /* start of image within blob, len of image */ + ulong load; /* load addr for the image */ + uint8_t comp, type, os; /* compression, type of image, os type */ +} image_info_t; + +/* + * Legacy and FIT format headers used by do_bootm() and do_bootm_<os>() + * routines. + */ +struct bd; + +typedef struct bootm_headers { + /* + * Legacy os image header, if it is a multi component image + * then boot_get_ramdisk() and get_fdt() will attempt to get + * data from second and third component accordingly. + */ + image_header_t *legacy_hdr_os; /* image header pointer */ + image_header_t legacy_hdr_os_copy; /* header copy */ + ulong legacy_hdr_valid; + +#if defined(CONFIG_FIT) + const char *fit_uname_cfg; /* configuration node unit name */ + + void *fit_hdr_os; /* os FIT image header */ + const char *fit_uname_os; /* os subimage node unit name */ + int fit_noffset_os; /* os subimage node offset */ + + void *fit_hdr_rd; /* init ramdisk FIT image header */ + const char *fit_uname_rd; /* init ramdisk subimage node unit name */ + int fit_noffset_rd; /* init ramdisk subimage node offset */ + + void *fit_hdr_fdt; /* FDT blob FIT image header */ + const char *fit_uname_fdt; /* FDT blob subimage node unit name */ + int fit_noffset_fdt;/* FDT blob subimage node offset */ +#endif + +#ifndef USE_HOSTCC + image_info_t os; /* os image info */ + ulong ep; /* entry point of OS */ + + ulong rd_start, rd_end;/* ramdisk start/end */ + +#ifdef CONFIG_OF_LIBFDT + char *ft_addr; /* flat dev tree address */ +#endif + ulong ft_len; /* length of flat device tree */ + + ulong initrd_start; + ulong initrd_end; + ulong cmdline_start; + ulong cmdline_end; + struct bd *kbd; +#endif + + int verify; /* getenv("verify")[0] != 'n' */ + +#define BOOTM_STATE_START (0x00000001) +#define BOOTM_STATE_LOADOS (0x00000002) +#define BOOTM_STATE_RAMDISK (0x00000004) +#define BOOTM_STATE_FDT (0x00000008) +#define BOOTM_STATE_OS_CMDLINE (0x00000010) +#define BOOTM_STATE_OS_BD_T (0x00000020) +#define BOOTM_STATE_OS_PREP (0x00000040) +#define BOOTM_STATE_OS_GO (0x00000080) + int state; + +#ifdef CONFIG_LMB + struct lmb lmb; /* for memory mgmt */ +#endif +} bootm_headers_t; + +/* + * Some systems (for example LWMON) have very short watchdog periods; + * we must make sure to split long operations like memmove() or + * checksum calculations into reasonable chunks. + */ +#ifndef CHUNKSZ +#define CHUNKSZ (64 * 1024) +#endif + +#ifndef CHUNKSZ_CRC32 +#define CHUNKSZ_CRC32 (64 * 1024) +#endif + +#ifndef CHUNKSZ_MD5 +#define CHUNKSZ_MD5 (64 * 1024) +#endif + +#ifndef CHUNKSZ_SHA1 +#define CHUNKSZ_SHA1 (64 * 1024) +#endif + +#define uimage_to_cpu(x) be32_to_cpu(x) +#define cpu_to_uimage(x) cpu_to_be32(x) + +/* + * Translation table for entries of a specific type; used by + * get_table_entry_id() and get_table_entry_name(). + */ +typedef struct table_entry { + int id; + char *sname; /* short (input) name to find table entry */ + char *lname; /* long (output) name to print for messages */ +} table_entry_t; + +/* + * get_table_entry_id() scans the translation table trying to find an + * entry that matches the given short name. If a matching entry is + * found, it's id is returned to the caller. + */ +int get_table_entry_id (table_entry_t *table, + const char *table_name, const char *name); +/* + * get_table_entry_name() scans the translation table trying to find + * an entry that matches the given id. If a matching entry is found, + * its long name is returned to the caller. + */ +char *get_table_entry_name (table_entry_t *table, char *msg, int id); + +const char *genimg_get_os_name (uint8_t os); +const char *genimg_get_arch_name (uint8_t arch); +const char *genimg_get_type_name (uint8_t type); +const char *genimg_get_comp_name (uint8_t comp); +int genimg_get_os_id (const char *name); +int genimg_get_arch_id (const char *name); +int genimg_get_type_id (const char *name); +int genimg_get_comp_id (const char *name); +void genimg_print_size (uint32_t size); + +#ifndef USE_HOSTCC +/* Image format types, returned by _get_format() routine */ +#define IMAGE_FORMAT_INVALID 0x00 +#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ +#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ + +int genimg_get_format (void *img_addr); +int genimg_has_config (bootm_headers_t *images); +ulong genimg_get_image (ulong img_addr); + +int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end); + + +#ifdef CONFIG_OF_LIBFDT +int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, + char **of_flat_tree, ulong *of_size); +int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + char **of_flat_tree, ulong *of_size); +#endif + +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end); + +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base); +int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); +#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* !USE_HOSTCC */ + +/*******************************************************************/ +/* Legacy format specific code (prefixed with image_) */ +/*******************************************************************/ +static inline uint32_t image_get_header_size (void) +{ + return (sizeof (image_header_t)); +} + +#define image_get_hdr_l(f) \ + static inline uint32_t image_get_##f(const image_header_t *hdr) \ + { \ + return uimage_to_cpu (hdr->ih_##f); \ + } +image_get_hdr_l (magic) /* image_get_magic */ +image_get_hdr_l (hcrc) /* image_get_hcrc */ +image_get_hdr_l (time) /* image_get_time */ +image_get_hdr_l (size) /* image_get_size */ +image_get_hdr_l (load) /* image_get_load */ +image_get_hdr_l (ep) /* image_get_ep */ +image_get_hdr_l (dcrc) /* image_get_dcrc */ + +#define image_get_hdr_b(f) \ + static inline uint8_t image_get_##f(const image_header_t *hdr) \ + { \ + return hdr->ih_##f; \ + } +image_get_hdr_b (os) /* image_get_os */ +image_get_hdr_b (arch) /* image_get_arch */ +image_get_hdr_b (type) /* image_get_type */ +image_get_hdr_b (comp) /* image_get_comp */ + +static inline char *image_get_name (const image_header_t *hdr) +{ + return (char *)hdr->ih_name; +} + +static inline uint32_t image_get_data_size (const image_header_t *hdr) +{ + return image_get_size (hdr); +} + +/** + * image_get_data - get image payload start address + * @hdr: image header + * + * image_get_data() returns address of the image payload. For single + * component images it is image data start. For multi component + * images it points to the null terminated table of sub-images sizes. + * + * returns: + * image payload data start address + */ +static inline ulong image_get_data (const image_header_t *hdr) +{ + return ((ulong)hdr + image_get_header_size ()); +} + +static inline uint32_t image_get_image_size (const image_header_t *hdr) +{ + return (image_get_size (hdr) + image_get_header_size ()); +} +static inline ulong image_get_image_end (const image_header_t *hdr) +{ + return ((ulong)hdr + image_get_image_size (hdr)); +} + +#define image_set_hdr_l(f) \ + static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + { \ + hdr->ih_##f = cpu_to_uimage (val); \ + } +image_set_hdr_l (magic) /* image_set_magic */ +image_set_hdr_l (hcrc) /* image_set_hcrc */ +image_set_hdr_l (time) /* image_set_time */ +image_set_hdr_l (size) /* image_set_size */ +image_set_hdr_l (load) /* image_set_load */ +image_set_hdr_l (ep) /* image_set_ep */ +image_set_hdr_l (dcrc) /* image_set_dcrc */ + +#define image_set_hdr_b(f) \ + static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + { \ + hdr->ih_##f = val; \ + } +image_set_hdr_b (os) /* image_set_os */ +image_set_hdr_b (arch) /* image_set_arch */ +image_set_hdr_b (type) /* image_set_type */ +image_set_hdr_b (comp) /* image_set_comp */ + +static inline void image_set_name (image_header_t *hdr, const char *name) +{ + strncpy (image_get_name (hdr), name, IH_NMLEN); +} + +int image_check_hcrc (const image_header_t *hdr); +int image_check_dcrc (const image_header_t *hdr); +#ifndef USE_HOSTCC +int getenv_yesno (char *var); +ulong getenv_bootm_low(void); +phys_size_t getenv_bootm_size(void); +void memmove_wd (void *to, void *from, size_t len, ulong chunksz); +#endif + +static inline int image_check_magic (const image_header_t *hdr) +{ + return (image_get_magic (hdr) == IH_MAGIC); +} +static inline int image_check_type (const image_header_t *hdr, uint8_t type) +{ + return (image_get_type (hdr) == type); +} +static inline int image_check_arch (const image_header_t *hdr, uint8_t arch) +{ + return (image_get_arch (hdr) == arch); +} +static inline int image_check_os (const image_header_t *hdr, uint8_t os) +{ + return (image_get_os (hdr) == os); +} + +ulong image_multi_count (const image_header_t *hdr); +void image_multi_getimg (const image_header_t *hdr, ulong idx, + ulong *data, ulong *len); + +void image_print_contents (const void *hdr); + +#ifndef USE_HOSTCC +static inline int image_check_target_arch (const image_header_t *hdr) +{ +#if defined(__ARM__) + if (!image_check_arch (hdr, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!image_check_arch (hdr, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!image_check_arch (hdr, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!image_check_arch (hdr, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!image_check_arch (hdr, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!image_check_arch (hdr, IH_ARCH_MIPS)) +#elif defined(__nios2__) + if (!image_check_arch (hdr, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!image_check_arch (hdr, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!image_check_arch (hdr, IH_ARCH_SH)) +#elif defined(__sparc__) + if (!image_check_arch (hdr, IH_ARCH_SPARC)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + +/*******************************************************************/ +/* New uImage format specific code (prefixed with fit_) */ +/*******************************************************************/ +#if defined(CONFIG_FIT) + +#define FIT_IMAGES_PATH "/images" +#define FIT_CONFS_PATH "/configurations" + +/* hash node */ +#define FIT_HASH_NODENAME "hash" +#define FIT_ALGO_PROP "algo" +#define FIT_VALUE_PROP "value" + +/* image node */ +#define FIT_DATA_PROP "data" +#define FIT_TIMESTAMP_PROP "timestamp" +#define FIT_DESC_PROP "description" +#define FIT_ARCH_PROP "arch" +#define FIT_TYPE_PROP "type" +#define FIT_OS_PROP "os" +#define FIT_COMP_PROP "compression" +#define FIT_ENTRY_PROP "entry" +#define FIT_LOAD_PROP "load" + +/* configuration node */ +#define FIT_KERNEL_PROP "kernel" +#define FIT_RAMDISK_PROP "ramdisk" +#define FIT_FDT_PROP "fdt" +#define FIT_DEFAULT_PROP "default" + +#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */ + +/* cmdline argument format parsing */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name); +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name); + +void fit_print_contents (const void *fit); +void fit_image_print (const void *fit, int noffset, const char *p); +void fit_image_print_hash (const void *fit, int noffset, const char *p); + +/** + * fit_get_end - get FIT image size + * @fit: pointer to the FIT format image header + * + * returns: + * size of the FIT image (blob) in memory + */ +static inline ulong fit_get_size (const void *fit) +{ + return fdt_totalsize (fit); +} + +/** + * fit_get_end - get FIT image end + * @fit: pointer to the FIT format image header + * + * returns: + * end address of the FIT image (blob) in memory + */ +static inline ulong fit_get_end (const void *fit) +{ + return (ulong)fit + fdt_totalsize (fit); +} + +/** + * fit_get_name - get FIT node name + * @fit: pointer to the FIT format image header + * + * returns: + * NULL, on error + * pointer to node name, on success + */ +static inline const char *fit_get_name (const void *fit_hdr, + int noffset, int *len) +{ + return fdt_get_name (fit_hdr, noffset, len); +} + +int fit_get_desc (const void *fit, int noffset, char **desc); +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp); + +int fit_image_get_node (const void *fit, const char *image_uname); +int fit_image_get_os (const void *fit, int noffset, uint8_t *os); +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch); +int fit_image_get_type (const void *fit, int noffset, uint8_t *type); +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp); +int fit_image_get_load (const void *fit, int noffset, ulong *load); +int fit_image_get_entry (const void *fit, int noffset, ulong *entry); +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size); + +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo); +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len); + +int fit_set_timestamp (void *fit, int noffset, time_t timestamp); +int fit_set_hashes (void *fit); +int fit_image_set_hashes (void *fit, int image_noffset); +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len); + +int fit_image_check_hashes (const void *fit, int noffset); +int fit_all_image_check_hashes (const void *fit); +int fit_image_check_os (const void *fit, int noffset, uint8_t os); +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch); +int fit_image_check_type (const void *fit, int noffset, uint8_t type); +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp); +int fit_check_format (const void *fit); + +int fit_conf_get_node (const void *fit, const char *conf_uname); +int fit_conf_get_kernel_node (const void *fit, int noffset); +int fit_conf_get_ramdisk_node (const void *fit, int noffset); +int fit_conf_get_fdt_node (const void *fit, int noffset); + +void fit_conf_print (const void *fit, int noffset, const char *p); + +#ifndef USE_HOSTCC +static inline int fit_image_check_target_arch (const void *fdt, int node) +{ +#if defined(__ARM__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS)) +#elif defined(__nios2__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SH)) +#elif defined(__sparc__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SPARC)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + +#ifdef CONFIG_FIT_VERBOSE +#define fit_unsupported(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s'\n", \ + __FILE__, __LINE__, (msg)) + +#define fit_unsupported_reset(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s' " \ + "- must reset board to recover!\n", \ + __FILE__, __LINE__, (msg)) +#else +#define fit_unsupported(msg) +#define fit_unsupported_reset(msg) +#endif /* CONFIG_FIT_VERBOSE */ +#endif /* CONFIG_FIT */ + +#endif /* __IMAGE_H__ */
diff --git a/x-loader/include/linux/byteorder/big_endian.h b/x-loader/include/linux/byteorder/big_endian.h new file mode 100755 index 0000000..19b0c86 --- /dev/null +++ b/x-loader/include/linux/byteorder/big_endian.h
@@ -0,0 +1,69 @@ +#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H +#define _LINUX_BYTEORDER_BIG_ENDIAN_H + +#ifndef __BIG_ENDIAN +#define __BIG_ENDIAN 4321 +#endif +#ifndef __BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN_BITFIELD +#endif +#define __BYTE_ORDER __BIG_ENDIAN + +#include <linux/byteorder/swab.h> + +#define __constant_htonl(x) ((__u32)(x)) +#define __constant_ntohl(x) ((__u32)(x)) +#define __constant_htons(x) ((__u16)(x)) +#define __constant_ntohs(x) ((__u16)(x)) +#define __constant_cpu_to_le64(x) ___swab64((x)) +#define __constant_le64_to_cpu(x) ___swab64((x)) +#define __constant_cpu_to_le32(x) ___swab32((x)) +#define __constant_le32_to_cpu(x) ___swab32((x)) +#define __constant_cpu_to_le16(x) ___swab16((x)) +#define __constant_le16_to_cpu(x) ___swab16((x)) +#define __constant_cpu_to_be64(x) ((__u64)(x)) +#define __constant_be64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_be32(x) ((__u32)(x)) +#define __constant_be32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_be16(x) ((__u16)(x)) +#define __constant_be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64(x) __swab64((x)) +#define __le64_to_cpu(x) __swab64((x)) +#define __cpu_to_le32(x) __swab32((x)) +#define __le32_to_cpu(x) __swab32((x)) +#define __cpu_to_le16(x) __swab16((x)) +#define __le16_to_cpu(x) __swab16((x)) +#define __cpu_to_be64(x) ((__u64)(x)) +#define __be64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_be32(x) ((__u32)(x)) +#define __be32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_be16(x) ((__u16)(x)) +#define __be16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_le64p(x) __swab64p((x)) +#define __le64_to_cpup(x) __swab64p((x)) +#define __cpu_to_le32p(x) __swab32p((x)) +#define __le32_to_cpup(x) __swab32p((x)) +#define __cpu_to_le16p(x) __swab16p((x)) +#define __le16_to_cpup(x) __swab16p((x)) +#define __cpu_to_be64p(x) (*(__u64*)(x)) +#define __be64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_be32p(x) (*(__u32*)(x)) +#define __be32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_be16p(x) (*(__u16*)(x)) +#define __be16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_le64s(x) __swab64s((x)) +#define __le64_to_cpus(x) __swab64s((x)) +#define __cpu_to_le32s(x) __swab32s((x)) +#define __le32_to_cpus(x) __swab32s((x)) +#define __cpu_to_le16s(x) __swab16s((x)) +#define __le16_to_cpus(x) __swab16s((x)) +#define __cpu_to_be64s(x) do {} while (0) +#define __be64_to_cpus(x) do {} while (0) +#define __cpu_to_be32s(x) do {} while (0) +#define __be32_to_cpus(x) do {} while (0) +#define __cpu_to_be16s(x) do {} while (0) +#define __be16_to_cpus(x) do {} while (0) + +#include <linux/byteorder/generic.h> + +#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */
diff --git a/x-loader/include/linux/byteorder/generic.h b/x-loader/include/linux/byteorder/generic.h new file mode 100755 index 0000000..cff850f --- /dev/null +++ b/x-loader/include/linux/byteorder/generic.h
@@ -0,0 +1,180 @@ +#ifndef _LINUX_BYTEORDER_GENERIC_H +#define _LINUX_BYTEORDER_GENERIC_H + +/* + * linux/byteorder_generic.h + * Generic Byte-reordering support + * + * Francois-Rene Rideau <fare@tunes.org> 19970707 + * gathered all the good ideas from all asm-foo/byteorder.h into one file, + * cleaned them up. + * I hope it is compliant with non-GCC compilers. + * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, + * because I wasn't sure it would be ok to put it in types.h + * Upgraded it to 2.1.43 + * Francois-Rene Rideau <fare@tunes.org> 19971012 + * Upgraded it to 2.1.57 + * to please Linus T., replaced huge #ifdef's between little/big endian + * by nestedly #include'd files. + * Francois-Rene Rideau <fare@tunes.org> 19971205 + * Made it to 2.1.71; now a facelift: + * Put files under include/linux/byteorder/ + * Split swab from generic support. + * + * TODO: + * = Regular kernel maintainers could also replace all these manual + * byteswap macros that remain, disseminated among drivers, + * after some grep or the sources... + * = Linus might want to rename all these macros and files to fit his taste, + * to fit his personal naming scheme. + * = it seems that a few drivers would also appreciate + * nybble swapping support... + * = every architecture could add their byteswap macro in asm/byteorder.h + * see how some architectures already do (i386, alpha, ppc, etc) + * = cpu_to_beXX and beXX_to_cpu might some day need to be well + * distinguished throughout the kernel. This is not the case currently, + * since little endian, big endian, and pdp endian machines needn't it. + * But this might be the case for, say, a port of Linux to 20/21 bit + * architectures (and F21 Linux addict around?). + */ + +/* + * The following macros are to be defined by <asm/byteorder.h>: + * + * Conversion of long and short int between network and host format + * ntohl(__u32 x) + * ntohs(__u16 x) + * htonl(__u32 x) + * htons(__u16 x) + * It seems that some programs (which? where? or perhaps a standard? POSIX?) + * might like the above to be functions, not macros (why?). + * if that's true, then detect them, and take measures. + * Anyway, the measure is: define only ___ntohl as a macro instead, + * and in a separate file, have + * unsigned long inline ntohl(x){return ___ntohl(x);} + * + * The same for constant arguments + * __constant_ntohl(__u32 x) + * __constant_ntohs(__u16 x) + * __constant_htonl(__u32 x) + * __constant_htons(__u16 x) + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + * + */ + + +#if defined(__KERNEL__) +/* + * inside the kernel, we can use nicknames; + * outside of it, we must avoid POSIX namespace pollution... + */ +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus +#endif + + +/* + * Handle ntohl and suches. These have various compatibility + * issues - like we want to give the prototype even though we + * also have a macro for them in case some strange program + * wants to take the address of the thing or something.. + * + * Note that these used to return a "long" in libc5, even though + * long is often 64-bit these days.. Thus the casts. + * + * They have to be macros in order to do the constant folding + * correctly - if the argument passed into a inline function + * it is no longer constant according to gcc.. + */ + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +/* + * Do the prototypes. Somebody might want to take the + * address or some such sick thing.. + */ +#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2) +extern __u32 ntohl(__u32); +extern __u32 htonl(__u32); +#else +extern unsigned long int ntohl(unsigned long int); +extern unsigned long int htonl(unsigned long int); +#endif +extern unsigned short int ntohs(unsigned short int); +extern unsigned short int htons(unsigned short int); + + +#if defined(__GNUC__) && (__GNUC__ >= 2) + +#define ___htonl(x) __cpu_to_be32(x) +#define ___htons(x) __cpu_to_be16(x) +#define ___ntohl(x) __be32_to_cpu(x) +#define ___ntohs(x) __be16_to_cpu(x) + +#if defined(__KERNEL__) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#else +#define htonl(x) ((unsigned long)___htonl(x)) +#define ntohl(x) ((unsigned long)___ntohl(x)) +#endif +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#endif /* OPTIMIZE */ + + +#endif /* _LINUX_BYTEORDER_GENERIC_H */
diff --git a/x-loader/include/linux/byteorder/little_endian.h b/x-loader/include/linux/byteorder/little_endian.h new file mode 100755 index 0000000..a46f3ec --- /dev/null +++ b/x-loader/include/linux/byteorder/little_endian.h
@@ -0,0 +1,69 @@ +#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H +#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif +#define __BYTE_ORDER __LITTLE_ENDIAN + +#include <linux/byteorder/swab.h> + +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) +#define __constant_cpu_to_le64(x) ((__u64)(x)) +#define __constant_le64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_le32(x) ((__u32)(x)) +#define __constant_le32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le16(x) ((__u16)(x)) +#define __constant_le16_to_cpu(x) ((__u16)(x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) +#define __cpu_to_le64(x) ((__u64)(x)) +#define __le64_to_cpu(x) ((__u64)(x)) +#define __cpu_to_le32(x) ((__u32)(x)) +#define __le32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le16(x) ((__u16)(x)) +#define __le16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_be64(x) __swab64((x)) +#define __be64_to_cpu(x) __swab64((x)) +#define __cpu_to_be32(x) __swab32((x)) +#define __be32_to_cpu(x) __swab32((x)) +#define __cpu_to_be16(x) __swab16((x)) +#define __be16_to_cpu(x) __swab16((x)) +#define __cpu_to_le64p(x) (*(__u64*)(x)) +#define __le64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_le32p(x) (*(__u32*)(x)) +#define __le32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le16p(x) (*(__u16*)(x)) +#define __le16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_be64p(x) __swab64p((x)) +#define __be64_to_cpup(x) __swab64p((x)) +#define __cpu_to_be32p(x) __swab32p((x)) +#define __be32_to_cpup(x) __swab32p((x)) +#define __cpu_to_be16p(x) __swab16p((x)) +#define __be16_to_cpup(x) __swab16p((x)) +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) + +#include <linux/byteorder/generic.h> + +#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */
diff --git a/x-loader/include/linux/byteorder/swab.h b/x-loader/include/linux/byteorder/swab.h new file mode 100755 index 0000000..b1d570e --- /dev/null +++ b/x-loader/include/linux/byteorder/swab.h
@@ -0,0 +1,158 @@ +#ifndef _LINUX_BYTEORDER_SWAB_H +#define _LINUX_BYTEORDER_SWAB_H + +/* + * linux/byteorder/swab.h + * Byte-swapping, independently from CPU endianness + * swabXX[ps]?(foo) + * + * Francois-Rene Rideau <fare@tunes.org> 19971205 + * separated swab functions from cpu_to_XX, + * to clean up support for bizarre-endian architectures. + * + * See asm-i386/byteorder.h and suches for examples of how to provide + * architecture-dependent optimized versions + * + */ + +/* casts are necessary for constants, because we never know how for sure + * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. + */ +#define ___swab16(x) \ + ((__u16)( \ + (((__u16)(x) & (__u16)0x00ffU) << 8) | \ + (((__u16)(x) & (__u16)0xff00U) >> 8) )) +#define ___swab32(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +#define ___swab64(x) \ + ((__u64)( \ + (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) )) + +/* + * provide defaults when no architecture-specific optimization is detected + */ +#ifndef __arch__swab16 +# define __arch__swab16(x) ___swab16(x) +#endif +#ifndef __arch__swab32 +# define __arch__swab32(x) ___swab32(x) +#endif +#ifndef __arch__swab64 +# define __arch__swab64(x) ___swab64(x) +#endif + +#ifndef __arch__swab16p +# define __arch__swab16p(x) __swab16(*(x)) +#endif +#ifndef __arch__swab32p +# define __arch__swab32p(x) __swab32(*(x)) +#endif +#ifndef __arch__swab64p +# define __arch__swab64p(x) __swab64(*(x)) +#endif + +#ifndef __arch__swab16s +# define __arch__swab16s(x) do { *(x) = __swab16p((x)); } while (0) +#endif +#ifndef __arch__swab32s +# define __arch__swab32s(x) do { *(x) = __swab32p((x)); } while (0) +#endif +#ifndef __arch__swab64s +# define __arch__swab64s(x) do { *(x) = __swab64p((x)); } while (0) +#endif + + +/* + * Allow constant folding + */ +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) +# define __swab16(x) \ +(__builtin_constant_p((__u16)(x)) ? \ + ___swab16((x)) : \ + __fswab16((x))) +# define __swab32(x) \ +(__builtin_constant_p((__u32)(x)) ? \ + ___swab32((x)) : \ + __fswab32((x))) +# define __swab64(x) \ +(__builtin_constant_p((__u64)(x)) ? \ + ___swab64((x)) : \ + __fswab64((x))) +#else +# define __swab16(x) __fswab16(x) +# define __swab32(x) __fswab32(x) +# define __swab64(x) __fswab64(x) +#endif /* OPTIMIZE */ + + +static __inline__ __attribute__((const)) __u16 __fswab16(__u16 x) +{ + return __arch__swab16(x); +} +static __inline__ __u16 __swab16p(__u16 *x) +{ + return __arch__swab16p(x); +} +static __inline__ void __swab16s(__u16 *addr) +{ + __arch__swab16s(addr); +} + +static __inline__ __attribute__((const)) __u32 __fswab32(__u32 x) +{ + return __arch__swab32(x); +} +static __inline__ __u32 __swab32p(__u32 *x) +{ + return __arch__swab32p(x); +} +static __inline__ void __swab32s(__u32 *addr) +{ + __arch__swab32s(addr); +} + +#ifdef __BYTEORDER_HAS_U64__ +static __inline__ __attribute__((const)) __u64 __fswab64(__u64 x) +{ +# ifdef __SWAB_64_THRU_32__ + __u32 h = x >> 32; + __u32 l = x & ((1ULL<<32)-1); + return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h))); +# else + return __arch__swab64(x); +# endif +} +static __inline__ __u64 __swab64p(__u64 *x) +{ + return __arch__swab64p(x); +} +static __inline__ void __swab64s(__u64 *addr) +{ + __arch__swab64s(addr); +} +#endif /* __BYTEORDER_HAS_U64__ */ + +#if defined(__KERNEL__) +#define swab16 __swab16 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab32s __swab32s +#define swab64s __swab64s +#endif + +#endif /* _LINUX_BYTEORDER_SWAB_H */
diff --git a/x-loader/include/linux/config.h b/x-loader/include/linux/config.h new file mode 100644 index 0000000..a0194cb --- /dev/null +++ b/x-loader/include/linux/config.h
@@ -0,0 +1,6 @@ +#ifndef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H + +/* #include <linux/autoconf.h> */ + +#endif
diff --git a/x-loader/include/linux/ctype.h b/x-loader/include/linux/ctype.h new file mode 100644 index 0000000..afa3639 --- /dev/null +++ b/x-loader/include/linux/ctype.h
@@ -0,0 +1,54 @@ +#ifndef _LINUX_CTYPE_H +#define _LINUX_CTYPE_H + +/* + * NOTE! This ctype does not handle EOF like the standard C + * library is required to. + */ + +#define _U 0x01 /* upper */ +#define _L 0x02 /* lower */ +#define _D 0x04 /* digit */ +#define _C 0x08 /* cntrl */ +#define _P 0x10 /* punct */ +#define _S 0x20 /* white space (space/lf/tab) */ +#define _X 0x40 /* hex digit */ +#define _SP 0x80 /* hard space (0x20) */ + +extern unsigned char _ctype[]; + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) + +#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0) +#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0) +#define iscntrl(c) ((__ismask(c)&(_C)) != 0) +#define isdigit(c) ((__ismask(c)&(_D)) != 0) +#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0) +#define islower(c) ((__ismask(c)&(_L)) != 0) +#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0) +#define ispunct(c) ((__ismask(c)&(_P)) != 0) +#define isspace(c) ((__ismask(c)&(_S)) != 0) +#define isupper(c) ((__ismask(c)&(_U)) != 0) +#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0) + +#define isascii(c) (((unsigned char)(c))<=0x7f) +#define toascii(c) (((unsigned char)(c))&0x7f) + +static inline unsigned char __tolower(unsigned char c) +{ + if (isupper(c)) + c -= 'A'-'a'; + return c; +} + +static inline unsigned char __toupper(unsigned char c) +{ + if (islower(c)) + c -= 'a'-'A'; + return c; +} + +#define tolower(c) __tolower(c) +#define toupper(c) __toupper(c) + +#endif
diff --git a/x-loader/include/linux/posix_types.h b/x-loader/include/linux/posix_types.h new file mode 100644 index 0000000..bd37e1f --- /dev/null +++ b/x-loader/include/linux/posix_types.h
@@ -0,0 +1,48 @@ +#ifndef _LINUX_POSIX_TYPES_H +#define _LINUX_POSIX_TYPES_H + +#include <linux/stddef.h> + +/* + * This allows for 1024 file descriptors: if NR_OPEN is ever grown + * beyond that you'll have to change this too. But 1024 fd's seem to be + * enough even for such "real" unices like OSF/1, so hopefully this is + * one limit that doesn't have to be changed [again]. + * + * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in + * <sys/time.h> (and thus <linux/time.h>) - but this is a more logical + * place for them. Solved by having dummy defines in <sys/time.h>. + */ + +/* + * Those macros may have been defined in <gnu/types.h>. But we always + * use the ones here. + */ +#undef __NFDBITS +#define __NFDBITS (8 * sizeof(unsigned long)) + +#undef __FD_SETSIZE +#define __FD_SETSIZE 1024 + +#undef __FDSET_LONGS +#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS) + +#undef __FDELT +#define __FDELT(d) ((d) / __NFDBITS) + +#undef __FDMASK +#define __FDMASK(d) (1UL << ((d) % __NFDBITS)) + +typedef struct { + unsigned long fds_bits [__FDSET_LONGS]; +} __kernel_fd_set; + +/* Type of a signal handler. */ +typedef void (*__kernel_sighandler_t)(int); + +/* Type of a SYSV IPC key. */ +typedef int __kernel_key_t; + +#include <asm/posix_types.h> + +#endif /* _LINUX_POSIX_TYPES_H */
diff --git a/x-loader/include/linux/stat.h b/x-loader/include/linux/stat.h new file mode 100755 index 0000000..f9422cb --- /dev/null +++ b/x-loader/include/linux/stat.h
@@ -0,0 +1,132 @@ +#ifndef _LINUX_STAT_H +#define _LINUX_STAT_H + +#include <linux/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define S_IFMT 00170000 /* type of file */ +#define S_IFSOCK 0140000 /* named socket */ +#define S_IFLNK 0120000 /* symbolic link */ +#define S_IFREG 0100000 /* regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFIFO 0010000 /* fifo */ +#define S_ISUID 0004000 /* set user id on execution */ +#define S_ISGID 0002000 /* set group id on execution */ +#define S_ISVTX 0001000 /* save swapped text even after use */ + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) + +#define S_IRWXU 00700 /* rwx for owner */ +#define S_IRUSR 00400 /* read permission for owner */ +#define S_IWUSR 00200 /* write permission for owner */ +#define S_IXUSR 00100 /* execute/search permission for owner */ + +#define S_IRWXG 00070 /* rwx for group */ +#define S_IRGRP 00040 /* read permission for group */ +#define S_IWGRP 00020 /* write permission for group */ +#define S_IXGRP 00010 /* execute/search permission for group */ + +#define S_IRWXO 00007 /* rwx for other */ +#define S_IROTH 00004 /* read permission for other */ +#define S_IWOTH 00002 /* read permission for other */ +#define S_IXOTH 00001 /* execute/search permission for other */ + +#ifdef __PPC__ + +struct stat { + dev_t st_dev; /* file system id */ + ino_t st_ino; /* file id */ + mode_t st_mode; /* ownership/protection */ + nlink_t st_nlink; /* number of links */ + uid_t st_uid; /* user id */ + gid_t st_gid; /* group id */ + dev_t st_rdev; + off_t st_size; /* file size in # of bytes */ + unsigned long st_blksize; /* block size */ + unsigned long st_blocks; /* file size in # of blocks */ + unsigned long st_atime; /* time file was last accessed */ + unsigned long __unused1; + unsigned long st_mtime; /* time file was last modified */ + unsigned long __unused2; + unsigned long st_ctime; /* time file status was last changed */ + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* __PPC__ */ + +#if defined (__ARM__) || defined (__I386__) || defined (__M68K__) || defined (__blackfin__) + +struct stat { + unsigned short st_dev; + unsigned short __pad1; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long __unused1; + unsigned long st_mtime; + unsigned long __unused2; + unsigned long st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +}; + +#endif /* __ARM__ */ + +#if defined (__MIPS__) + +struct stat { + dev_t st_dev; + long st_pad1[3]; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + long st_pad2[2]; + off_t st_size; + long st_pad3; + /* + * Actually this should be timestruc_t st_atime, st_mtime and st_ctime + * but we don't have it under Linux. + */ + time_t st_atime; + long reserved0; + time_t st_mtime; + long reserved1; + time_t st_ctime; + long reserved2; + long st_blksize; + long st_blocks; + long st_pad4[14]; +}; + +#endif /* __MIPS__ */ + +#ifdef __cplusplus +} +#endif + +#endif
diff --git a/x-loader/include/linux/stddef.h b/x-loader/include/linux/stddef.h new file mode 100644 index 0000000..81e34c2 --- /dev/null +++ b/x-loader/include/linux/stddef.h
@@ -0,0 +1,18 @@ +#ifndef _LINUX_STDDEF_H +#define _LINUX_STDDEF_H + +#undef NULL +#if defined(__cplusplus) +#define NULL 0 +#else +#define NULL ((void *)0) +#endif + +#ifndef _SIZE_T +#include <linux/types.h> +#endif + +#undef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#endif
diff --git a/x-loader/include/linux/string.h b/x-loader/include/linux/string.h new file mode 100644 index 0000000..6239039 --- /dev/null +++ b/x-loader/include/linux/string.h
@@ -0,0 +1,89 @@ +#ifndef _LINUX_STRING_H_ +#define _LINUX_STRING_H_ + +#include <linux/types.h> /* for size_t */ +#include <linux/stddef.h> /* for NULL */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char * ___strtok; +extern char * strpbrk(const char *,const char *); +extern char * strtok(char *,const char *); +extern char * strsep(char **,const char *); +extern __kernel_size_t strspn(const char *,const char *); + + +/* + * Include machine specific inline routines + */ +#include <asm/string.h> + +#ifndef __HAVE_ARCH_STRCPY +extern char * strcpy(char *,const char *); +#endif +#ifndef __HAVE_ARCH_STRNCPY +extern char * strncpy(char *,const char *, __kernel_size_t); +#endif +#ifndef __HAVE_ARCH_STRCAT +extern char * strcat(char *, const char *); +#endif +#ifndef __HAVE_ARCH_STRNCAT +extern char * strncat(char *, const char *, __kernel_size_t); +#endif +#ifndef __HAVE_ARCH_STRCMP +extern int strcmp(const char *,const char *); +#endif +#ifndef __HAVE_ARCH_STRNCMP +extern int strncmp(const char *,const char *,__kernel_size_t); +#endif +#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ +extern int strnicmp(const char *, const char *, __kernel_size_t); +#endif +#ifndef __HAVE_ARCH_STRCHR +extern char * strchr(const char *,int); +#endif +#ifndef __HAVE_ARCH_STRRCHR +extern char * strrchr(const char *,int); +#endif +#ifndef __HAVE_ARCH_STRSTR +extern char * strstr(const char *,const char *); +#endif +#ifndef __HAVE_ARCH_STRLEN +extern __kernel_size_t strlen(const char *); +#endif +#ifndef __HAVE_ARCH_STRNLEN +extern __kernel_size_t strnlen(const char *,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_STRDUP +extern char * strdup(const char *); +#endif +#ifndef __HAVE_ARCH_STRSWAB +extern char * strswab(const char *); +#endif + +#ifndef __HAVE_ARCH_MEMSET +extern void * memset(void *,int,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_MEMCPY +extern void * memcpy(void *,const void *,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_MEMMOVE +extern void * memmove(void *,const void *,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_MEMSCAN +extern void * memscan(void *,int,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_MEMCMP +extern int memcmp(const void *,const void *,__kernel_size_t); +#endif +#ifndef __HAVE_ARCH_MEMCHR +extern void * memchr(const void *,int,__kernel_size_t); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _LINUX_STRING_H_ */
diff --git a/x-loader/include/linux/time.h b/x-loader/include/linux/time.h new file mode 100755 index 0000000..bf12b99 --- /dev/null +++ b/x-loader/include/linux/time.h
@@ -0,0 +1,158 @@ +#ifndef _LINUX_TIME_H +#define _LINUX_TIME_H + +#include <linux/types.h> + +#define _DEFUN(a,b,c) a(c) +#define _CONST const +#define _AND , + +#define _REENT_ONLY + +#define SECSPERMIN 60L +#define MINSPERHOUR 60L +#define HOURSPERDAY 24L +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 + +#define YEAR_BASE 1900 +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY 4 + +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) + + +/* Used by other time functions. */ +struct tm { + int tm_sec; /* Seconds. [0-60] (1 leap second) */ + int tm_min; /* Minutes. [0-59] */ + int tm_hour; /* Hours. [0-23] */ + int tm_mday; /* Day. [1-31] */ + int tm_mon; /* Month. [0-11] */ + int tm_year; /* Year - 1900. */ + int tm_wday; /* Day of week. [0-6] */ + int tm_yday; /* Days in year.[0-365] */ + int tm_isdst; /* DST. [-1/0/1]*/ + +# ifdef __USE_BSD + long int tm_gmtoff; /* Seconds east of UTC. */ + __const char *tm_zone; /* Timezone abbreviation. */ +# else + long int __tm_gmtoff; /* Seconds east of UTC. */ + __const char *__tm_zone; /* Timezone abbreviation. */ +# endif +}; + +static inline char * +_DEFUN (asctime_r, (tim_p, result), + _CONST struct tm *tim_p _AND + char *result) +{ + static _CONST char day_name[7][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static _CONST char mon_name[12][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + sprintf (result, "%.3s %.3s %.2d %.2d:%.2d:%.2d %d\n", + day_name[tim_p->tm_wday], + mon_name[tim_p->tm_mon], + tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min, + tim_p->tm_sec, 1900 + tim_p->tm_year); + return result; +} + +static inline struct tm * +_DEFUN (localtime_r, (tim_p, res), + _CONST time_t * tim_p _AND + struct tm *res) +{ + static _CONST int mon_lengths[2][MONSPERYEAR] = { + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + } ; + + static _CONST int year_lengths[2] = { + 365, + 366 + } ; + + long days, rem; + int y; + int yleap; + _CONST int *ip; + + days = ((long) *tim_p) / SECSPERDAY; + rem = ((long) *tim_p) % SECSPERDAY; + while (rem < 0) + { + rem += SECSPERDAY; + --days; + } + while (rem >= SECSPERDAY) + { + rem -= SECSPERDAY; + ++days; + } + + /* compute hour, min, and sec */ + res->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + res->tm_min = (int) (rem / SECSPERMIN); + res->tm_sec = (int) (rem % SECSPERMIN); + + /* compute day of week */ + if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) + res->tm_wday += DAYSPERWEEK; + + /* compute year & day of year */ + y = EPOCH_YEAR; + if (days >= 0) + { + for (;;) + { + yleap = isleap(y); + if (days < year_lengths[yleap]) + break; + y++; + days -= year_lengths[yleap]; + } + } + else + { + do + { + --y; + yleap = isleap(y); + days += year_lengths[yleap]; + } while (days < 0); + } + + res->tm_year = y - YEAR_BASE; + res->tm_yday = days; + ip = mon_lengths[yleap]; + for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) + days -= ip[res->tm_mon]; + res->tm_mday = days + 1; + + /* set daylight saving time flag */ + res->tm_isdst = -1; + + return (res); +} + +static inline char * +_DEFUN (ctime_r, (tim_p, result), + _CONST time_t * tim_p _AND + char * result) + +{ + struct tm tm; + return asctime_r (localtime_r (tim_p, &tm), result); +} + +#endif
diff --git a/x-loader/include/linux/types.h b/x-loader/include/linux/types.h new file mode 100644 index 0000000..df4808f --- /dev/null +++ b/x-loader/include/linux/types.h
@@ -0,0 +1,130 @@ +#ifndef _LINUX_TYPES_H +#define _LINUX_TYPES_H + +#ifdef __KERNEL__ +#include <linux/config.h> +#endif + +#include <linux/posix_types.h> +#include <asm/types.h> + +#ifndef __KERNEL_STRICT_NAMES + +typedef __kernel_fd_set fd_set; +typedef __kernel_dev_t dev_t; +typedef __kernel_ino_t ino_t; +typedef __kernel_mode_t mode_t; +typedef __kernel_nlink_t nlink_t; +typedef __kernel_off_t off_t; +typedef __kernel_pid_t pid_t; +typedef __kernel_daddr_t daddr_t; +typedef __kernel_key_t key_t; +typedef __kernel_suseconds_t suseconds_t; + +#ifdef __KERNEL__ +typedef __kernel_uid32_t uid_t; +typedef __kernel_gid32_t gid_t; +typedef __kernel_uid16_t uid16_t; +typedef __kernel_gid16_t gid16_t; + +#ifdef CONFIG_UID16 +/* This is defined by include/asm-{arch}/posix_types.h */ +typedef __kernel_old_uid_t old_uid_t; +typedef __kernel_old_gid_t old_gid_t; +#endif /* CONFIG_UID16 */ + +/* libc5 includes this file to define uid_t, thus uid_t can never change + * when it is included by non-kernel code + */ +#else +typedef __kernel_uid_t uid_t; +typedef __kernel_gid_t gid_t; +#endif /* __KERNEL__ */ + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __kernel_loff_t loff_t; +#endif + +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef __kernel_time_t time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __kernel_clock_t clock_t; +#endif + +#ifndef _CADDR_T +#define _CADDR_T +typedef __kernel_caddr_t caddr_t; +#endif + +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ + +typedef __u8 u_int8_t; +typedef __s8 int8_t; +typedef __u16 u_int16_t; +typedef __s16 int16_t; +typedef __u32 u_int32_t; +typedef __s32 int32_t; + +#endif /* !(__BIT_TYPES_DEFINED__) */ + +typedef __u8 uint8_t; +typedef __u16 uint16_t; +typedef __u32 uint32_t; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __u64 uint64_t; +typedef __u64 u_int64_t; +typedef __s64 int64_t; +#endif + +#endif /* __KERNEL_STRICT_NAMES */ + +/* + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. + */ + +struct ustat { + __kernel_daddr_t f_tfree; + __kernel_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +#endif /* _LINUX_TYPES_H */
diff --git a/x-loader/include/malloc.h b/x-loader/include/malloc.h new file mode 100644 index 0000000..47154b0 --- /dev/null +++ b/x-loader/include/malloc.h
@@ -0,0 +1,942 @@ +/* + A version of malloc/free/realloc written by Doug Lea and released to the + public domain. Send questions/comments/complaints/performance data + to dl@cs.oswego.edu + +* VERSION 2.6.6 Sun Mar 5 19:10:03 2000 Doug Lea (dl at gee) + + Note: There may be an updated version of this malloc obtainable at + ftp://g.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Why use this malloc? + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and tunable. + Consistent balance across these factors results in a good general-purpose + allocator. For a high-level description, see + http://g.oswego.edu/dl/html/malloc.html + +* Synopsis of public routines + + (Much fuller descriptions are contained in the program documentation below.) + + malloc(size_t n); + Return a pointer to a newly allocated chunk of at least n bytes, or null + if no space is available. + free(Void_t* p); + Release the chunk of memory pointed to by p, or no effect if p is null. + realloc(Void_t* p, size_t n); + Return a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. The returned pointer may or may not be + the same as p. If p is null, equivalent to malloc. Unless the + #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a + size argument of zero (re)allocates a minimum-sized chunk. + memalign(size_t alignment, size_t n); + Return a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument, which must be a power of + two. + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system (or as near to this as can be figured out from + all the includes/defines below.) + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + calloc(size_t unit, size_t quantity); + Returns a pointer to quantity * unit bytes, with all locations + set to zero. + cfree(Void_t* p); + Equivalent to free(p). + malloc_trim(size_t pad); + Release all but pad bytes of freed top-most memory back + to the system. Return 1 if successful, else 0. + malloc_usable_size(Void_t* p); + Report the number usable allocated bytes associated with allocated + chunk p. This may or may not report more bytes than were requested, + due to alignment and minimum size constraints. + malloc_stats(); + Prints brief summary statistics on stderr. + mallinfo() + Returns (by copy) a struct containing various summary statistics. + mallopt(int parameter_number, int parameter_value) + Changes one of the tunable parameters described below. Returns + 1 if successful in changing the parameter, else 0. + +* Vital statistics: + + Alignment: 8-byte + 8 byte alignment is currently hardwired into the design. This + seems to suffice for all current machines and C compilers. + + Assumed pointer representation: 4 or 8 bytes + Code for 8-byte pointers is untested by me but has worked + reliably by Wolfram Gloger, who contributed most of the + changes supporting this. + + Assumed size_t representation: 4 or 8 bytes + Note that size_t is allowed to be 4 bytes even if pointers are 8. + + Minimum overhead per allocated chunk: 4 or 8 bytes + Each malloced chunk has a hidden overhead of 4 bytes holding size + and status information. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead) + 8-byte ptrs: 24/32 bytes (including, 4/8 overhead) + + When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte + ptrs but 4 byte size) or 24 (for 8/8) additional bytes are + needed; 4 (8) for a trailing size field + and 8 (16) bytes for free list pointers. Thus, the minimum + allocatable size is 16/24/32 bytes. + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + + Maximum allocated size: 4-byte size_t: 2^31 - 8 bytes + 8-byte size_t: 2^63 - 16 bytes + + It is assumed that (possibly signed) size_t bit values suffice to + represent chunk sizes. `Possibly signed' is due to the fact + that `size_t' may be defined on a system as either a signed or + an unsigned type. To be conservative, values that would appear + as negative numbers are avoided. + Requests for sizes with a negative sign bit when the request + size is treaded as a long will return null. + + Maximum overhead wastage per allocated chunk: normally 15 bytes + + Alignnment demands, plus the minimum allocatable size restriction + make the normal worst-case wastage 15 bytes (i.e., up to 15 + more bytes will be allocated than were requested in malloc), with + two exceptions: + 1. Because requests for zero bytes allocate non-zero space, + the worst case wastage for a request of zero bytes is 24 bytes. + 2. For requests >= mmap_threshold that are serviced via + mmap(), the worst case wastage is 8 bytes plus the remainder + from a system page (the minimal mmap unit); typically 4096 bytes. + +* Limitations + + Here are some features that are NOT currently supported + + * No user-definable hooks for callbacks and the like. + * No automated mechanism for fully checking that all accesses + to malloced memory stay within their bounds. + * No support for compaction. + +* Synopsis of compile-time options: + + People have reported using previous versions of this malloc on all + versions of Unix, sometimes by tweaking some of the defines + below. It has been tested most extensively on Solaris and + Linux. It is also reported to work on WIN32 platforms. + People have also reported adapting this malloc for use in + stand-alone embedded systems. + + The implementation is in straight, hand-tuned ANSI C. Among other + consequences, it uses a lot of macros. Because of this, to be at + all usable, this code should be compiled using an optimizing compiler + (for example gcc -O2) that can simplify expressions and control + paths. + + __STD_C (default: derived from C compiler defines) + Nonzero if using ANSI-standard C compiler, a C++ compiler, or + a C compiler sufficiently close to ANSI to get away with it. + DEBUG (default: NOT defined) + Define to enable debugging. Adds fairly extensive assertion-based + checking to help track down memory errors, but noticeably slows down + execution. + REALLOC_ZERO_BYTES_FREES (default: NOT defined) + Define this if you think that realloc(p, 0) should be equivalent + to free(p). Otherwise, since malloc returns a unique pointer for + malloc(0), so does realloc(p, 0). + HAVE_MEMCPY (default: defined) + Define if you are not otherwise using ANSI STD C, but still + have memcpy and memset in your C library and want to use them. + Otherwise, simple internal versions are supplied. + USE_MEMCPY (default: 1 if HAVE_MEMCPY is defined, 0 otherwise) + Define as 1 if you want the C library versions of memset and + memcpy called in realloc and calloc (otherwise macro versions are used). + At least on some platforms, the simple macro versions usually + outperform libc versions. + HAVE_MMAP (default: defined as 1) + Define to non-zero to optionally make malloc() use mmap() to + allocate very large blocks. + HAVE_MREMAP (default: defined as 0 unless Linux libc set) + Define to non-zero to optionally make realloc() use mremap() to + reallocate very large blocks. + malloc_getpagesize (default: derived from system #includes) + Either a constant or routine call returning the system page size. + HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined) + Optionally define if you are on a system with a /usr/include/malloc.h + that declares struct mallinfo. It is not at all necessary to + define this even if you do, but will ensure consistency. + INTERNAL_SIZE_T (default: size_t) + Define to a 32-bit type (probably `unsigned int') if you are on a + 64-bit machine, yet do not want or need to allow malloc requests of + greater than 2^31 to be handled. This saves space, especially for + very small chunks. + INTERNAL_LINUX_C_LIB (default: NOT defined) + Defined only when compiled as part of Linux libc. + Also note that there is some odd internal name-mangling via defines + (for example, internally, `malloc' is named `mALLOc') needed + when compiling in this case. These look funny but don't otherwise + affect anything. + WIN32 (default: undefined) + Define this on MS win (95, nt) platforms to compile in sbrk emulation. + LACKS_UNISTD_H (default: undefined if not WIN32) + Define this if your system does not have a <unistd.h>. + LACKS_SYS_PARAM_H (default: undefined if not WIN32) + Define this if your system does not have a <sys/param.h>. + MORECORE (default: sbrk) + The name of the routine to call to obtain more memory from the system. + MORECORE_FAILURE (default: -1) + The value returned upon failure of MORECORE. + MORECORE_CLEARS (default 1) + True (1) if the routine mapped to MORECORE zeroes out memory (which + holds for sbrk). + DEFAULT_TRIM_THRESHOLD + DEFAULT_TOP_PAD + DEFAULT_MMAP_THRESHOLD + DEFAULT_MMAP_MAX + Default values of tunable parameters (described in detail below) + controlling interaction with host system routines (sbrk, mmap, etc). + These values may also be changed dynamically via mallopt(). The + preset defaults are those that give best performance for typical + programs/systems. + USE_DL_PREFIX (default: undefined) + Prefix all public routines with the string 'dl'. Useful to + quickly avoid procedure declaration conflicts and linker symbol + conflicts with existing memory allocation routines. + + +*/ + + + + +/* Preliminaries */ + +#ifndef __STD_C +#ifdef __STDC__ +#define __STD_C 1 +#else +#if __cplusplus +#define __STD_C 1 +#else +#define __STD_C 0 +#endif /*__cplusplus*/ +#endif /*__STDC__*/ +#endif /*__STD_C*/ + +#ifndef Void_t +#if (__STD_C || defined(WIN32)) +#define Void_t void +#else +#define Void_t char +#endif +#endif /*Void_t*/ + +#if __STD_C +#include <linux/stddef.h> /* for size_t */ +#else +#include <sys/types.h> +#endif /* __STD_C */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 /* not for U-Boot */ +#include <stdio.h> /* needed for malloc_stats */ +#endif + + +/* + Compile-time options +*/ + + +/* + Debugging: + + Because freed chunks may be overwritten with link fields, this + malloc will often die when freed memory is overwritten by user + programs. This can be very effective (albeit in an annoying way) + in helping track down dangling pointers. + + If you compile with -DDEBUG, a number of assertion checks are + enabled that will catch more memory errors. You probably won't be + able to make much sense of the actual assertion errors, but they + should help you locate incorrectly overwritten memory. The + checking is fairly extensive, and will slow down execution + noticeably. Calling malloc_stats or mallinfo with DEBUG set will + attempt to check every non-mmapped allocated and free chunk in the + course of computing the summmaries. (By nature, mmapped regions + cannot be checked very much automatically.) + + Setting DEBUG may also be helpful if you are trying to modify + this code. The assertions in the check routines spell out in more + detail the assumptions and invariants underlying the algorithms. + +*/ + +#ifdef DEBUG +/* #include <assert.h> */ +#define assert(x) ((void)0) +#else +#define assert(x) ((void)0) +#endif + + +/* + INTERNAL_SIZE_T is the word-size used for internal bookkeeping + of chunk sizes. On a 64-bit machine, you can reduce malloc + overhead by defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' + at the expense of not being able to handle requests greater than + 2^31. This limitation is hardly ever a concern; you are encouraged + to set this. However, the default version is the same as size_t. +*/ + +#ifndef INTERNAL_SIZE_T +#define INTERNAL_SIZE_T size_t +#endif + +/* + REALLOC_ZERO_BYTES_FREES should be set if a call to + realloc with zero bytes should be the same as a call to free. + Some people think it should. Otherwise, since this malloc + returns a unique pointer for malloc(0), so does realloc(p, 0). +*/ + + +/* #define REALLOC_ZERO_BYTES_FREES */ + + +/* + WIN32 causes an emulation of sbrk to be compiled in + mmap-based options are not currently supported in WIN32. +*/ + +/* #define WIN32 */ +#ifdef WIN32 +#define MORECORE wsbrk +#define HAVE_MMAP 0 + +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H + +/* + Include 'windows.h' to get the necessary declarations for the + Microsoft Visual C++ data structures and routines used in the 'sbrk' + emulation. + + Define WIN32_LEAN_AND_MEAN so that only the essential Microsoft + Visual C++ header files are included. +*/ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + + +/* + HAVE_MEMCPY should be defined if you are not otherwise using + ANSI STD C, but still have memcpy and memset in your C library + and want to use them in calloc and realloc. Otherwise simple + macro versions are defined here. + + USE_MEMCPY should be defined as 1 if you actually want to + have memset and memcpy called. People report that the macro + versions are often enough faster than libc versions on many + systems that it is better to use them. + +*/ + +#define HAVE_MEMCPY + +#ifndef USE_MEMCPY +#ifdef HAVE_MEMCPY +#define USE_MEMCPY 1 +#else +#define USE_MEMCPY 0 +#endif +#endif + +#if (__STD_C || defined(HAVE_MEMCPY)) + +#if __STD_C +void* memset(void*, int, size_t); +void* memcpy(void*, const void*, size_t); +#else +#ifdef WIN32 +/* On Win32 platforms, 'memset()' and 'memcpy()' are already declared in */ +/* 'windows.h' */ +#else +Void_t* memset(); +Void_t* memcpy(); +#endif +#endif +#endif + +#if USE_MEMCPY + +/* The following macros are only invoked with (2n+1)-multiples of + INTERNAL_SIZE_T units, with a positive integer n. This is exploited + for fast inline execution when n is small. */ + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + INTERNAL_SIZE_T mzsz = (nbytes); \ + if(mzsz <= 9*sizeof(mzsz)) { \ + INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \ + if(mzsz >= 5*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 7*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; \ + if(mzsz >= 9*sizeof(mzsz)) { *mz++ = 0; \ + *mz++ = 0; }}} \ + *mz++ = 0; \ + *mz++ = 0; \ + *mz = 0; \ + } else memset((charp), 0, mzsz); \ +} while(0) + +#define MALLOC_COPY(dest,src,nbytes) \ +do { \ + INTERNAL_SIZE_T mcsz = (nbytes); \ + if(mcsz <= 9*sizeof(mcsz)) { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src); \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest); \ + if(mcsz >= 5*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + if(mcsz >= 7*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; }}} \ + *mcdst++ = *mcsrc++; \ + *mcdst++ = *mcsrc++; \ + *mcdst = *mcsrc ; \ + } else memcpy(dest, src, mcsz); \ +} while(0) + +#else /* !USE_MEMCPY */ + +/* Use Duff's device for good zeroing/copying performance. */ + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \ + long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = 0; \ + case 7: *mzp++ = 0; \ + case 6: *mzp++ = 0; \ + case 5: *mzp++ = 0; \ + case 4: *mzp++ = 0; \ + case 3: *mzp++ = 0; \ + case 2: *mzp++ = 0; \ + case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#define MALLOC_COPY(dest,src,nbytes) \ +do { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \ + long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T), mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mcdst++ = *mcsrc++; \ + case 7: *mcdst++ = *mcsrc++; \ + case 6: *mcdst++ = *mcsrc++; \ + case 5: *mcdst++ = *mcsrc++; \ + case 4: *mcdst++ = *mcsrc++; \ + case 3: *mcdst++ = *mcsrc++; \ + case 2: *mcdst++ = *mcsrc++; \ + case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#endif + + +/* + Define HAVE_MMAP to optionally make malloc() use mmap() to + allocate very large blocks. These will be returned to the + operating system immediately after a free(). +*/ + +/*** +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif +***/ +#undef HAVE_MMAP /* Not available for U-Boot */ + +/* + Define HAVE_MREMAP to make realloc() use mremap() to re-allocate + large blocks. This is currently only possible on Linux with + kernel versions newer than 1.3.77. +*/ + +/*** +#ifndef HAVE_MREMAP +#ifdef INTERNAL_LINUX_C_LIB +#define HAVE_MREMAP 1 +#else +#define HAVE_MREMAP 0 +#endif +#endif +***/ +#undef HAVE_MREMAP /* Not available for U-Boot */ + +#if HAVE_MMAP + +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> + +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif + +#endif /* HAVE_MMAP */ + +/* + Access to system page size. To the extent possible, this malloc + manages memory from the system in page-size units. + + The following mechanics for getpagesize were adapted from + bsd/gnu getpagesize.h +*/ + +#define LACKS_UNISTD_H /* Shortcut for U-Boot */ +#define malloc_getpagesize 4096 + +#ifndef LACKS_UNISTD_H +# include <unistd.h> +#endif + +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 +# define malloc_getpagesize (4096) /* TBD: Use 'GetSystemInfo' instead */ +# else +# ifndef LACKS_SYS_PARAM_H +# include <sys/param.h> +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else +# define malloc_getpagesize (4096) /* just guess */ +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + + +/* + + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing the same kind of + information you can get from malloc_stats. It should work on + any SVID/XPG compliant system that has a /usr/include/malloc.h + defining struct mallinfo. (If you'd like to install such a thing + yourself, cut out the preliminary declarations as described above + and below and save them in a malloc.h file. But there's no + compelling reason to bother to do this.) + + The main declaration needed is the mallinfo struct that is returned + (by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a + bunch of fields, most of which are not even meaningful in this + version of malloc. Some of these fields are are instead filled by + mallinfo() with other numbers that might possibly be of interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else an SVID2/XPG2 compliant + version is declared below. These must be precisely the same for + mallinfo() to work. + +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#if HAVE_USR_INCLUDE_MALLOC_H +#include "/usr/include/malloc.h" +#else + +/* SVID2/XPG mallinfo structure */ + +struct mallinfo { + int arena; /* total space allocated from system */ + int ordblks; /* number of non-inuse chunks */ + int smblks; /* unused -- always zero */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* total space in mmapped regions */ + int usmblks; /* unused -- always zero */ + int fsmblks; /* unused -- always zero */ + int uordblks; /* total allocated space */ + int fordblks; /* total non-inuse space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +/* SVID2/XPG mallopt options */ + +#define M_MXFAST 1 /* UNUSED in this malloc */ +#define M_NLBLKS 2 /* UNUSED in this malloc */ +#define M_GRAIN 3 /* UNUSED in this malloc */ +#define M_KEEP 4 /* UNUSED in this malloc */ + +#endif + +/* mallopt options that actually do something */ + +#define M_TRIM_THRESHOLD -1 +#define M_TOP_PAD -2 +#define M_MMAP_THRESHOLD -3 +#define M_MMAP_MAX -4 + + +#ifndef DEFAULT_TRIM_THRESHOLD +#define DEFAULT_TRIM_THRESHOLD (128 * 1024) +#endif + +/* + M_TRIM_THRESHOLD is the maximum amount of unused top-most memory + to keep before releasing via malloc_trim in free(). + + Automatic trimming is mainly useful in long-lived programs. + Because trimming via sbrk can be slow on some systems, and can + sometimes be wasteful (in cases where programs immediately + afterward allocate more large chunks) the value should be high + enough so that your overall system performance would improve by + releasing. + + The trim threshold and the mmap control parameters (see below) + can be traded off with one another. Trimming and mmapping are + two different ways of releasing unused memory back to the + system. Between these two, it is often possible to keep + system-level demands of a long-lived program down to a bare + minimum. For example, in one test suite of sessions measuring + the XF86 X server on Linux, using a trim threshold of 128K and a + mmap threshold of 192K led to near-minimal long term resource + consumption. + + If you are using this malloc in a long-lived program, it should + pay to experiment with these values. As a rough guide, you + might set to a value close to the average size of a process + (program) running on your system. Releasing this much memory + would allow such a process to run in memory. Generally, it's + worth it to tune for trimming rather tham memory mapping when a + program undergoes phases where several large chunks are + allocated and released in ways that can reuse each other's + storage, perhaps mixed with phases where there are no such + chunks at all. And in well-behaved long-lived programs, + controlling release of large blocks via trimming versus mapping + is usually faster. + + However, in most programs, these parameters serve mainly as + protection against the system-level effects of carrying around + massive amounts of unneeded memory. Since frequent calls to + sbrk, mmap, and munmap otherwise degrade performance, the default + parameters are set to relatively high values that serve only as + safeguards. + + The default trim value is high enough to cause trimming only in + fairly extreme (by current memory consumption standards) cases. + It must be greater than page size to have any useful effect. To + disable trimming completely, you can set to (unsigned long)(-1); + + +*/ + + +#ifndef DEFAULT_TOP_PAD +#define DEFAULT_TOP_PAD (0) +#endif + +/* + M_TOP_PAD is the amount of extra `padding' space to allocate or + retain whenever sbrk is called. It is used in two ways internally: + + * When sbrk is called to extend the top of the arena to satisfy + a new malloc request, this much padding is added to the sbrk + request. + + * When malloc_trim is called automatically from free(), + it is used as the `pad' argument. + + In both cases, the actual amount of padding is rounded + so that the end of the arena is always a system page boundary. + + The main reason for using padding is to avoid calling sbrk so + often. Having even a small pad greatly reduces the likelihood + that nearly every malloc request during program start-up (or + after trimming) will invoke sbrk, which needlessly wastes + time. + + Automatic rounding-up to page-size units is normally sufficient + to avoid measurable overhead, so the default is 0. However, in + systems where sbrk is relatively slow, it can pay to increase + this value, at the expense of carrying around more memory than + the program needs. + +*/ + + +#ifndef DEFAULT_MMAP_THRESHOLD +#define DEFAULT_MMAP_THRESHOLD (128 * 1024) +#endif + +/* + + M_MMAP_THRESHOLD is the request size threshold for using mmap() + to service a request. Requests of at least this size that cannot + be allocated using already-existing space will be serviced via mmap. + (If enough normal freed space already exists it is used instead.) + + Using mmap segregates relatively large chunks of memory so that + they can be individually obtained and released from the host + system. A request serviced through mmap is never reused by any + other request (at least not directly; the system may just so + happen to remap successive requests to the same locations). + + Segregating space in this way has the benefit that mmapped space + can ALWAYS be individually released back to the system, which + helps keep the system level memory demands of a long-lived + program low. Mapped memory can never become `locked' between + other chunks, as can happen with normally allocated chunks, which + menas that even trimming via malloc_trim would not release them. + + However, it has the disadvantages that: + + 1. The space cannot be reclaimed, consolidated, and then + used to service later requests, as happens with normal chunks. + 2. It can lead to more wastage because of mmap page alignment + requirements + 3. It causes malloc performance to be more dependent on host + system memory management support routines which may vary in + implementation quality and may impose arbitrary + limitations. Generally, servicing a request via normal + malloc steps is faster than going through a system's mmap. + + All together, these considerations should lead you to use mmap + only for relatively large requests. + + +*/ + + +#ifndef DEFAULT_MMAP_MAX +#if HAVE_MMAP +#define DEFAULT_MMAP_MAX (64) +#else +#define DEFAULT_MMAP_MAX (0) +#endif +#endif + +/* + M_MMAP_MAX is the maximum number of requests to simultaneously + service using mmap. This parameter exists because: + + 1. Some systems have a limited number of internal tables for + use by mmap. + 2. In most systems, overreliance on mmap can degrade overall + performance. + 3. If a program allocates many large regions, it is probably + better off using normal sbrk-based allocation routines that + can reclaim and reallocate normal heap memory. Using a + small value allows transition into this mode after the + first few allocations. + + Setting to 0 disables all use of mmap. If HAVE_MMAP is not set, + the default value is 0, and attempts to set it to non-zero values + in mallopt will fail. +*/ + + +/* + USE_DL_PREFIX will prefix all public routines with the string 'dl'. + Useful to quickly avoid procedure declaration conflicts and linker + symbol conflicts with existing memory allocation routines. + +*/ + +/* #define USE_DL_PREFIX */ + + +/* + + Special defines for linux libc + + Except when compiled using these special defines for Linux libc + using weak aliases, this malloc is NOT designed to work in + multithreaded applications. No semaphores or other concurrency + control are provided to ensure that multiple malloc or free calls + don't run at the same time, which could be disasterous. A single + semaphore could be used across malloc, realloc, and free (which is + essentially the effect of the linux weak alias approach). It would + be hard to obtain finer granularity. + +*/ + + +#ifdef INTERNAL_LINUX_C_LIB + +#if __STD_C + +Void_t * __default_morecore_init (ptrdiff_t); +Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init; + +#else + +Void_t * __default_morecore_init (); +Void_t *(*__morecore)() = __default_morecore_init; + +#endif + +#define MORECORE (*__morecore) +#define MORECORE_FAILURE 0 +#define MORECORE_CLEARS 1 + +#else /* INTERNAL_LINUX_C_LIB */ + +#if __STD_C +extern Void_t* sbrk(ptrdiff_t); +#else +extern Void_t* sbrk(); +#endif + +#ifndef MORECORE +#define MORECORE sbrk +#endif + +#ifndef MORECORE_FAILURE +#define MORECORE_FAILURE -1 +#endif + +#ifndef MORECORE_CLEARS +#define MORECORE_CLEARS 1 +#endif + +#endif /* INTERNAL_LINUX_C_LIB */ + +#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__) + +#define cALLOc __libc_calloc +#define fREe __libc_free +#define mALLOc __libc_malloc +#define mEMALIGn __libc_memalign +#define rEALLOc __libc_realloc +#define vALLOc __libc_valloc +#define pvALLOc __libc_pvalloc +#define mALLINFo __libc_mallinfo +#define mALLOPt __libc_mallopt + +#pragma weak calloc = __libc_calloc +#pragma weak free = __libc_free +#pragma weak cfree = __libc_free +#pragma weak malloc = __libc_malloc +#pragma weak memalign = __libc_memalign +#pragma weak realloc = __libc_realloc +#pragma weak valloc = __libc_valloc +#pragma weak pvalloc = __libc_pvalloc +#pragma weak mallinfo = __libc_mallinfo +#pragma weak mallopt = __libc_mallopt + +#else + +#ifdef USE_DL_PREFIX +#define cALLOc dlcalloc +#define fREe dlfree +#define mALLOc dlmalloc +#define mEMALIGn dlmemalign +#define rEALLOc dlrealloc +#define vALLOc dlvalloc +#define pvALLOc dlpvalloc +#define mALLINFo dlmallinfo +#define mALLOPt dlmallopt +#else /* USE_DL_PREFIX */ +#define cALLOc calloc +#define fREe free +#define mALLOc malloc +#define mEMALIGn memalign +#define rEALLOc realloc +#define vALLOc valloc +#define pvALLOc pvalloc +#define mALLINFo mallinfo +#define mALLOPt mallopt +#endif /* USE_DL_PREFIX */ + +#endif + +/* Public routines */ + +#if __STD_C + +Void_t* mALLOc(size_t); +void fREe(Void_t*); +Void_t* rEALLOc(Void_t*, size_t); +Void_t* mEMALIGn(size_t, size_t); +Void_t* vALLOc(size_t); +Void_t* pvALLOc(size_t); +Void_t* cALLOc(size_t, size_t); +void cfree(Void_t*); +int malloc_trim(size_t); +size_t malloc_usable_size(Void_t*); +void malloc_stats(void); +int mALLOPt(int, int); +struct mallinfo mALLINFo(void); +#else +Void_t* mALLOc(); +void fREe(); +Void_t* rEALLOc(); +Void_t* mEMALIGn(); +Void_t* vALLOc(); +Void_t* pvALLOc(); +Void_t* cALLOc(); +void cfree(); +int malloc_trim(); +size_t malloc_usable_size(); +void malloc_stats(); +int mALLOPt(); +struct mallinfo mALLINFo(); +#endif + + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif
diff --git a/x-loader/include/mmc.h b/x-loader/include/mmc.h new file mode 100644 index 0000000..c92a907 --- /dev/null +++ b/x-loader/include/mmc.h
@@ -0,0 +1,38 @@ +/* + * (C) Copyright 2000-2003 + * 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 + */ + +#ifndef _MMC_H_ +#define _MMC_H_ + +#include <part.h> + +#include <asm/arch/mmc.h> + +int mmc_init(int verbose); +int mmc_read(unsigned int src, unsigned char *dst, int size); +int mmc_write(unsigned char *src, unsigned long dst, int size); +int mmc2info(unsigned int addr); + +block_dev_desc_t *mmc_get_dev(int dev); + +#endif /* _MMC_H_ */
diff --git a/x-loader/include/ns16550.h b/x-loader/include/ns16550.h new file mode 100644 index 0000000..36d2d40 --- /dev/null +++ b/x-loader/include/ns16550.h
@@ -0,0 +1,130 @@ +/* + *This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * NS16550 Serial Port + * originally from linux source (arch/ppc/boot/ns16550.h) + * modified slightly to + * have addresses as offsets from CFG_ISA_BASE + * added a few more definitions + * added prototypes for ns16550.c + * reduced no of com ports to 2 + * modifications (c) Rob Taylor, Flying Pig Systems. 2000. + */ + +#if (CFG_NS16550_REG_SIZE == 1) +struct NS16550 { + unsigned char rbr; /* 0 */ + unsigned char ier; /* 1 */ + unsigned char fcr; /* 2 */ + unsigned char lcr; /* 3 */ + unsigned char mcr; /* 4 */ + unsigned char lsr; /* 5 */ + unsigned char msr; /* 6 */ + unsigned char scr; /* 7 */ +} __attribute__ ((packed)); +#elif (CFG_NS16550_REG_SIZE == 2) +struct NS16550 { + unsigned short rbr; /* 0 */ + unsigned short ier; /* 1 */ + unsigned short fcr; /* 2 */ + unsigned short lcr; /* 3 */ + unsigned short mcr; /* 4 */ + unsigned short lsr; /* 5 */ + unsigned short msr; /* 6 */ + unsigned short scr; /* 7 */ +} __attribute__ ((packed)); +#elif (CFG_NS16550_REG_SIZE == 4) +struct NS16550 { + unsigned long rbr; /* 0 */ + unsigned long ier; /* 1 */ + unsigned long fcr; /* 2 */ + unsigned long lcr; /* 3 */ + unsigned long mcr; /* 4 */ + unsigned long lsr; /* 5 */ + unsigned long msr; /* 6 */ + unsigned long scr; /* 7 */ +} __attribute__ ((packed)); +#elif (CFG_NS16550_REG_SIZE == -4) +struct NS16550 { + unsigned char rbr; /* 0 */ + int pad1:24; + unsigned char ier; /* 1 */ + int pad2:24; + unsigned char fcr; /* 2 */ + int pad3:24; + unsigned char lcr; /* 3 */ + int pad4:24; + unsigned char mcr; /* 4 */ + int pad5:24; + unsigned char lsr; /* 5 */ + int pad6:24; + unsigned char msr; /* 6 */ + int pad7:24; + unsigned char scr; /* 7 */ + int pad8:24; +#if defined(CONFIG_OMAP) + unsigned char mdr1; /* mode select reset TL16C750*/ +#endif +#ifdef CONFIG_OMAP1510 + int pad9:24; + unsigned long pad[10]; + unsigned char osc_12m_sel; + int pad10:24; +#endif +} __attribute__ ((packed)); +#else +#error "Please define NS16550 registers size." +#endif + +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +typedef volatile struct NS16550 *NS16550_t; + +#define FCR_FIFO_EN 0x01 /* Fifo enable */ +#define FCR_RXSR 0x02 /* Receiver soft reset */ +#define FCR_TXSR 0x04 /* Transmitter soft reset */ + +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_DMA_EN 0x04 +#define MCR_TX_DFR 0x08 + +#define LCR_WLS_MSK 0x03 /* character length slect mask */ +#define LCR_WLS_5 0x00 /* 5 bit character length */ +#define LCR_WLS_6 0x01 /* 6 bit character length */ +#define LCR_WLS_7 0x02 /* 7 bit character length */ +#define LCR_WLS_8 0x03 /* 8 bit character length */ +#define LCR_STB 0x04 /* Number of stop Bits, off = 1, on = 1.5 or 2) */ +#define LCR_PEN 0x08 /* Parity eneble */ +#define LCR_EPS 0x10 /* Even Parity Select */ +#define LCR_STKP 0x20 /* Stick Parity */ +#define LCR_SBRK 0x40 /* Set Break */ +#define LCR_BKSE 0x80 /* Bank select enable */ + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + +#ifdef CONFIG_OMAP1510 +#define OSC_12M_SEL 0x01 /* selects 6.5 * current clk div */ +#endif + +/* useful defaults for LCR */ +#define LCR_8N1 0x03 + +void NS16550_init (NS16550_t com_port, int baud_divisor); +void NS16550_putc (NS16550_t com_port, char c); +char NS16550_getc (NS16550_t com_port); +int NS16550_tstc (NS16550_t com_port); +void NS16550_reinit (NS16550_t com_port, int baud_divisor);
diff --git a/x-loader/include/part.h b/x-loader/include/part.h new file mode 100644 index 0000000..318aa3c --- /dev/null +++ b/x-loader/include/part.h
@@ -0,0 +1,121 @@ +/* + * (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 + */ +#ifndef _PART_H +#define _PART_H +#include <ide.h> + +typedef struct block_dev_desc { + int if_type; /* type of the interface */ + int dev; /* device number */ + unsigned char part_type; /* partition type */ + unsigned char target; /* target SCSI ID */ + unsigned char lun; /* target LUN */ + unsigned char type; /* device type */ + unsigned char removable; /* removable device */ +#ifdef CONFIG_LBA48 + unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ +#endif + lbaint_t lba; /* number of blocks */ + unsigned long blksz; /* block size */ + unsigned char vendor [40+1]; /* IDE model, SCSI Vendor */ + unsigned char product[20+1]; /* IDE Serial no, SCSI product */ + unsigned char revision[8+1]; /* firmware revision */ + unsigned long (*block_read)(int dev, + unsigned long start, + lbaint_t blkcnt, + unsigned long *buffer); +}block_dev_desc_t; + +/* Interface types: */ +#define IF_TYPE_UNKNOWN 0 +#define IF_TYPE_IDE 1 +#define IF_TYPE_SCSI 2 +#define IF_TYPE_ATAPI 3 +#define IF_TYPE_USB 4 +#define IF_TYPE_DOC 5 +#define IF_TYPE_MMC 6 + +/* Part types */ +#define PART_TYPE_UNKNOWN 0x00 +#define PART_TYPE_MAC 0x01 +#define PART_TYPE_DOS 0x02 +#define PART_TYPE_ISO 0x03 +#define PART_TYPE_AMIGA 0x04 + +/* + * Type string for U-Boot bootable partitions + */ +#define BOOT_PART_TYPE "U-Boot" /* primary boot partition type */ +#define BOOT_PART_COMP "PPCBoot" /* PPCBoot compatibility type */ + +/* device types */ +#define DEV_TYPE_UNKNOWN 0xff /* not connected */ +#define DEV_TYPE_HARDDISK 0x00 /* harddisk */ +#define DEV_TYPE_TAPE 0x01 /* Tape */ +#define DEV_TYPE_CDROM 0x05 /* CD-ROM */ +#define DEV_TYPE_OPDISK 0x07 /* optical disk */ + +typedef struct disk_partition { + ulong start; /* # of first block in partition */ + ulong size; /* number of blocks in partition */ + ulong blksz; /* block size in bytes */ + uchar name[32]; /* partition name */ + uchar type[32]; /* string type description */ +} disk_partition_t; + +/* disk/part.c */ +int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part (block_dev_desc_t *dev_desc); +void init_part (block_dev_desc_t *dev_desc); +void dev_print(block_dev_desc_t *dev_desc); + + +#ifdef CONFIG_MAC_PARTITION +/* disk/part_mac.c */ +int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_mac (block_dev_desc_t *dev_desc); +int test_part_mac (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_DOS_PARTITION +/* disk/part_dos.c */ +int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_dos (block_dev_desc_t *dev_desc); +int test_part_dos (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_ISO_PARTITION +/* disk/part_iso.c */ +int get_partition_info_iso (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_iso (block_dev_desc_t *dev_desc); +int test_part_iso (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_AMIGA_PARTITION +/* disk/part_amiga.c */ +int get_partition_info_amiga (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_amiga (block_dev_desc_t *dev_desc); +int test_part_amiga (block_dev_desc_t *dev_desc); +#endif + +#endif /* _PART_H */
diff --git a/x-loader/include/rtc.h b/x-loader/include/rtc.h new file mode 100644 index 0000000..d006ba5 --- /dev/null +++ b/x-loader/include/rtc.h
@@ -0,0 +1,65 @@ +/* + * (C) Copyright 2001 + * 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 + */ + +/* + * Generic RTC interface. + */ +#ifndef _RTC_H_ +#define _RTC_H_ + +/* bcd<->bin functions are needed by almost all the RTC drivers, let's include + * it there instead of in evey single driver */ + +#include <bcd.h> + +/* + * The struct used to pass data from the generic interface code to + * the hardware dependend low-level code ande vice versa. Identical + * to struct rtc_time used by the Linux kernel. + * + * Note that there are small but significant differences to the + * common "struct time": + * + * struct time: struct rtc_time: + * tm_mon 0 ... 11 1 ... 12 + * tm_year years since 1900 years since 0 + */ + +struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +void GregorianDay (struct rtc_time *); +void to_tm (int, struct rtc_time *); +unsigned long mktime (unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int); + +#endif /* _RTC_H_ */
diff --git a/x-loader/include/timestamp.h b/x-loader/include/timestamp.h new file mode 100644 index 0000000..b2f4cf4 --- /dev/null +++ b/x-loader/include/timestamp.h
@@ -0,0 +1,30 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __TIMESTAMP_H__ +#define __TIMESTAMP_H__ + +#ifndef DO_DEPS_ONLY +#include "timestamp_autogenerated.h" +#endif + +#endif /* __TIMESTAMP_H__ */
diff --git a/x-loader/include/version.h b/x-loader/include/version.h new file mode 100644 index 0000000..a34291a --- /dev/null +++ b/x-loader/include/version.h
@@ -0,0 +1,31 @@ +/* + * (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 + */ + +#ifndef __VERSION_H__ +#define __VERSION_H__ + +#ifndef DO_DEPS_ONLY +#include "version_autogenerated.h" +#endif + +#endif /* __VERSION_H__ */
diff --git a/x-loader/include/watchdog.h b/x-loader/include/watchdog.h new file mode 100644 index 0000000..465416d --- /dev/null +++ b/x-loader/include/watchdog.h
@@ -0,0 +1,69 @@ +/* + * (C) Copyright 2001 + * Erik Theisen, Wave 7 Optics, etheisen@mindspring.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 + */ + +/* + * Watchdog functions and macros. + */ +#ifndef _WATCHDOG_H_ +#define _WATCHDOG_H_ + +#if defined(CONFIG_HW_WATCHDOG) && defined(CONFIG_WATCHDOG) +# error "Configuration error: CONFIG_HW_WATCHDOG and CONFIG_WATCHDOG can't be used together." +#endif + +/* + * Hardware watchdog + */ +#ifdef CONFIG_HW_WATCHDOG + #if defined(__ASSEMBLY__) + #define WATCHDOG_RESET bl hw_watchdog_reset + #else + extern void hw_watchdog_reset(void); + + #define WATCHDOG_RESET hw_watchdog_reset + #endif /* __ASSEMBLY__ */ +#else + /* + * Maybe a software watchdog? + */ + #if defined(CONFIG_WATCHDOG) + #if defined(__ASSEMBLY__) + #define WATCHDOG_RESET bl watchdog_reset + #else + extern void watchdog_reset(void); + + #define WATCHDOG_RESET watchdog_reset + #endif + #else + /* + * No hardware or software watchdog. + */ + #if defined(__ASSEMBLY__) + #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ + #else + #define WATCHDOG_RESET() {} + #endif /* __ASSEMBLY__ */ + #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */ +#endif /* CONFIG_HW_WATCHDOG */ + +#endif /* _WATCHDOG_H_ */
diff --git a/x-loader/include/x-load/crc.h b/x-loader/include/x-load/crc.h new file mode 100644 index 0000000..d091cab --- /dev/null +++ b/x-loader/include/x-load/crc.h
@@ -0,0 +1,33 @@ +/* + * (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 + */ + +#ifndef _XLOAD_CRC_H +#define _XLOAD_CRC_H + +/* lib/crc32.c */ +uint32_t crc32 (uint32_t, const unsigned char *, uint); +uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint); +uint32_t crc32_no_comp (uint32_t, const unsigned char *, uint); + +#endif /* _XLOAD_CRC_H */
diff --git a/x-loader/include/x-load/zlib.h b/x-loader/include/x-load/zlib.h new file mode 100644 index 0000000..fb27081 --- /dev/null +++ b/x-loader/include/x-load/zlib.h
@@ -0,0 +1,698 @@ +/* + * This file is derived from zlib.h and zconf.h from the zlib-1.2.3 + * distribution by Jean-loup Gailly and Mark Adler, with some additions + * by Paul Mackerras to aid in implementing Deflate compression and + * decompression for PPP packets. + */ + + /* + * ==FILEVERSION 960122== + * + * This marker is used by the Linux installation script to determine + * whether an up-to-date version of this file is already installed. + */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* #include "zconf.h" */ /* included directly here */ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* Begin of new zconf.h */ +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# define z_off_t off_t +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif +/* End of new zconf.h */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt size)); +typedef void (*cb_func) OF((Bytef *buf, uInt len)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + int data_type; /* best guess about the data type: + binary or text */ + cb_func outcb; /* called regularly just before blocks of output */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + + /* constants */ +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + + /* basic functions */ + +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, + int stream_size)); + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uInt ZEXPORT crc32 OF((uInt crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */
diff --git a/x-loader/lib/Makefile b/x-loader/lib/Makefile new file mode 100644 index 0000000..6403442 --- /dev/null +++ b/x-loader/lib/Makefile
@@ -0,0 +1,62 @@ +# +# (C) Copyright 2004 Texas Instruments +# +# (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$(ARCH).a + +SOBJS += _ashldi3.o +SOBJS += _divsi3.o +SOBJS += _lshrdi3.o +SOBJS += _modsi3.o +SOBJS += _udivsi3.o +SOBJS += _umodsi3.o + +COBJS-y += crc32.o +COBJS-y += ctype.o +COBJS-y += display_options.o +COBJS-y += div0.o +COBJS-y += board.o +COBJS-y += string.o +COBJS-y += ecc.o +COBJS-y += printf.o +COBJS-y += omap_bch_decoder.o +COBJS-y += omap_bch.o + +COBJS := $(COBJS-y) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/lib/_ashldi3.S b/x-loader/lib/_ashldi3.S new file mode 100644 index 0000000..834ddc2 --- /dev/null +++ b/x-loader/lib/_ashldi3.S
@@ -0,0 +1,48 @@ +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 + Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + + +#ifdef __ARMEB__ +#define al r1 +#define ah r0 +#else +#define al r0 +#define ah r1 +#endif + +.globl __ashldi3 +.globl __aeabi_llsl +__ashldi3: +__aeabi_llsl: + + subs r3, r2, #32 + rsb ip, r2, #32 + movmi ah, ah, lsl r2 + movpl ah, al, lsl r3 + orrmi ah, ah, al, lsr ip + mov al, al, lsl r2 + mov pc, lr
diff --git a/x-loader/lib/_divsi3.S b/x-loader/lib/_divsi3.S new file mode 100644 index 0000000..cfbadb2 --- /dev/null +++ b/x-loader/lib/_divsi3.S
@@ -0,0 +1,142 @@ + +.macro ARM_DIV_BODY dividend, divisor, result, curbit + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \curbit, \divisor + clz \result, \dividend + sub \result, \curbit, \result + mov \curbit, #1 + mov \divisor, \divisor, lsl \result + mov \curbit, \curbit, lsl \result + mov \result, #0 + +#else + + @ Initially shift the divisor left 3 bits if possible, + @ set curbit accordingly. This allows for curbit to be located + @ at the left end of each 4 bit nibbles in the division loop + @ to save one loop in most cases. + tst \divisor, #0xe0000000 + moveq \divisor, \divisor, lsl #3 + moveq \curbit, #8 + movne \curbit, #1 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + movlo \curbit, \curbit, lsl #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + movlo \curbit, \curbit, lsl #1 + blo 1b + + mov \result, #0 + +#endif + + @ Division loop +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + orrhs \result, \result, \curbit + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + orrhs \result, \result, \curbit, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + orrhs \result, \result, \curbit, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + orrhs \result, \result, \curbit, lsr #3 + cmp \dividend, #0 @ Early termination? + movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? + movne \divisor, \divisor, lsr #4 + bne 1b + +.endm + +.macro ARM_DIV2_ORDER divisor, order + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + rsb \order, \order, #31 + +#else + + cmp \divisor, #(1 << 16) + movhs \divisor, \divisor, lsr #16 + movhs \order, #16 + movlo \order, #0 + + cmp \divisor, #(1 << 8) + movhs \divisor, \divisor, lsr #8 + addhs \order, \order, #8 + + cmp \divisor, #(1 << 4) + movhs \divisor, \divisor, lsr #4 + addhs \order, \order, #4 + + cmp \divisor, #(1 << 2) + addhi \order, \order, #3 + addls \order, \order, \divisor, lsr #1 + +#endif + +.endm + + .align 5 +.globl __divsi3 +.globl __aeabi_idiv +__divsi3: +__aeabi_idiv: + cmp r1, #0 + eor ip, r0, r1 @ save the sign of the result. + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + subs r2, r1, #1 @ division by 1 or -1 ? + beq 10f + movs r3, r0 + rsbmi r3, r0, #0 @ positive dividend value + cmp r3, r1 + bls 11f + tst r1, r2 @ divisor is power of 2 ? + beq 12f + + ARM_DIV_BODY r3, r1, r0, r2 + + cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + +10: teq ip, r0 @ same sign ? + rsbmi r0, r0, #0 + mov pc, lr + +11: movlo r0, #0 + moveq r0, ip, asr #31 + orreq r0, r0, #1 + mov pc, lr + +12: ARM_DIV2_ORDER r1, r2 + + cmp ip, #0 + mov r0, r3, lsr r2 + rsbmi r0, r0, #0 + mov pc, lr + +Ldiv0: + + str lr, [sp, #-4]! + bl __div0 + mov r0, #0 @ About as wrong as it could be. + ldr pc, [sp], #4
diff --git a/x-loader/lib/_lshrdi3.S b/x-loader/lib/_lshrdi3.S new file mode 100644 index 0000000..e7fa799 --- /dev/null +++ b/x-loader/lib/_lshrdi3.S
@@ -0,0 +1,48 @@ +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 + Free Software Foundation, Inc. + +This file 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, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +This file 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; see the file COPYING. If not, write to +the Free Software Foundation, 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ + + +#ifdef __ARMEB__ +#define al r1 +#define ah r0 +#else +#define al r0 +#define ah r1 +#endif + +.globl __lshrdi3 +.globl __aeabi_llsr +__lshrdi3: +__aeabi_llsr: + + subs r3, r2, #32 + rsb ip, r2, #32 + movmi al, al, lsr r2 + movpl al, ah, lsr r3 + orrmi al, al, ah, lsl ip + mov ah, ah, lsr r2 + mov pc, lr
diff --git a/x-loader/lib/_modsi3.S b/x-loader/lib/_modsi3.S new file mode 100644 index 0000000..539c584 --- /dev/null +++ b/x-loader/lib/_modsi3.S
@@ -0,0 +1,99 @@ + +.macro ARM_MOD_BODY dividend, divisor, order, spare + +#if __LINUX_ARM_ARCH__ >= 5 + + clz \order, \divisor + clz \spare, \dividend + sub \order, \order, \spare + mov \divisor, \divisor, lsl \order + +#else + + mov \order, #0 + + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. +1: cmp \divisor, #0x10000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #4 + addlo \order, \order, #4 + blo 1b + + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. +1: cmp \divisor, #0x80000000 + cmplo \divisor, \dividend + movlo \divisor, \divisor, lsl #1 + addlo \order, \order, #1 + blo 1b + +#endif + + @ Perform all needed substractions to keep only the reminder. + @ Do comparisons in batch of 4 first. + subs \order, \order, #3 @ yes, 3 is intended here + blt 2f + +1: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + cmp \dividend, \divisor, lsr #1 + subhs \dividend, \dividend, \divisor, lsr #1 + cmp \dividend, \divisor, lsr #2 + subhs \dividend, \dividend, \divisor, lsr #2 + cmp \dividend, \divisor, lsr #3 + subhs \dividend, \dividend, \divisor, lsr #3 + cmp \dividend, #1 + mov \divisor, \divisor, lsr #4 + subges \order, \order, #4 + bge 1b + + tst \order, #3 + teqne \dividend, #0 + beq 5f + + @ Either 1, 2 or 3 comparison/substractions are left. +2: cmn \order, #2 + blt 4f + beq 3f + cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +3: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor + mov \divisor, \divisor, lsr #1 +4: cmp \dividend, \divisor + subhs \dividend, \dividend, \divisor +5: +.endm + + .align 5 +.globl __modsi3 +__modsi3: + cmp r1, #0 + beq Ldiv0 + rsbmi r1, r1, #0 @ loops below use unsigned. + movs ip, r0 @ preserve sign of dividend + rsbmi r0, r0, #0 @ if negative make positive + subs r2, r1, #1 @ compare divisor with 1 + cmpne r0, r1 @ compare dividend with divisor + moveq r0, #0 + tsthi r1, r2 @ see if divisor is power of 2 + andeq r0, r0, r2 + bls 10f + + ARM_MOD_BODY r0, r1, r2, r3 + +10: cmp ip, #0 + rsbmi r0, r0, #0 + mov pc, lr + + +Ldiv0: + + str lr, [sp, #-4]! + bl __div0 + mov r0, #0 @ About as wrong as it could be. + ldr pc, [sp], #4
diff --git a/x-loader/lib/_udivsi3.S b/x-loader/lib/_udivsi3.S new file mode 100644 index 0000000..2cdcd48 --- /dev/null +++ b/x-loader/lib/_udivsi3.S
@@ -0,0 +1,77 @@ +/* # 1 "libgcc1.S" */ +@ libgcc1 routines for ARM cpu. +@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) +dividend .req r0 +divisor .req r1 +result .req r2 +curbit .req r3 +/* ip .req r12 */ +/* sp .req r13 */ +/* lr .req r14 */ +/* pc .req r15 */ + .text + .globl __udivsi3 + .type __udivsi3 ,function + .align 0 + __udivsi3 : + cmp divisor, #0 + beq Ldiv0 + mov curbit, #1 + mov result, #0 + cmp dividend, divisor + bcc Lgot_result +Loop1: + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. + cmp divisor, #0x10000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #4 + movcc curbit, curbit, lsl #4 + bcc Loop1 +Lbignum: + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. + cmp divisor, #0x80000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #1 + movcc curbit, curbit, lsl #1 + bcc Lbignum +Loop3: + @ Test for possible subtractions, and note which bits + @ are done in the result. On the final pass, this may subtract + @ too much from the dividend, but the result will be ok, since the + @ "bit" will have been shifted out at the bottom. + cmp dividend, divisor + subcs dividend, dividend, divisor + orrcs result, result, curbit + cmp dividend, divisor, lsr #1 + subcs dividend, dividend, divisor, lsr #1 + orrcs result, result, curbit, lsr #1 + cmp dividend, divisor, lsr #2 + subcs dividend, dividend, divisor, lsr #2 + orrcs result, result, curbit, lsr #2 + cmp dividend, divisor, lsr #3 + subcs dividend, dividend, divisor, lsr #3 + orrcs result, result, curbit, lsr #3 + cmp dividend, #0 @ Early termination? + movnes curbit, curbit, lsr #4 @ No, any more bits to do? + movne divisor, divisor, lsr #4 + bne Loop3 +Lgot_result: + mov r0, result + mov pc, lr +Ldiv0: + str lr, [sp, #-4]! + bl __div0 (PLT) + mov r0, #0 @ about as wrong as it could be + ldmia sp!, {pc} + .size __udivsi3 , . - __udivsi3 +/* # 235 "libgcc1.S" */ +/* # 320 "libgcc1.S" */ +/* # 421 "libgcc1.S" */ +/* # 433 "libgcc1.S" */ +/* # 456 "libgcc1.S" */ +/* # 500 "libgcc1.S" */ +/* # 580 "libgcc1.S" */
diff --git a/x-loader/lib/_umodsi3.S b/x-loader/lib/_umodsi3.S new file mode 100644 index 0000000..e4aebe8 --- /dev/null +++ b/x-loader/lib/_umodsi3.S
@@ -0,0 +1,88 @@ +/* # 1 "libgcc1.S" */ +@ libgcc1 routines for ARM cpu. +@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) +/* # 145 "libgcc1.S" */ +dividend .req r0 +divisor .req r1 +overdone .req r2 +curbit .req r3 +/* ip .req r12 */ +/* sp .req r13 */ +/* lr .req r14 */ +/* pc .req r15 */ + .text + .globl __umodsi3 + .type __umodsi3 ,function + .align 0 + __umodsi3 : + cmp divisor, #0 + beq Ldiv0 + mov curbit, #1 + cmp dividend, divisor + movcc pc, lr +Loop1: + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. + cmp divisor, #0x10000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #4 + movcc curbit, curbit, lsl #4 + bcc Loop1 +Lbignum: + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. + cmp divisor, #0x80000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #1 + movcc curbit, curbit, lsl #1 + bcc Lbignum +Loop3: + @ Test for possible subtractions. On the final pass, this may + @ subtract too much from the dividend, so keep track of which + @ subtractions are done, we can fix them up afterwards... + mov overdone, #0 + cmp dividend, divisor + subcs dividend, dividend, divisor + cmp dividend, divisor, lsr #1 + subcs dividend, dividend, divisor, lsr #1 + orrcs overdone, overdone, curbit, ror #1 + cmp dividend, divisor, lsr #2 + subcs dividend, dividend, divisor, lsr #2 + orrcs overdone, overdone, curbit, ror #2 + cmp dividend, divisor, lsr #3 + subcs dividend, dividend, divisor, lsr #3 + orrcs overdone, overdone, curbit, ror #3 + mov ip, curbit + cmp dividend, #0 @ Early termination? + movnes curbit, curbit, lsr #4 @ No, any more bits to do? + movne divisor, divisor, lsr #4 + bne Loop3 + @ Any subtractions that we should not have done will be recorded in + @ the top three bits of "overdone". Exactly which were not needed + @ are governed by the position of the bit, stored in ip. + @ If we terminated early, because dividend became zero, + @ then none of the below will match, since the bit in ip will not be + @ in the bottom nibble. + ands overdone, overdone, #0xe0000000 + moveq pc, lr @ No fixups needed + tst overdone, ip, ror #3 + addne dividend, dividend, divisor, lsr #3 + tst overdone, ip, ror #2 + addne dividend, dividend, divisor, lsr #2 + tst overdone, ip, ror #1 + addne dividend, dividend, divisor, lsr #1 + mov pc, lr +Ldiv0: + str lr, [sp, #-4]! + bl __div0 (PLT) + mov r0, #0 @ about as wrong as it could be + ldmia sp!, {pc} + .size __umodsi3 , . - __umodsi3 +/* # 320 "libgcc1.S" */ +/* # 421 "libgcc1.S" */ +/* # 433 "libgcc1.S" */ +/* # 456 "libgcc1.S" */ +/* # 500 "libgcc1.S" */ +/* # 580 "libgcc1.S" */
diff --git a/x-loader/lib/board.c b/x-loader/lib/board.c new file mode 100644 index 0000000..a493584 --- /dev/null +++ b/x-loader/lib/board.c
@@ -0,0 +1,481 @@ +/* + * Copyright (C) 2005 Texas Instruments. + * + * (C) Copyright 2004 + * Jian Zhang, Texas Instruments, jzhang@ti.com. + * + * (C) Copyright 2002-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.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 <bootm.h> +#include <part.h> +#include <fat.h> +#include <image.h> +#include <mmc.h> +#include <timestamp.h> +#include <version.h> +#include <asm/arch/mem.h> + +/* + * Preprocessor Definitions + */ +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +/* Type Definition */ + +typedef int (init_fnc_t)(void); + +/* + * Function Prototypes + */ +extern int misc_init_r (void); +extern int mmc_init(int verbose); +extern block_dev_desc_t *mmc_get_dev(int dev); +extern int get_boot_devices_list(const u32** devices_list); + +/* + * Global Variables + */ +const char version_string[] = + X_LOADER_VERSION" (" X_LOADER_DATE " - " X_LOADER_TIME ")"CONFIG_IDENT_STRING; + +init_fnc_t *init_sequence[] = { + cpu_init, /* basic cpu dependent setup */ + board_init, /* basic board dependent setup */ +#ifdef CFG_PRINTF + serial_init, /* serial communications setup */ + display_options, +#endif + nand_init, /* board specific nand init */ + NULL, +}; + +static inline int check_load_params(const uint8_t *buffer, const int *index, int count) +{ + if (buffer == NULL || index == NULL || count == 0 || *index < BOOTM_INDEX_START || *index >= count) { + return (BOOTM_STATUS_FAILURE); + } + + return (BOOTM_STATUS_SUCCESS); +} + +#if (defined(CFG_MMC_ONENAND) || defined (CFG_MMC_NAND)) && defined(CFG_CMD_FAT) +/* + * int fat_load() + * + * Description: + * This routine attempts to read from the first initialized + * Multimedia Card (MMC) device, one of one or more designated + * secondary program loaders (SPL) from the a FAT file system on + * the first partition of a Master Boot Record volume. + * + * Input(s): + * buffer - A pointer to storage for the secondary program loader. + * index - A pointer to the index of boot file to attempt to load. + * + * Output(s): + * buffer - A pointer to the secondary program loader. + * index - A pointer to the index of the next boot file to + * attempt to load. + * + * Returns: + * BOOTM_STATUS_SUCCESS on success; otherwise, BOOTM_STATUS_FAILURE + * on error. + * + */ +static int fat_load(uint8_t *buffer, int *index) +{ +#if defined(CONFIG_BOOTFILE) + const char * const files[] = { CONFIG_BOOTFILE }; +#elif defined(CONFIG_BOOTFILE_LIST) && defined(CONFIG_BOOTM_IMAGE) + const char * const files[] = CONFIG_BOOTFILE_LIST; +#else + const char * const files[] = { NULL }; +#endif /* defined(CONFIG_BOOTFILE) */ + const char * file = NULL; + const char * failure = NULL; + const int count = ARRAY_SIZE(files); + const int device = 0; + const int partition = 1; + const int maxsize = 0; + const int verbose = 1; + long size = 0; + block_dev_desc_t *dev_desc = NULL; + unsigned char status = 0; + + if (!check_load_params(buffer, index, count)) { + return (BOOTM_STATUS_FAILURE); + } + + file = files[(*index)++]; + + if (*index >= count) { + *index = BOOTM_INDEX_STOP; + } + + status = mmc_init(verbose); + + if (status == 0) { + failure = "MMC initialization failed\n"; + goto fail; + } + + dev_desc = mmc_get_dev(device); + + if (dev_desc == NULL) { + failure = "Could not access MMC device\n"; + goto fail; + } + + fat_register_device(dev_desc, partition); + + size = file_fat_read(file, buffer, maxsize); + + if (size == -1) { + printf("Could not read file \"%s\"\n", file); + goto fail; + } + + printf("\n%ld bytes read\n", size); + + printf("Loading from MMC%d, file \"%s\"\n", device, file); + + return (BOOTM_STATUS_SUCCESS); + + fail: + if (failure != NULL) { + puts(failure); + } + + return (BOOTM_STATUS_FAILURE); +} +#endif /* (defined(CFG_MMC_ONENAND) || defined (CFG_MMC_NAND)) && defined(CFG_CMD_FAT) */ + +/* + * int block_load() + * + * Description: + * This routine attempts to read from a block device one of one or + * more designated secondary program loaders (SPL) specified by the + * array of block extents. + * + * Input(s): + * buffer - A pointer to storage for the secondary program + * loader. + * index - A pointer to the index of boot extent to attempt to + * load. + * count - The total number of extents. + * extents - The array of boot file extents to attempt to load. + * device - A pointer to a C string describing the block device + * being loaded from. + * read - A pointer to the device-specific function that will + * read the blocks to load. + * block_size - The size, in bytes, of the device's fundamental read + * block size. + * + * + * Output(s): + * buffer - A pointer to the secondary program loader. + * index - A pointer to the index of the next boot extent to + * attempt to load. + * + * Returns: + * BOOTM_STATUS_SUCCESS on success; otherwise, BOOTM_STATUS_FAILURE + * on error. + * + */ +static int block_load(uint8_t *buffer, int *index, int count, const boot_extent_t extents[], const char *device, int (*read)(unsigned char *, ulong), unsigned long block_size) +{ + const boot_extent_t *extent = NULL; + unsigned long address; + unsigned long end; + int read_status; + + if (!check_load_params(buffer, index, count)) { + return (BOOTM_STATUS_FAILURE); + } + + extent = &extents[(*index)++]; + + if (*index >= count) { + *index = BOOTM_INDEX_STOP; + } + + end = extent->start + extent->size + 1; + + for (address = extent->start; address < end; address += block_size) { + read_status = read(buffer, address); + + /* If successful, move the data pointer. If ECC fails, + * report failure to caller. If skipping bad block, + * just continue looping without moving the data pointer. + */ + if (read_status == NAND_READ_SUCCESS) + { + buffer += block_size; + } + else if (read_status == NAND_READ_ECC_FAILURE) + { + return (BOOTM_STATUS_FAILURE); + } + } + + printf("Loading from %s, offset %#08lx\n", device, extent->start); + + return (BOOTM_STATUS_SUCCESS); +} + +#if defined(CFG_GPMC_ONENAND) +/* + * int onenand_load() + * + * Description: + * This routine attempts to read from a OneNAND device one of one or + * more designated secondary program loaders (SPL) specified by the + * array of block extents. + * + * Input(s): + * buffer - A pointer to storage for the secondary program + * loader. + * index - A pointer to the index of boot extent to attempt to + * load. + * + * Output(s): + * buffer - A pointer to the secondary program loader. + * index - A pointer to the index of the next boot extent to + * attempt to load. + * + * Returns: + * BOOTM_STATUS_SUCCESS on success; otherwise, BOOTM_STATUS_FAILURE + * on error. + * + */ +static int onenand_load(uint8_t *buffer, int *index) +{ +#if defined(CONFIG_ONENAND_BOOTEXTENT) + const boot_extent_t extents[] = { CONFIG_ONENAND_BOOTEXTENT }; +#elif defined(CONFIG_ONENAND_BOOTEXTENT_LIST) && defined(CONFIG_BOOTM_IMAGE) + const boot_extent_t extents[] = CONFIG_ONENAND_BOOTEXTENT_LIST; +#else + const boot_extent_t extents[] = { NULL }; +#endif /* defined(CONFIG_ONENAND_BOOTEXTENT) */ + + return block_load(buffer, + index, + ARRAY_SIZE(extents), + extents, + "OneNAND", + onenand_read_block, + ONENAND_BLOCK_SIZE); +} +#endif /* defined(CFG_GPMC_ONENAND) */ + +#if defined(CFG_GPMC_NAND) +/* + * int nand_load() + * + * Description: + * This routine attempts to read from a NAND device one of one or + * more designated secondary program loaders (SPL) specified by the + * array of block extents. + * + * Input(s): + * buffer - A pointer to storage for the secondary program + * loader. + * index - A pointer to the index of boot extent to attempt to + * load. + * + * Output(s): + * buffer - A pointer to the secondary program loader. + * index - A pointer to the index of the next boot extent to + * attempt to load. + * + * Returns: + * BOOTM_STATUS_SUCCESS on success; otherwise, BOOTM_STATUS_FAILURE + * on error. + * + */ +static int nand_load(uint8_t *buffer, int *index) +{ +#if defined(CONFIG_NAND_BOOTEXTENT) + const boot_extent_t extents[] = { CONFIG_NAND_BOOTEXTENT }; +#elif defined(CONFIG_NAND_BOOTEXTENT_LIST) && defined(CONFIG_BOOTM_IMAGE) + const boot_extent_t extents[] = CONFIG_NAND_BOOTEXTENT_LIST; +#else + const boot_extent_t extents[] = { NULL }; +#endif /* defined(CONFIG_NAND_BOOTEXTENT) */ + + return block_load(buffer, + index, + ARRAY_SIZE(extents), + extents, + "NAND", + nand_read_block, + NAND_BLOCK_SIZE); +} +#endif /* defined(CFG_GPMC_NAND) */ + +/* + * void do_arm_boot() + * + * Description: + * This routine attempts to boot the system from the specified + * boot device after copying the secondary-program loader into + * the specified memory buffer. + * + * Input(s): + * buffer - A pointer to storage for the secondary program + * loader. + * type - The boot device to boot from. + * + * Output(s): + * buffer - A pointer to the secondary program loader. + * + * Returns: + * N/A + * + */ +static void do_arm_boot(uint8_t *buffer, u32 type) +{ + int index = BOOTM_INDEX_START; + int status = BOOTM_STATUS_FAILURE; + device_load load_image = NULL; + + /* Determine, based on the boot setting, the source we are going + * to attempt to boot from. + */ + + switch (type) { + +#if ((defined(CFG_MMC_ONENAND) || defined (CFG_MMC_NAND)) && defined(CFG_CMD_FAT)) + case MMC_NAND: + case MMC_ONENAND: + load_image = fat_load; + break; +#endif + +#if defined(CFG_GPMC_ONENAND) + case GPMC_ONENAND: + load_image = onenand_load; + break; +#endif + +#if defined(CFG_GPMC_NAND) + case GPMC_NAND: + load_image = nand_load; + break; +#endif + + default: + goto fail; + + } + + /* Attempt to load and boot any configured images until we + * successfully boot or until we've exhausted all possible images. + */ + + do { + status = load_image(buffer, &index); + + if (bootm_load_successful(status)) { + status = bootm(buffer); + } + + } while (bootm_load_continue(status, index)); +fail: + return; +} + +void start_armboot (void) +{ + const u32* devices_list = NULL; + int devIdx; + int boot_devices_count = get_boot_devices_list(&devices_list); + const char * boot_name = NULL; + init_fnc_t **init_fnc_ptr; + uint8_t *buffer = (uint8_t *)CFG_LOADADDR; + + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr)() != 0) { + goto fail; + } + } + + misc_init_r(); + + for( devIdx = 0; devIdx < boot_devices_count; devIdx++ ) + { + u32 boot_dev = devices_list[devIdx]; + switch (boot_dev) { + + case MMC_NAND: + case MMC_ONENAND: + boot_name = "MMC"; + break; + + case GPMC_ONENAND: + boot_name = "OneNAND"; + break; + + case GPMC_NAND: + boot_name = "NAND"; + break; + case USB_PERIPHERAL: + boot_name = ""; + printf("Trying load from USB\n"); + do_usb(); /* check for usb download */ + break; + default: + boot_name = "<unknown>"; + break; + + } + + debug("Trying X-Loader on %s\n", boot_name); + /* This should never return. */ + do_arm_boot(buffer, boot_dev); + } + + /* If for some reason it does, we have only one choice, hang. */ + puts("Images exhausted\n"); +fail: + hang(); +} + +void hang (void) +{ + /* call board specific hang function */ + board_hang(); + + /* if board_hang() returns, hange here */ + puts("X-Loader hangs\n"); + + for (;;); +}
diff --git a/x-loader/lib/bootm.c b/x-loader/lib/bootm.c new file mode 100644 index 0000000..3101321 --- /dev/null +++ b/x-loader/lib/bootm.c
@@ -0,0 +1,242 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.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 + * + */ + +#include <common.h> +#include <command.h> +#include <image.h> +#include <u-boot/zlib.h> +#include <asm/byteorder.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); + +static struct tag *params; +#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ + +int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) +{ + bd_t *bd = gd->bd; + char *s; + int machid = bd->bi_arch_number; + void (*theKernel)(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; + + theKernel = (void (*)(int, int, uint))images->ep; + + s = getenv ("machid"); + if (s) { + machid = simple_strtoul (s, NULL, 16); + printf ("Using machid 0x%x from environment\n", machid); + } + + show_boot_progress (15); + + debug ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); + +#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 + + /* we assume that the kernel is in place */ + printf ("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_USB_DEVICE + { + extern void udc_disconnect (void); + udc_disconnect (); + } +#endif + + cleanup_before_linux (); + + theKernel (0, machid, bd->bi_boot_params); + /* does not return */ + + return 1; +} + + +#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->hdr.tag = ATAG_CORE; + params->hdr.size = tag_size (tag_core); + + params->u.core.flags = 0; + params->u.core.pagesize = 0; + params->u.core.rootdev = 0; + + params = tag_next (params); +} + + +#ifdef CONFIG_SETUP_MEMORY_TAGS +static void setup_memory_tags (bd_t *bd) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + params->hdr.tag = ATAG_MEM; + params->hdr.size = tag_size (tag_mem32); + + params->u.mem.start = bd->bi_dram[i].start; + params->u.mem.size = bd->bi_dram[i].size; + + params = tag_next (params); + } +} +#endif /* CONFIG_SETUP_MEMORY_TAGS */ + + +static void setup_commandline_tag (bd_t *bd, char *commandline) +{ + char *p; + + if (!commandline) + return; + + /* eat leading white space */ + for (p = commandline; *p == ' '; p++); + + /* skip non-existent command lines so the kernel will still + * use its default command line. + */ + if (*p == '\0') + return; + + params->hdr.tag = ATAG_CMDLINE; + params->hdr.size = + (sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2; + + strcpy (params->u.cmdline.cmdline, p); + + params = tag_next (params); +} + + +#ifdef CONFIG_INITRD_TAG +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->hdr.tag = ATAG_INITRD2; + params->hdr.size = tag_size (tag_initrd); + + params->u.initrd.start = initrd_start; + params->u.initrd.size = initrd_end - initrd_start; + + params = tag_next (params); +} +#endif /* CONFIG_INITRD_TAG */ + +#ifdef CONFIG_SERIAL_TAG +void setup_serial_tag (struct tag **tmp) +{ + struct tag *params = *tmp; + struct tag_serialnr serialnr; + void get_board_serial(struct tag_serialnr *serialnr); + + get_board_serial(&serialnr); + params->hdr.tag = ATAG_SERIAL; + params->hdr.size = tag_size (tag_serialnr); + params->u.serialnr.low = serialnr.low; + params->u.serialnr.high= serialnr.high; + params = tag_next (params); + *tmp = params; +} +#endif + +#ifdef CONFIG_REVISION_TAG +void setup_revision_tag(struct tag **in_params) +{ + u32 rev = 0; + u32 get_board_rev(void); + + rev = get_board_rev(); + params->hdr.tag = ATAG_REVISION; + params->hdr.size = tag_size (tag_revision); + params->u.revision.rev = rev; + params = tag_next (params); +} +#endif /* 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 */
diff --git a/x-loader/lib/crc32.c b/x-loader/lib/crc32.c new file mode 100644 index 0000000..997494c --- /dev/null +++ b/x-loader/lib/crc32.c
@@ -0,0 +1,235 @@ +/* + * This file is derived from crc32.c from the zlib-1.1.3 distribution + * by Jean-loup Gailly and Mark Adler. + */ + +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef USE_HOSTCC +#include <common.h> +#endif +#include <compiler.h> +#include <x-load/crc.h> + +#include "x-load/zlib.h" + +#define local static +#define ZEXPORT /* empty */ + +#define tole(x) cpu_to_le32(x) + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local uint32_t crc_table[256]; +local void make_crc_table OF((void)); + +/* + Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all + the information needed to generate CRC's on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +local void make_crc_table() +{ + uint32_t c; + int n, k; + uLong poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + poly = 0L; + for (n = 0; n < sizeof(p)/sizeof(Byte); n++) + poly |= 1L << (31 - p[n]); + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[n] = tole(c); + } + crc_table_empty = 0; +} +#else +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ + +local const uint32_t crc_table[256] = { +tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL), +tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L), +tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L), +tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L), +tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL), +tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L), +tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL), +tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L), +tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L), +tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL), +tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L), +tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L), +tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L), +tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL), +tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L), +tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL), +tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL), +tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L), +tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L), +tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L), +tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL), +tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L), +tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL), +tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L), +tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L), +tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL), +tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L), +tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L), +tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L), +tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL), +tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L), +tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL), +tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL), +tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L), +tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L), +tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L), +tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL), +tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L), +tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL), +tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L), +tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L), +tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL), +tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L), +tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L), +tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L), +tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL), +tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L), +tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL), +tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL), +tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L), +tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L), +tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L), +tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL), +tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L), +tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL), +tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L), +tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L), +tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL), +tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L), +tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L), +tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L), +tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL), +tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L), +tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL) +}; +#endif + +/* ========================================================================= */ +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc >> 8) +# else +# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) +# endif + +/* ========================================================================= */ + +/* No ones complement version. JFFS2 (and other things ?) + * don't use ones compliment in their CRC calculations. + */ +uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len) +{ + const uint32_t *tab = crc_table; + const uint32_t *b =(const uint32_t *)buf; + size_t rem_len; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = cpu_to_le32(crc); + /* Align it */ + if (((long)b) & 3 && len) { + uint8_t *p = (uint8_t *)b; + do { + DO_CRC(*p++); + } while ((--len) && ((long)p)&3); + b = (uint32_t *)p; + } + + rem_len = len & 3; + len = len >> 2; + for (--b; len; --len) { + /* load data 32 bits wide, xor data 32 bits wide. */ + crc ^= *++b; /* use pre increment for speed */ + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + DO_CRC(0); + } + len = rem_len; + /* And the last few bytes */ + if (len) { + uint8_t *p = (uint8_t *)(b + 1) - 1; + do { + DO_CRC(*++p); /* use pre increment for speed */ + } while (--len); + } + + return le32_to_cpu(crc); +} +#undef DO_CRC + +uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *p, uInt len) +{ + return crc32_no_comp(crc ^ 0xffffffffL, p, len) ^ 0xffffffffL; +} + +/* + * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes + * of input. + */ +uint32_t ZEXPORT crc32_wd (uint32_t crc, + const unsigned char *buf, + uInt len, uInt chunk_sz) +{ +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + const unsigned char *end, *curr; + int chunk; + + curr = buf; + end = buf + len; + while (curr < end) { + chunk = end - curr; + if (chunk > chunk_sz) + chunk = chunk_sz; + crc = crc32 (crc, curr, chunk); + curr += chunk; + WATCHDOG_RESET (); + } +#else + crc = crc32 (crc, buf, len); +#endif + + return crc; +}
diff --git a/x-loader/lib/ctype.c b/x-loader/lib/ctype.c new file mode 100644 index 0000000..6ed0468 --- /dev/null +++ b/x-loader/lib/ctype.c
@@ -0,0 +1,56 @@ +/* + * (C) Copyright 2000 + * 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 + */ + +/* + * linux/lib/ctype.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include <linux/ctype.h> + +unsigned char _ctype[] = { +_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ +_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ +_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ +_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ +_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ +_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ +_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ +_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ +_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
diff --git a/x-loader/lib/display_options.c b/x-loader/lib/display_options.c new file mode 100644 index 0000000..6ed74ba --- /dev/null +++ b/x-loader/lib/display_options.c
@@ -0,0 +1,149 @@ +/* + * (C) Copyright 2000-2002 + * 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 <config.h> +#include <common.h> +#include <linux/ctype.h> +int display_options (void) +{ + extern char version_string[]; + +#if defined(BUILD_TAG) + printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG); +#else + printf ("\n\n%s\n\n", version_string); +#endif + return 0; +} + +/* + * print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB", + * xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string + * (like "\n") + */ +void print_size(unsigned long long size, const char *s) +{ + unsigned long m = 0, n; + unsigned long long f; + static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'}; + unsigned long d = 10 * ARRAY_SIZE(names); + char c = 0; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) { + if (size >> d) { + c = names[i]; + break; + } + } + + if (!c) { + printf("%llu Bytes%s", size, s); + return; + } + + n = size >> d; + f = size & ((1ULL << d) - 1); + + /* If there's a remainder, deal with it */ + if (f) { + m = (10ULL * f + (1ULL << (d - 1))) >> d; + + if (m >= 10) { + m -= 10; + n += 1; + } + } + + printf ("%lu", n); + if (m) { + printf (".%ld", m); + } + printf (" %ciB%s", c, s); +} + +/* + * Print data buffer in hex and ascii form to the terminal. + * + * data reads are buffered so that each memory address is only read once. + * Useful when displaying the contents of volatile registers. + * + * parameters: + * addr: Starting address to display at start of line + * data: pointer to data buffer + * width: data value width. May be 1, 2, or 4. + * count: number of values to display + * linelen: Number of values to print per line; specify 0 for default length + */ +#define MAX_LINE_LENGTH_BYTES (64) +#define DEFAULT_LINE_LENGTH_BYTES (16) +int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen) +{ + /* linebuf as a union causes proper alignment */ + union linebuf { + uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; + uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; + uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; + } lb; + int i; + + if (linelen*width > MAX_LINE_LENGTH_BYTES) + linelen = MAX_LINE_LENGTH_BYTES / width; + if (linelen < 1) + linelen = DEFAULT_LINE_LENGTH_BYTES / width; + + while (count) { + printf("%08lx:", addr); + + /* check for overflow condition */ + if (count < linelen) + linelen = count; + + /* Copy from memory into linebuf and print hex values */ + for (i = 0; i < linelen; i++) { + uint32_t x; + if (width == 4) + x = lb.ui[i] = *(volatile uint32_t *)data; + else if (width == 2) + x = lb.us[i] = *(volatile uint16_t *)data; + else + x = lb.uc[i] = *(volatile uint8_t *)data; + printf(" %0*x", width * 2, x); + data += width; + } + + /* Print data in ASCII characters */ + for (i = 0; i < linelen * width; i++) { + if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80) + lb.uc[i] = '.'; + } + lb.uc[i] = '\0'; + printf(" %s\n", lb.uc); + + /* update references */ + addr += linelen * width; + count -= linelen; + } + + return 0; +}
diff --git a/x-loader/lib/div0.c b/x-loader/lib/div0.c new file mode 100644 index 0000000..6267bf1 --- /dev/null +++ b/x-loader/lib/div0.c
@@ -0,0 +1,30 @@ +/* + * (C) Copyright 2002 + * 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 + */ + +/* Replacement (=dummy) for GNU/Linux division-by zero handler */ +void __div0 (void) +{ + extern void hang (void); + + hang(); +}
diff --git a/x-loader/lib/ecc.c b/x-loader/lib/ecc.c new file mode 100644 index 0000000..28fc40d --- /dev/null +++ b/x-loader/lib/ecc.c
@@ -0,0 +1,250 @@ +/* + * (C) Copyright 2000 Texas Instruments + * + * This file os based on the following u-boot file: + * common/cmd_nand.c + * + * 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> + +/* + * Pre-calculated 256-way 1 byte column parity + */ +static const u_char nand_ecc_precalc_table[] = { + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 +}; + + +/* + * Creates non-inverted ECC code from line parity + */ +static void nand_trans_result(u_char reg2, u_char reg3, + u_char *ecc_code) +{ + u_char a, b, i, tmp1, tmp2; + + /* Initialize variables */ + a = b = 0x80; + tmp1 = tmp2 = 0; + + /* Calculate first ECC byte */ + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + a >>= 1; + } + + /* Calculate second ECC byte */ + b = 0x80; + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + a >>= 1; + } + + /* Store two of the ECC bytes */ + ecc_code[0] = tmp1; + ecc_code[1] = tmp2; +} + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +/* ECC Calculation is different between NAND and NAND Legacy code + * in U-Boot. If NAND_LEGACY is enabled in u-boot it should be + * enabled in the config file in x-loader also + */ +#ifdef NAND_LEGACY +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg3; + int j; + + /* Initialize variables */ + reg1 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= idx; + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; +} +#else +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg2, reg3; + int j; + + /* Initialize variables */ + reg1 = reg2 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= (idx & 0x3f); + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + reg2 ^= ~((u_char) j); + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result(reg2, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; +} +#endif +/* + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + u_char a, b, c, d1, d2, d3, add, bit, i; + + /* Do error detection */ + d1 = calc_ecc[0] ^ read_ecc[0]; + d2 = calc_ecc[1] ^ read_ecc[1]; + d3 = calc_ecc[2] ^ read_ecc[2]; + + if ((d1 | d2 | d3) == 0) { + /* No errors */ + return 0; + } + else { + a = (d1 ^ (d1 >> 1)) & 0x55; + b = (d2 ^ (d2 >> 1)) & 0x55; + c = (d3 ^ (d3 >> 1)) & 0x54; + + /* Found and will correct single bit error in the data */ + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { + c = 0x80; + add = 0; + a = 0x80; + for (i=0; i<4; i++) { + if (d1 & c) + add |= a; + c >>= 2; + a >>= 1; + } + c = 0x80; + for (i=0; i<4; i++) { + if (d2 & c) + add |= a; + c >>= 2; + a >>= 1; + } + bit = 0; + b = 0x04; + c = 0x80; + for (i=0; i<3; i++) { + if (d3 & c) + bit |= b; + c >>= 2; + b >>= 1; + } + b = 0x01; + a = dat[add]; + a ^= (b << bit); + dat[add] = a; + return 1; + } + else { + i = 0; + while (d1) { + if (d1 & 0x01) + ++i; + d1 >>= 1; + } + while (d2) { + if (d2 & 0x01) + ++i; + d2 >>= 1; + } + while (d3) { + if (d3 & 0x01) + ++i; + d3 >>= 1; + } + if (i == 1) { + /* ECC Code Error Correction */ + read_ecc[0] = calc_ecc[0]; + read_ecc[1] = calc_ecc[1]; + read_ecc[2] = calc_ecc[2]; + return 2; + } + else { + /* Uncorrectable Error */ + return -1; + } + } + } + + /* Should never happen */ + return -1; +} +
diff --git a/x-loader/lib/omap_bch.c b/x-loader/lib/omap_bch.c new file mode 100644 index 0000000..3b424a6 --- /dev/null +++ b/x-loader/lib/omap_bch.c
@@ -0,0 +1,278 @@ +/* + * omap_bch.c + * + * Support modules for BCH 4-bit/8-bit error correction. + * + * Copyright (C) {2011} Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; 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> + +#define GPMC_ECC_BCH_RESULT_0 0x240 +#define PAGE_SIZE 2048 +#define NAND_ECC_READ 0 +#define NAND_ECC_WRITE 1 +#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v)) +#define __raw_readl(a) (*(volatile unsigned int *)(a)) + +int decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc); + +/* + * omap_calculate_ecc_bch8 - Version for 8BIT BCH correction. + * + * @dat: unused + * @ecc_code: ecc_code buffer + */ +int omap_calculate_ecc_bch8(const uint8_t *dat, + uint8_t *ecc_code) +{ + unsigned long reg, val1 = 0x0, val2 = 0x0; + unsigned long val3 = 0x0, val4 = 0x0; + int i; + + for (i = 0; i < PAGE_SIZE/512; i++) { + /* Reading HW ECC_BCH_Results + * 0x240-0x24C, 0x250-0x25C, 0x260-0x26C, 0x270-0x27C + */ + reg = (unsigned long)(GPMC_BASE + + GPMC_ECC_BCH_RESULT_0 + (0x10 * i)); + val1 = __raw_readl(reg); + val2 = __raw_readl(reg + 4); + val3 = __raw_readl(reg + 8); + val4 = __raw_readl(reg + 12); + + *ecc_code++ = (val4 & 0xFF); + *ecc_code++ = ((val3 >> 24) & 0xFF); + *ecc_code++ = ((val3 >> 16) & 0xFF); + *ecc_code++ = ((val3 >> 8) & 0xFF); + *ecc_code++ = (val3 & 0xFF); + *ecc_code++ = ((val2 >> 24) & 0xFF); + + *ecc_code++ = ((val2 >> 16) & 0xFF); + *ecc_code++ = ((val2 >> 8) & 0xFF); + *ecc_code++ = (val2 & 0xFF); + *ecc_code++ = ((val1 >> 24) & 0xFF); + *ecc_code++ = ((val1 >> 16) & 0xFF); + *ecc_code++ = ((val1 >> 8) & 0xFF); + *ecc_code++ = (val1 & 0xFF); + } + return 0; +} + +/* + * omap_calculate_ecc_bch4 - Version for 4BIT BCH correction. + * + * @dat: unused + * @ecc_code: ecc_code buffer + */ +int omap_calculate_ecc_bch4(const uint8_t *dat, + uint8_t *ecc_code) +{ + unsigned long reg, val1 = 0x0, val2 = 0x0; + int i; + + for (i = 0; i < PAGE_SIZE/512; i++) { + /* Reading HW ECC_BCH_Results + * 0x240-0x24C, 0x250-0x25C, 0x260-0x26C, 0x270-0x27C + */ + reg = (unsigned long)(GPMC_BASE + + GPMC_ECC_BCH_RESULT_0 + (0x10 * i)); + val1 = __raw_readl(reg); + val2 = __raw_readl(reg + 4); + + *ecc_code++ = ((val2 >> 16) & 0xFF); + *ecc_code++ = ((val2 >> 8) & 0xFF); + *ecc_code++ = (val2 & 0xFF); + *ecc_code++ = ((val1 >> 24) & 0xFF); + *ecc_code++ = ((val1 >> 16) & 0xFF); + *ecc_code++ = ((val1 >> 8) & 0xFF); + *ecc_code++ = (val1 & 0xFF); + } + return 0; +} + +/* Implementation for 4b/8b BCH correction. Pass either 4 or 8 into the + correct_bits parameter. */ +static int omap_correct_data_bch(int correct_bits, uint8_t *dat, + uint8_t *read_ecc, uint8_t *calc_ecc) +{ + int i=0, blockCnt=4, j, eccflag, count, corrected=0; + int eccsize = (correct_bits == 8) ? 13 : 7; + int mode = (correct_bits == 8) ? 1 : 0; + unsigned int err_loc[8]; + + if (correct_bits == 4) + omap_calculate_ecc_bch4(dat, calc_ecc); + else if (correct_bits == 8) + omap_calculate_ecc_bch8(dat, calc_ecc); + else + return -1; /* unsupported number of correction bits */ + + for (i = 0; i < blockCnt; i++) { + /* check if any ecc error */ + eccflag = 0; + for (j = 0; (j < eccsize) && (eccflag == 0); j++) + if (calc_ecc[j] != 0) + eccflag = 1; + + if (eccflag == 1) { + eccflag = 0; + for (j = 0; (j < eccsize) && (eccflag == 0); j++) + if (read_ecc[j] != 0xFF) + eccflag = 1; + } + + if (eccflag == 1) { + count = 0; + /*printk(KERN_INFO "...bch correct(%d 512 byte)\n", i+1);*/ + count = decode_bch(mode, calc_ecc, err_loc); + + /* + * If uncorrectable error detected in sub-page, + * keep uncorrectable flag to upper layer + */ + if(count == -1) + corrected = -1; + /* + * If no uncorrectable error then increment + * corrected count + */ + if(corrected != -1) + corrected += count; + + for (j = 0; j < count; j++) { + /*printk(KERN_INFO "err_loc=%d\n", err_loc[j]);*/ + printf("err_loc=%d\n", err_loc[j]); + if (err_loc[j] < 4096) + dat[err_loc[j] >> 3] ^= 1 << (err_loc[j] & 7); + /* else, not interested to correct ecc */ + } + + } + + calc_ecc = calc_ecc + eccsize; + read_ecc = read_ecc + eccsize; + dat += 512; + } + + return corrected; +} + +/* Wrapper function for 4 bit BCH correction */ +int omap_correct_data_bch4(uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) +{ + return omap_correct_data_bch(4, dat, read_ecc, calc_ecc); +} + +/* Wrapper function for 8 bit BCH correction */ +int omap_correct_data_bch8(uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) +{ + return omap_correct_data_bch(8, dat, read_ecc, calc_ecc); +} + +/* + * omap_enable_ecc - This function enables the hardware ecc functionality + * @mtd: MTD device structure + * @mode: Read/Write mode + */ +void omap_enable_hwecc_bch4(uint32_t bus_width, int32_t mode) +{ + uint32_t bch_mod=0; + uint32_t dev_width = (bus_width==8)?0:1; + unsigned int eccsize1, eccsize0; + unsigned int ecc_conf_val = 0, ecc_size_conf_val = 0; + + switch (mode) { + case NAND_ECC_READ : + eccsize1 = 0xD; eccsize0 = 0x48; + /* ECCSIZE1=26 | ECCSIZE0=12 */ + ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12); + + /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B | + * ECCTOPSECTOR | ECCCS | ECC Enable + */ + ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x09 << 8) | + (dev_width << 7) | (0x03 << 4) | + (0 << 1) | (0x1)); + break; + case NAND_ECC_WRITE : + eccsize1 = 0x20; eccsize0 = 0x00; + + /* ECCSIZE1=32 | ECCSIZE0=00 */ + ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12); + + /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B | + * ECCTOPSECTOR | ECCCS | ECC Enable + */ + ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x06 << 8) | + (dev_width << 7) | (0x03 << 4) | + (0 << 1) | (0x1)); + break; + default: + printf("Error: Unrecognized Mode[%d]!\n", mode); + break; + } + + __raw_writel(0x1, (GPMC_ECC_CONTROL)); + __raw_writel(ecc_size_conf_val, (GPMC_ECC_SIZE_CONFIG)); + __raw_writel(ecc_conf_val, (GPMC_ECC_CONFIG)); + __raw_writel(0x101, (GPMC_ECC_CONTROL)); +} + +/* + * omap_enable_ecc - This function enables the hardware ecc functionality + * @mtd: MTD device structure + * @mode: Read/Write mode + */ +void omap_enable_hwecc_bch8(uint32_t bus_width, int32_t mode) +{ + uint32_t bch_mod=1; + uint32_t dev_width = (bus_width==8)?0:1; + unsigned int eccsize1, eccsize0; + unsigned int ecc_conf_val = 0, ecc_size_conf_val = 0; + + switch (mode) { + case NAND_ECC_READ : + eccsize1 = 0x1A; eccsize0 = 0x18; + /* ECCSIZE1=26 | ECCSIZE0=12 */ + ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12); + + /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B | + * ECCTOPSECTOR | ECCCS | ECC Enable + */ + ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x04 << 8) | + (dev_width << 7) | (0x03 << 4) | + (0 << 1) | (0x1)); + break; + case NAND_ECC_WRITE : + eccsize1 = 0x20; eccsize0 = 0x00; + + /* ECCSIZE1=32 | ECCSIZE0=00 */ + ecc_size_conf_val = (eccsize1 << 22) | (eccsize0 << 12); + + /* ECCALGORITHM | ECCBCHT8 | ECCWRAPMODE | ECC16B | + * ECCTOPSECTOR | ECCCS | ECC Enable + */ + ecc_conf_val = ((0x01 << 16) | (bch_mod << 12) | (0x06 << 8) | + (dev_width << 7) | (0x03 << 4) | + (0 << 1) | (0x1)); + break; + default: + printf("Error: Unrecognized Mode[%d]!\n", mode); + break; + } + + __raw_writel(0x1, (GPMC_ECC_CONTROL)); + __raw_writel(ecc_size_conf_val, (GPMC_ECC_SIZE_CONFIG)); + __raw_writel(ecc_conf_val, (GPMC_ECC_CONFIG)); + __raw_writel(0x101, (GPMC_ECC_CONTROL)); +}
diff --git a/x-loader/lib/omap_bch_decoder.c b/x-loader/lib/omap_bch_decoder.c new file mode 100644 index 0000000..d77e93c --- /dev/null +++ b/x-loader/lib/omap_bch_decoder.c
@@ -0,0 +1,405 @@ +/* + * lib/omap_bch_decoder.c + * + * Whole BCH ECC Decoder (Post hardware generated syndrome decoding) + * + * Copyright (c) 2007 Texas Instruments + * + * Author: Sukumar Ghorai <s-ghorai@ti.com + * Michael Fillinger <m-fillinger@ti.com> + * + * 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 "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define printk //printf + +#define mm 13 +#define kk_shorten 4096 +#define nn 8191 /* Length of codeword, n = 2**mm - 1 */ + +#define PPP 0x201B /* Primary Polynomial : x^13 + x^4 + x^3 + x + 1 */ +#define P 0x001B /* With omitted x^13 */ +#define POLY 12 /* degree of the primary Polynomial less one */ + +/** + * mpy_mod_gf - GALOIS field multiplier + * Input : A(x), B(x) + * Output : A(x)*B(x) mod P(x) + */ +static unsigned int mpy_mod_gf(unsigned int a, unsigned int b) +{ + unsigned int R = 0; + unsigned int R1 = 0; + unsigned int k = 0; + + for (k = 0; k < mm; k++) { + + R = (R << 1) & 0x1FFE; + if (R1 == 1) + R ^= P; + + if (((a >> (POLY - k)) & 1) == 1) + R ^= b; + + if (k < POLY) + R1 = (R >> POLY) & 1; + } + return R; +} + +/** + * chien - CHIEN search + * + * @location - Error location vector pointer + * + * Inputs : ELP(z) + * No. of found errors + * Size of input codeword + * Outputs : Up to 8 locations + * No. of errors + */ +static int chien(unsigned int select_4_8, int err_nums, + unsigned int err[], unsigned int *location) +{ + int i, count; /* Number of dectected errors */ + /* Contains accumulation of evaluation at x^i (i:1->8) */ + unsigned int gammas[8]; + unsigned int alpha; + unsigned int bit, ecc_bits; + unsigned int elp_sum; + + ecc_bits = (select_4_8 == 0) ? 52 : 104; + + /* Start evaluation at Alpha**8192 and decreasing */ + for (i = 0; i < 8; i++) + gammas[i] = err[i]; + + count = 0; + for (i = 1; (i <= nn) && (count < err_nums); i++) { + + /* Result of evaluation at root */ + elp_sum = 1 ^ gammas[0] ^ gammas[1] ^ + gammas[2] ^ gammas[3] ^ + gammas[4] ^ gammas[5] ^ + gammas[6] ^ gammas[7]; + + alpha = PPP >> 1; + gammas[0] = mpy_mod_gf(gammas[0], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-2 */ + gammas[1] = mpy_mod_gf(gammas[1], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-2 */ + gammas[2] = mpy_mod_gf(gammas[2], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-3 */ + gammas[3] = mpy_mod_gf(gammas[3], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-4 */ + gammas[4] = mpy_mod_gf(gammas[4], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-5 */ + gammas[5] = mpy_mod_gf(gammas[5], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-6 */ + gammas[6] = mpy_mod_gf(gammas[6], alpha); + alpha = mpy_mod_gf(alpha, (PPP >> 1)); /* x alphha^-7 */ + gammas[7] = mpy_mod_gf(gammas[7], alpha); + + if (elp_sum == 0) { + /* calculate location */ + bit = ((i-1) & ~7)|(7-((i-1) & 7)); + location[count++] = kk_shorten - (bit - 2 * ecc_bits) - 1; + } + } + + /* Failure: No. of detected errors != No. or corrected errors */ + if (count != err_nums) { + count = -1; + /* printk(KERN_INFO "BCH decoding failed\n");*/ + } + /* + for (i = 0; i < count; i++) + printk(KERN_INFO "%d ", location[i]); + */ + return count; +} + +/* synd : 16 Syndromes + * return: gamaas - Coefficients to the error polynomial + * return: : Number of detected errors +*/ +static unsigned int berlekamp(unsigned int select_4_8, + unsigned int synd[], unsigned int err[]) +{ + int loop, iteration; + unsigned int LL = 0; /* Detected errors */ + unsigned int d = 0; /* Distance between Syndromes and ELP[n](z) */ + unsigned int invd = 0; /* Inverse of d */ + /* Intermediate ELP[n](z). + * Final ELP[n](z) is Error Location Polynomial + */ + unsigned int gammas[16]; + /* Intermediate normalized ELP[n](z) : D[n](z) */ + unsigned int D[16]; + /* Temporary value that holds an ELP[n](z) coefficient */ + unsigned int next_gamma = 0; + + int e = 0; + unsigned int sign = 0; + unsigned int u = 0; + unsigned int v = 0; + unsigned int C1 = 0, C2 = 0; + unsigned int ss = 0; + unsigned int tmp_v = 0, tmp_s = 0; + unsigned int tmp_poly; + + /*-------------- Step 0 ------------------*/ + for (loop = 0; loop < 16; loop++) { + gammas[loop] = 0; + D[loop] = 0; + } + + gammas[0] = 1; + D[1] = 1; + + iteration = 0; + LL = 0; + while ((iteration < ((select_4_8+1)*2*4)) && + (LL <= ((select_4_8+1)*4))) { + + /*printk(KERN_INFO "\nIteration.............%d\n", iteration);*/ + d = 0; + /* Step: 0 */ + for (loop = 0; loop <= LL; loop++) { + tmp_poly = mpy_mod_gf( + gammas[loop], synd[iteration - loop]); + d ^= tmp_poly; + /*printk(KERN_INFO "%02d. s=0 LL=%x poly %x\n", + loop, LL, tmp_poly);*/ + } + + /* Step 1: 1 cycle only to perform inversion */ + v = d << 1; + e = -1; + sign = 1; + ss = 0x2000; + invd = 0; + u = PPP; + for (loop = 0; (d != 0) && (loop <= (2 * POLY)); loop++) { + /*printk(KERN_INFO "%02d. s=1 LL=%x poly NULL\n", + loop, LL);*/ + C1 = (v >> 13) & 1; + C2 = C1 & sign; + + sign ^= C2 ^ (e == 0); + + tmp_v = v; + tmp_s = ss; + + if (C1 == 1) { + v ^= u; + ss ^= invd; + } + v = (v << 1) & 0x3FFF; + if (C2 == 1) { + u = tmp_v; + invd = tmp_s; + e = -e; + } + invd >>= 1; + e--; + } + + for (loop = 0; (d != 0) && (loop <= (iteration + 1)); loop++) { + /* Step 2 + * Interleaved with Step 3, if L<(n-k) + * invd: Update of ELP[n](z) = ELP[n-1](z) - d.D[n-1](z) + */ + + /* Holds value of ELP coefficient until precedent + * value does not have to be used anymore + */ + tmp_poly = mpy_mod_gf(d, D[loop]); + /*printk(KERN_INFO "%02d. s=2 LL=%x poly %x\n", + loop, LL, tmp_poly);*/ + + next_gamma = gammas[loop] ^ tmp_poly; + if ((2 * LL) < (iteration + 1)) { + /* Interleaving with Step 3 + * for parallelized update of ELP(z) and D(z) + */ + } else { + /* Update of ELP(z) only -> stay in Step 2 */ + gammas[loop] = next_gamma; + if (loop == (iteration + 1)) { + /* to step 4 */ + break; + } + } + + /* Step 3 + * Always interleaved with Step 2 (case when L<(n-k)) + * Update of D[n-1](z) = ELP[n-1](z)/d + */ + D[loop] = mpy_mod_gf(gammas[loop], invd); + /*printk(KERN_INFO "%02d. s=3 LL=%x poly %x\n", + loop, LL, D[loop]);*/ + + /* Can safely update ELP[n](z) */ + gammas[loop] = next_gamma; + + if (loop == (iteration + 1)) { + /* If update finished */ + LL = iteration - LL + 1; + /* to step 4 */ + break; + } + /* Else, interleaving to step 2*/ + } + + /* Step 4: Update D(z): i:0->L */ + /* Final update of D[n](z) = D[n](z).z*/ + for (loop = 0; loop < 15; loop++) /* Left Shift */ + D[15 - loop] = D[14 - loop]; + + D[0] = 0; + + iteration++; + } /* while */ + + /* Processing finished, copy ELP to final registers : 0->2t-1*/ + for (loop = 0; loop < 8; loop++) + err[loop] = gammas[loop+1]; + + /*printk(KERN_INFO "\n Err poly:"); + for (loop = 0; loop < 8; loop++) + printk(KERN_INFO "0x%x ", err[loop]); + */ + return LL; +} + +/* + * syndrome - Generate syndrome components from hw generate syndrome + * r(x) = c(x) + e(x) + * s(x) = c(x) mod g(x) + e(x) mod g(x) = e(x) mod g(x) + * so receiver checks if the syndrome s(x) = r(x) mod g(x) is equal to zero. + * unsigned int s[16]; - Syndromes + */ +static void syndrome(unsigned int select_4_8, + unsigned char *ecc, unsigned int syn[]) +{ + unsigned int k, l, t; + unsigned int alpha_bit, R_bit; + int ecc_pos, ecc_min; + + /* 2t-1 = 15 (for t=8) minimal polynomials of the first 15 powers of a + * primitive elemmants of GF(m); Even powers minimal polynomials are + * duplicate of odd powers' minimal polynomials. + * Odd powers of alpha (1 to 15) + */ + unsigned int pow_alpha[8] = {0x0002, 0x0008, 0x0020, 0x0080, + 0x0200, 0x0800, 0x001B, 0x006C}; + + /*printk(KERN_INFO "\n ECC[0..n]: "); + for (k = 0; k < 13; k++) + printk(KERN_INFO "0x%x ", ecc[k]); + */ + + if (select_4_8 == 0) { + t = 4; + ecc_pos = 55; /* bits(52-bits): 55->4 */ + ecc_min = 4; + } else { + t = 8; + ecc_pos = 103; /* bits: 103->0 */ + ecc_min = 0; + } + + /* total numbber of syndrom to be used is 2t */ + /* Step1: calculate the odd syndrome(s) */ + R_bit = ((ecc[ecc_pos/8] >> (7 - ecc_pos%8)) & 1); + ecc_pos--; + for (k = 0; k < t; k++) + syn[2 * k] = R_bit; + + while (ecc_pos >= ecc_min) { + R_bit = ((ecc[ecc_pos/8] >> (7 - ecc_pos%8)) & 1); + ecc_pos--; + + for (k = 0; k < t; k++) { + /* Accumulate value of x^i at alpha^(2k+1) */ + if (R_bit == 1) + syn[2*k] ^= pow_alpha[k]; + + /* Compute a**(2k+1), using LSFR */ + for (l = 0; l < (2 * k + 1); l++) { + alpha_bit = (pow_alpha[k] >> POLY) & 1; + pow_alpha[k] = (pow_alpha[k] << 1) & 0x1FFF; + if (alpha_bit == 1) + pow_alpha[k] ^= P; + } + } + } + + /* Step2: calculate the even syndrome(s) + * Compute S(a), where a is an even power of alpha + * Evenry even power of primitive element has the same minimal + * polynomial as some odd power of elemets. + * And based on S(a^2) = S^2(a) + */ + for (k = 0; k < t; k++) + syn[2*k+1] = mpy_mod_gf(syn[k], syn[k]); + + /*printk(KERN_INFO "\n Syndromes: "); + for (k = 0; k < 16; k++) + printk(KERN_INFO "0x%x ", syn[k]);*/ +} + +/** + * decode_bch - BCH decoder for 4- and 8-bit error correction + * + * @ecc - ECC syndrome generated by hw BCH engine + * @err_loc - pointer to error location array + * + * This function does post sydrome generation (hw generated) decoding + * for:- + * Dimension of Galoise Field: m = 13 + * Length of codeword: n = 2**m - 1 + * Number of errors that can be corrected: 4- or 8-bits + * Length of information bit: kk = nn - rr + */ +int decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc) +{ + int no_of_err, i; + unsigned int syn[16]; /* 16 Syndromes */ + unsigned int err_poly[8]; + /* Coefficients to the error polynomial + * ELP(x) = 1 + err0.x + err1.x^2 + ... + err7.x^8 + */ + + /* perform manual initialization to avoid memset */ + for (i=0; i<16; i++) { + syn[i] = 0; + if (i<8) + err_poly[i] = 0; + } + + /* Decoting involes three steps + * 1. Compute the syndrom from teh received codeword, + * 2. Find the error location polynomial from a set of equations + * derived from the syndrome, + * 3. Use the error location polynomial to identify errants bits, + * + * And correcttion done by bit flips using error locaiton and expected + * to be outseide of this implementation. + */ + syndrome(select_4_8, ecc, syn); + no_of_err = berlekamp(select_4_8, syn, err_poly); + if (no_of_err <= (4 << select_4_8)) + no_of_err = chien(select_4_8, no_of_err, err_poly, err_loc); + + return no_of_err; +} +EXPORT_SYMBOL(decode_bch);
diff --git a/x-loader/lib/printf.c b/x-loader/lib/printf.c new file mode 100644 index 0000000..91d22fc --- /dev/null +++ b/x-loader/lib/printf.c
@@ -0,0 +1,304 @@ +/* + * (C) Copyright 2004 Texas Instruments + * + * Based on the following file: + * linux/lib/vsprintf.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + */ + +#include <stdarg.h> +#include <common.h> + +#ifdef CFG_PRINTF + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +#define do_div(n,base) ({ \ +int __res; \ +__res = ((unsigned long) n) % (unsigned) base; \ +n = ((unsigned long) n) / (unsigned) base; \ +__res; }) + +static char * number(char * str, long num, int base, int size, int precision + ,int type) +{ + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + + +static int vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long num; + int i, base; + char * str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = "<NULL>"; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (short) num; + } else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +void serial_printf (const char *fmt, ...) +{ + va_list args; + uint i; + char printbuffer[CFG_PBSIZE]; + + va_start (args, fmt); + + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsprintf (printbuffer, fmt, args); + va_end (args); + + /* Print the string */ + serial_puts (printbuffer); +} +#endif
diff --git a/x-loader/lib/string.c b/x-loader/lib/string.c new file mode 100644 index 0000000..ebd8675 --- /dev/null +++ b/x-loader/lib/string.c
@@ -0,0 +1,49 @@ +/* + * linux/lib/string.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +/* + * stupid library routines.. The optimized versions should generally be found + * as inline code in <asm-xx/string.h> + * + * These are buggy as well.. + * + * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> + * - Added strsep() which will replace strtok() soon (because strsep() is + * reentrant and should be faster). Use only strsep() in new code, please. + */ + +#include <linux/types.h> +#include <linux/string.h> +#include <malloc.h> +#ifndef __HAVE_ARCH_MEMMOVE +/** + * memmove - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @count: The size of the area. + * + * Unlike memcpy(), memmove() copes with overlapping areas. + */ +void * memmove(void * dest,const void *src,size_t count) +{ + char *tmp, *s; + + if (dest <= src) { + tmp = (char *) dest; + s = (char *) src; + while (count--) + *tmp++ = *s++; + } + else { + tmp = (char *) dest + count; + s = (char *) src + count; + while (count--) + *--tmp = *--s; + } + + return dest; +} +#endif
diff --git a/x-loader/mkconfig b/x-loader/mkconfig new file mode 100755 index 0000000..0a5a68c --- /dev/null +++ b/x-loader/mkconfig
@@ -0,0 +1,138 @@ +#!/bin/sh -e + +# Script to create header files and links to configure +# X-Loader for a specific board. +# +# Parameters: Target Architecture CPU Board [VENDOR] [SOC] +# +# (C) 2004 Texas Instruments +# (C) 2002-2006 DENX Software Engineering, Wolfgang Denk <wd@denx.de> +# + +APPEND=no # Default: Create new config file +BOARD_NAME="" # Name to print in make output +TARGETS="" + +arch="" +cpu="" +board="" +vendor="" +soc="" + +if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then + # Automatic mode + line=`egrep -i "^[[:space:]]*${2}[[:space:]]" boards.cfg` || { + echo "make: *** No rule to make target \`$2_config'. Stop." >&2 + exit 1 + } + + set ${line} + # add default board name if needed + [ $# = 3 ] && set ${line} ${1} +fi + +while [ $# -gt 0 ] ; do + case "$1" in + --) shift ; break ;; + -a) shift ; APPEND=yes ;; + -n) shift ; BOARD_NAME="${1%_config}" ; shift ;; + -t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;; + *) break ;; + esac +done + +[ $# -lt 4 ] && exit 1 +[ $# -gt 6 ] && exit 1 + +CONFIG_NAME="${1%_config}" + +[ "${BOARD_NAME}" ] || BOARD_NAME="${CONFIG_NAME}" + +arch="$2" +cpu="$3" +if [ "$4" = "-" ] ; then + board=${BOARD_NAME} +else + board="$4" +fi +[ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5" +[ $# -gt 5 ] && [ "$6" != "-" ] && soc="$6" + +if [ "${ARCH}" -a "${ARCH}" != "${arch}" ]; then + echo "Failed: \$ARCH=${ARCH}, should be '${arch}' for ${BOARD_NAME}" 1>&2 + exit 1 +fi + +echo "Configuring for ${BOARD_NAME} board..." + +# +# Create link to architecture specific headers +# +if [ "$SRCTREE" != "$OBJTREE" ] ; then + mkdir -p ${OBJTREE}/include + mkdir -p ${OBJTREE}/include2 + cd ${OBJTREE}/include2 + rm -f asm + ln -s ${SRCTREE}/include/asm asm + LNPREFIX=${SRCTREE}/include/asm/ + cd ../include + rm -f asm + ln -s ${SRCTREE}/include/asm asm +else + cd ./include +fi + +rm -f asm/arch + +if [ -z "${soc}" ] ; then + ln -s ${LNPREFIX}arch-${cpu} asm/arch +else + ln -s ${LNPREFIX}arch-${soc} asm/arch +fi + +if [ "${arch}" = "arm" ] ; then + rm -f asm/proc + ln -s ${LNPREFIX}proc-armv asm/proc +fi + +# +# Create include file for Make +# +echo "ARCH = ${arch}" > config.mk +echo "CPU = ${cpu}" >> config.mk +echo "BOARD = ${board}" >> config.mk + +[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk + +[ "${soc}" ] && echo "SOC = ${soc}" >> config.mk + +# Assign board directory to BOARDIR variable +if [ -z "${vendor}" ] ; then + BOARDDIR=${board} +else + BOARDDIR=${vendor}/${board} +fi + +# +# Create board specific header file +# +if [ "$APPEND" = "yes" ] # Append to existing config file +then + echo >> config.h +else + > config.h # Create new config file +fi +echo "/* Automatically generated - do not edit */" >>config.h + +for i in ${TARGETS} ; do + echo "#define CONFIG_MK_${i} 1" >>config.h ; +done + +cat << EOF >> config.h +#define CONFIG_BOARDDIR board/$BOARDDIR +#include <config_defaults.h> +#include <configs/${CONFIG_NAME}.h> +#include <asm/config.h> +EOF + +exit 0
diff --git a/x-loader/rules.mk b/x-loader/rules.mk new file mode 100644 index 0000000..c1670ac --- /dev/null +++ b/x-loader/rules.mk
@@ -0,0 +1,44 @@ +# +# (C) Copyright 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 +# + +######################################################################### + +_depend: $(obj).depend + +$(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS) $(HOSTSRCS) + @rm -f $@ + @for f in $(SRCS); do \ + g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \ + $(CC) -M $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \ + done + @for f in $(HOSTSRCS); do \ + g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \ + $(HOSTCC) -M $(HOSTCPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \ + done + +$(HOSTOBJS): $(obj)%.o: %.c + $(HOSTCC) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) $(HOSTCFLAGS_$(BCURDIR)) -o $@ $< -c +$(NOPEDOBJS): $(obj)%.o: %.c + $(HOSTCC) $(HOSTCFLAGS_NOPED) $(HOSTCFLAGS_$(@F)) $(HOSTCFLAGS_$(BCURDIR)) -o $@ $< -c + +#########################################################################
diff --git a/x-loader/scripts/mkoneboot.sh b/x-loader/scripts/mkoneboot.sh new file mode 100644 index 0000000..f0862a5 --- /dev/null +++ b/x-loader/scripts/mkoneboot.sh
@@ -0,0 +1,16 @@ +#!/bin/sh + +IMAGE1=x-load.bin.ift +IMAGE2=x-load-signed.ift +TMP=oneloader +PAGESIZE=2048 + +size=`ls -la $IMAGE1 | awk -F' ' '{ printf $5}'` +let remain=$PAGESIZE-$size +dd if=/dev/zero of=$IMAGE2 bs=1 count=512 +#dd if=/dev/zero of=zerofile bs=$remain count=1 > /dev/null 2> /dev/null +cat $IMAGE1>>$IMAGE2 + +rm -f $IMAGE1 + +echo "Create $IMAGE2 completed..."
diff --git a/x-loader/tools/Makefile b/x-loader/tools/Makefile new file mode 100644 index 0000000..8e45b2b --- /dev/null +++ b/x-loader/tools/Makefile
@@ -0,0 +1,89 @@ +# +# (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 +# + +TOOLSUBDIRS = + +# +# toolchains targeting win32 generate .exe files +# +ifneq (,$(findstring WIN32 ,$(shell $(HOSTCC) -E -dM -xc /dev/null))) +SFX = .exe +else +SFX = +endif + +# +# Include this after HOSTOS HOSTARCH check +# so that we can act intelligently. +# +include $(TOPDIR)/config.mk + +# Generated executable files +BIN_FILES-y += signGP$(SFX) +OBJ_FILES-y += signGP.o + +# now $(obj) is defined +HOSTSRCS += $(addprefix $(SRCTREE)/tools/,$(OBJ_FILES-y:.o=.c)) +BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y))) +HOSTOBJS := $(addprefix $(obj),$(OBJ_FILES-y)) +NOPEDOBJS := $(addprefix $(obj),$(NOPED_OBJ_FILES-y)) + +# +# Use native tools and options +# Define __KERNEL_STRICT_NAMES to prevent typedef overlaps +# +HOSTCPPFLAGS = -idirafter $(SRCTREE)/include \ + -idirafter $(OBJTREE)/include2 \ + -idirafter $(OBJTREE)/include \ + -I $(SRCTREE)/lib/libfdt \ + -I $(SRCTREE)/tools \ + -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC \ + -D__KERNEL_STRICT_NAMES + + +all: $(obj).depend $(BINS) $(LOGO-y) subdirs + +$(obj)signGP$(SFX): $(obj)signGP.o + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^ + $(HOSTSTRIP) $@ + +subdirs: +ifeq ($(TOOLSUBDIRS),) + @: +else + @for dir in $(TOOLSUBDIRS) ; do \ + $(MAKE) \ + HOSTOS=$(HOSTOS) \ + HOSTARCH=$(HOSTARCH) \ + -C $$dir || exit 1 ; \ + done +endif + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +#########################################################################
diff --git a/x-loader/tools/setlocalversion b/x-loader/tools/setlocalversion new file mode 100755 index 0000000..e11f54f --- /dev/null +++ b/x-loader/tools/setlocalversion
@@ -0,0 +1,40 @@ +#!/bin/sh +# Print additional version information for non-release trees. + +usage() { + echo "Usage: $0 [srctree]" >&2 + exit 1 +} + +cd "${1:-.}" || usage + +# Check for git and a git repo. +if head=`git rev-parse --verify HEAD 2>/dev/null`; then + # Do we have an untagged version? + if git name-rev --tags HEAD | \ + grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then + (git describe || git describe --tags || git describe --all --long) \ + 2>/dev/null | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' + fi + + # Are there uncommitted changes? + git update-index --refresh --unmerged > /dev/null + if git diff-index --name-only HEAD | grep -v "^scripts/package" \ + | read dummy; then + printf '%s' -dirty + fi + + # Is this git on svn? + if git config --get svn-remote.svn.url >/dev/null; then + printf -- '-svn%s' "`git svn find-rev $head`" + fi +fi + +# Check for svn and a svn repo. +if rev=`svn info 2>/dev/null` ; then + rev=`echo "${rev}" | grep '^Revision' | awk '{print $NF}'` + printf -- '-svn%s' $rev +fi + +# Check for any localversion-* files +printf '%s' "`cat localversion-* 2>/dev/null`"
diff --git a/x-loader/tools/signGP.c b/x-loader/tools/signGP.c new file mode 100644 index 0000000..0e8ed07 --- /dev/null +++ b/x-loader/tools/signGP.c
@@ -0,0 +1,73 @@ +// +// signGP.c +// Read the x-load.bin file and write out the x-load.bin.ift file. +// The signed image is the original pre-pended with the size of the image +// and the load address. If not entered on command line, file name is +// assumed to be x-load.bin in current directory and load address is +// 0x40200800. + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <string.h> +#include <malloc.h> + + +main(int argc, char *argv[]) +{ + int i; + char ifname[FILENAME_MAX], ofname[FILENAME_MAX], ch; + FILE *ifile, *ofile; + unsigned long loadaddr, len; + struct stat sinfo; + + + // Default to x-load.bin and 0x40200800. + strcpy(ifname, "x-load.bin"); + loadaddr = 0x40200800; + + if ((argc == 2) || (argc == 3)) + strcpy(ifname, argv[1]); + + if (argc == 3) + loadaddr = strtol(argv[2], NULL, 16); + + // Form the output file name. + strcpy(ofname, ifname); + strcat(ofname, ".ift"); + + // Open the input file. + ifile = fopen(ifname, "rb"); + if (ifile == NULL) { + printf("Cannot open %s\n", ifname); + exit(0); + } + + // Get file length. + stat(ifname, &sinfo); + len = sinfo.st_size; + + // Open the output file and write it. + ofile = fopen(ofname, "wb"); + if (ofile == NULL) { + printf("Cannot open %s\n", ofname); + fclose(ifile); + exit(0); + } + + // Pad 1 sector of zeroes. + //ch = 0x00; + //for (i=0; i<0x200; i++) + // fwrite(&ch, 1, 1, ofile); + + fwrite(&len, 1, 4, ofile); + fwrite(&loadaddr, 1, 4, ofile); + for (i=0; i<len; i++) { + fread(&ch, 1, 1, ifile); + fwrite(&ch, 1, 1, ofile); + } + + fclose(ifile); + fclose(ofile); +}