Project import
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7c0c444 --- /dev/null +++ b/Makefile
@@ -0,0 +1,303 @@ +# +# Copyright (c) 2010-2011 Nest, 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 makefile for the Universal Bootloader, u-boot. +# + +.NOTPARALLEL: + +include pre.mak + +PackageRoot := . + +PackageSeparator := + +PackageVersion := +PackageSourceDir := $(UBootPackageName)$(PackageSeparator)$(PackageVersion) + +PackageBuildMakefile = $(call GenerateBuildPaths,include/config.mk) + +CleanPaths += $(PackageLicenseFile) + +CP = cp +DD = dd +LN = ln +TAR = tar +MKDIR = mkdir +CHMOD = chmod +PRINTF = printf +PUSHD = pushd +POPD = popd +FSL_HAB_SIGN = $(BuildRoot)/build/scripts/fsl_hab_sign.sh +FSL_CST = $(BuildRoot)/build/tools/host/i686-pc-linux-gnu/bin/freescale-cst + +# +# Build and result paths for staging targets +# + +UBootResultBinDir := $(call GenerateResultPaths,,bin) +UBootResultSbinDir := $(call GenerateResultPaths,,sbin) + +UBootPrintEnvBuildPath := $(call GenerateBuildPaths,tools/env/fw_printenv) +UBootPrintEnvResultPath := $(call GenerateResultPaths,,sbin/fw_printenv) + +UBootSetEnvResultPath := $(call GenerateResultPaths,,sbin/fw_setenv) + +UBootMkimageBuildPath := $(call GenerateBuildPaths,tools/mkimage) +UBootMkimageResultPath := $(call GenerateResultPaths,,bin/mkimage) + +UnsignedUBootBuildPath := $(call GenerateBuildPaths,$(UBootImageFile)) + +# +# If UBootSignedImageFile AND UBootSignedSDPImageFile are defined, we need to do +# an extra step and sign UBootImageFile to produce signed binaries. +# +# There are three different ways we can generate this signed binary: +# 1) Copy a signed image from within the Git repo* [ Default behavior if the appropriate signed image folder is present ] +# 2) Copy an unsigned image from the build folder* [ Fallback behavior if the appropriate signed image folder is not present (deleted or not yet present) ] +# 3) Sign it locally using the private keys [ Force this by passing 'SIGN_BOOTLOADER=true' on make cmdline ] +# +# *Also generates a signing .tgz archive in the u-boot results folder that can be unpacked on an offline +# signing workstation that has the necessary signing keys and used to sign the image. It contains: +# 1) The code signing binary: freescale-cst +# 2) The code signing helper script: fsl_hab_sign.sh +# 3) The unsigned u-boot image +# 4) A top-level signing script that defines the input and output filenames, for documentation purposes, and so that we are consistent. +# +ifneq "$(and $(UBootSignedImageFile),$(UBootSignedSDPImageFile))" "" +SignedUBootResultPath = $(call GenerateResultPaths,,$(UBootSignedImageFile)) +SignedSDPUBootResultPath= $(call GenerateResultPaths,,$(UBootSignedSDPImageFile)) +BuildResults = $(SignedUBootResultPath) $(SignedSDPUBootResultPath) + +# Generate a signing .tgz archive +UBootSigningArchiveResultPath = $(call GenerateResultPaths,,u-boot-unsigned-$(GeneratedBuildLabel).tgz) +define SIGNING_SCRIPT +#!/bin/bash +set -e + +# Check the input args +if [ $${#} -ne 2 ]; then + name=`basename $${0}` + echo "Usage: $${name} <password file> <key dir>" + exit 1 +elif [ ! -f $${1} ]; then + echo "Password file not found: $${1}" + exit 1 +elif [ ! -d $${2} ]; then + echo "Key dir not found: $${2}" + exit 1 +fi + +./$(notdir $(FSL_HAB_SIGN)) --passin $${1} --keypath $${2} $(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) $(basename $(UBootSignedImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootSignedImageFile)) +./$(notdir $(FSL_HAB_SIGN)) --sdp --passin $${1} --keypath $${2} $(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) $(basename $(UBootSignedImageFile))-sdp-$(GeneratedBuildLabel)$(suffix $(UBootSignedImageFile)) +echo "Done, no errors" + +endef +export SIGNING_SCRIPT +GenerateUBootSigningArchive = $(eval TMPDIR := $(shell mktemp -d)) \ + $(MKDIR) -p $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \ + $(CP) $(FSL_HAB_SIGN) $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \ + $(CP) $(FSL_CST) $(TMPDIR)/$(BuildProduct)/$(BuildConfig) && \ + $(CP) $(1) $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/$(basename $(UBootImageFile))-$(GeneratedBuildLabel)$(suffix $(UBootImageFile)) && \ + $(PRINTF) "$$SIGNING_SCRIPT" > $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/sign.sh && \ + $(CHMOD) u+x $(TMPDIR)/$(BuildProduct)/$(BuildConfig)/sign.sh && \ + $(PUSHD) $(TMPDIR) && sha256sum $(BuildProduct)/$(BuildConfig)/* > $(BuildProduct)/$(BuildConfig)/SHA256SUMS && $(POPD) && \ + $(TAR) -czf $(UBootSigningArchiveResultPath) --directory $(TMPDIR) $(BuildProduct) && \ + $(RM) -rf $(TMPDIR) + +ifdef SIGN_BOOTLOADER +# This is option (3) above +# This option also copies the signed result, places it into the signed u-boot images folder with a name that reflects the +# build label (tag, last commit hash, etc) and updates the symlinks to it so that it is ready to commit into the repo. +GenerateSignedResult = $(Echo) "Signing result \"$(call GenerateBuildRootEllipsedPath,$2)\" locally" && \ + $(FSL_HAB_SIGN) $(3) $(1) $(2) && \ + $(CP) $(2) $(UBootSignedImagesFolder)/$(basename $(notdir $(2)))$(GeneratedBuildLabel)$(suffix $(2)) && \ + $(LN) -fs $(basename $(notdir $(2)))$(GeneratedBuildLabel)$(suffix $(2)) $(UBootSignedImagesFolder)/$(notdir $(2)) +else ifneq ($(wildcard $(UBootSignedImagesFolder)),) +# This is option (1) above +GenerateSignedResult = $(Echo) "Copying signed result \"$(call GenerateBuildRootEllipsedPath,$2)\" from repo ($(UBootSignedImagesFolder)/$(notdir $(2)))" && \ + $(call GenerateUBootSigningArchive,$(1)) && \ + $(CP) $(UBootSignedImagesFolder)/$(notdir $(2)) $(2) +else +# This is option (2) above +# +# Note that setting CONFIG_SECURE_BOOT in the U-boot config causes a 'CSF 0x2000' command to be +# added to the mkimage config, which causes the CSF field in the the IVT header to be nonzero, +# and increases the length of the image given in the header by 0x2000 Bytes. If cases such as this, +# where we don't actually do the signing and append the CSF data, we need to zero the field and +# append 0x2000 Bytes of zeros, so that the boot ROM won't die trying to read it. +GenerateSignedResult = $(Echo) "Copying result \"$(call GenerateBuildRootEllipsedPath,$2)\" without signing" && \ + $(call GenerateUBootSigningArchive,$(1)) && \ + $(CP) $(1) $(2) && \ + $(DD) if=/dev/zero of=$(2) seek=24 bs=1 count=4 conv=notrunc > /dev/null 2>&1 && \ + $(DD) if=/dev/zero of=$(2) bs=$$((0x2000)) count=1 conv=notrunc oflag=append > /dev/null 2>&1 +endif + +else +UnsignedUBootResultPath = $(call GenerateResultPaths,,$(UBootImageFile)) +BuildResults = $(UnsignedUBootResultPath) +endif + +NestBuildDefines := NEST_BUILD_CONFIG_$(call ToUpper,$(BuildConfig)) NEST_BUILD_CONFIG=\\\"$(BuildConfig)\\\" +NestBuildDefineFlags := $(call ToolGenerateDefineArgument,$(NestBuildDefines)) + + +# The diamond1 and j49 u-boot builds require the HOSTCC and HOSTSTRIP flags to point to the cross-toolchain so that +# fw_printenv/fw_setenv will be built for the target arch. Doing this with the newer (2014.04) diamond3 and flintstone +# builds causes the host tools to be cross-compiled, and is unnecessary, which is more in line with what seems logical. +ifeq ($(UBootPackageName),u-boot) +toolHostCCFlags = HOSTCC="$(CC)" HOSTSTRIP=$(STRIP) +else +toolHostCCFlags = +endif + +SOURCEDIRS = $(PackageSourceDir) +$(PackageSourceDir)_RULE_TARGET = $(BuildDirectory)/configure + +all: $(PackageDefaultGoal) + +# Generate the package license contents. + +$(PackageSourceDir)/COPYING: source + +$(PackageLicenseFile): $(PackageSourceDir)/COPYING + $(copy-result) + +# We are building this package from version-controller source, so +# there is nothing to do for this target goal. + +$(PackageSourceDir): + +# Prepare the sources. + +.PHONY: source +$(BuildDirectory)/source: | $(PackageSourceDir) + $(Verbose)touch $@ + +# Patch the sources, if necessary. + +.PHONY: patch +$(BuildDirectory)/patch: $(BuildDirectory)/source + $(Verbose)touch $@ + +# U-Boot 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) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + O=$(CURDIR)/$(BuildDirectory) \ + $(UBootDefaultConfig) + $(Verbose)touch $@ + +# Build the source. + +$(BuildDirectory)/build: $(UnsignedUBootBuildPath) + $(Verbose)touch $@ + +$(UnsignedUBootBuildPath): $(BuildDirectory)/configure + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + O=$(CURDIR)/$(BuildDirectory) \ + NestBuildDefineFlags="$(NestBuildDefineFlags)" \ + all + +$(UBootPrintEnvBuildPath): $(BuildDirectory)/configure $(UnsignedUBootBuildPath) + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + O=$(CURDIR)/$(BuildDirectory) \ + $(toolHostCCFlags) \ + TOOLSUBDIRS=env \ + NestBuildDefineFlags="$(NestBuildDefineFlags)" \ + env tools + +# Stage the build to a temporary installation area. +# +# U-Boot 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. + +.PHONY: stage +stage: $(BuildDirectory)/stage + +$(BuildDirectory)/stage: $(BuildDirectory)/stage-target $(BuildDirectory)/stage-target-tools $(BuildDirectory)/stage-host-tools + $(Verbose)touch $@ + +$(BuildDirectory)/stage-target: $(BuildResults) + $(Verbose)$(CP) -f $(call GenerateBuildPaths,System.map) $(ResultDirectory) + $(Verbose)touch $@ + +$(BuildDirectory)/stage-target-tools: $(UBootPrintEnvResultPath) $(UBootSetEnvResultPath) + $(Verbose)touch $@ + +$(BuildDirectory)/stage-host-tools: $(UBootMkimageResultPath) + $(Verbose)touch $@ + +# +# Targets and commands for signing compiled images. +# Generates a regular signed image for NAND boot AND a special SDP one for USB DFU boot +# + +$(UnsignedUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory) + $(Verbose)$(CP) -f $< $@ + +$(SignedUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory) + $(Verbose)$(call GenerateSignedResult,$<,$@,) + +$(SignedSDPUBootResultPath): $(UnsignedUBootBuildPath) | $(ResultDirectory) + $(Verbose)$(call GenerateSignedResult,$<,$@,--sdp) + +# +# Targets and commands for staging target (i.e cross-compiled) tools. +# + +$(UBootResultSbinDir): + $(create-directory) + +$(UBootPrintEnvResultPath): $(UBootPrintEnvBuildPath) | $(UBootResultSbinDir) + $(copy-result) + +$(UBootSetEnvResultPath): $(UBootPrintEnvBuildPath) | $(UBootResultSbinDir) + $(Echo) "Creating \"$(call GenerateBuildRootEllipsedPath,$@)\"" + $(Verbose)ln -sf fw_printenv "$(@)" + +# +# Targets and commands for staging host (i.e. natively-compiled) tools +# that may be used elsewhere in the build. +# + +$(UBootResultBinDir): + $(create-directory) + +$(UBootMkimageBuildPath): $(BuildDirectory)/build + +$(UBootMkimageResultPath): $(UBootMkimageBuildPath) | $(UBootResultBinDir) + $(copy-result) + +clean: + $(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory) + $(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory) + +include post.mak
diff --git a/bin/diamond3/debug b/bin/diamond3/debug new file mode 120000 index 0000000..baec8fc --- /dev/null +++ b/bin/diamond3/debug
@@ -0,0 +1 @@ +development \ No newline at end of file
diff --git a/bin/diamond3/development/u-boot-4.5a22.hab b/bin/diamond3/development/u-boot-4.5a22.hab new file mode 100644 index 0000000..58350bb --- /dev/null +++ b/bin/diamond3/development/u-boot-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-4.5a22.imx b/bin/diamond3/development/u-boot-4.5a22.imx new file mode 100644 index 0000000..235804a --- /dev/null +++ b/bin/diamond3/development/u-boot-4.5a22.imx Binary files differ
diff --git a/bin/diamond3/development/u-boot-4.5d1-amb401-2.hab b/bin/diamond3/development/u-boot-4.5d1-amb401-2.hab new file mode 100644 index 0000000..ea4460b --- /dev/null +++ b/bin/diamond3/development/u-boot-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-4.5d1-amb401-2.imx b/bin/diamond3/development/u-boot-4.5d1-amb401-2.imx new file mode 100644 index 0000000..600fc07 --- /dev/null +++ b/bin/diamond3/development/u-boot-4.5d1-amb401-2.imx Binary files differ
diff --git a/bin/diamond3/development/u-boot-5.2d43.hab b/bin/diamond3/development/u-boot-5.2d43.hab new file mode 100644 index 0000000..14120df --- /dev/null +++ b/bin/diamond3/development/u-boot-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-5.2d43.imx b/bin/diamond3/development/u-boot-5.2d43.imx new file mode 100644 index 0000000..258f114 --- /dev/null +++ b/bin/diamond3/development/u-boot-5.2d43.imx Binary files differ
diff --git a/bin/diamond3/development/u-boot-sdp-4.5a22.hab b/bin/diamond3/development/u-boot-sdp-4.5a22.hab new file mode 100644 index 0000000..d183c8e --- /dev/null +++ b/bin/diamond3/development/u-boot-sdp-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-sdp-4.5d1-amb401-2.hab b/bin/diamond3/development/u-boot-sdp-4.5d1-amb401-2.hab new file mode 100644 index 0000000..a4e8404 --- /dev/null +++ b/bin/diamond3/development/u-boot-sdp-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-sdp-5.2d43.hab b/bin/diamond3/development/u-boot-sdp-5.2d43.hab new file mode 100644 index 0000000..4d76960 --- /dev/null +++ b/bin/diamond3/development/u-boot-sdp-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/development/u-boot-sdp.hab b/bin/diamond3/development/u-boot-sdp.hab new file mode 120000 index 0000000..a3cf33c --- /dev/null +++ b/bin/diamond3/development/u-boot-sdp.hab
@@ -0,0 +1 @@ +u-boot-sdp-5.2d43.hab \ No newline at end of file
diff --git a/bin/diamond3/development/u-boot.hab b/bin/diamond3/development/u-boot.hab new file mode 120000 index 0000000..da84890 --- /dev/null +++ b/bin/diamond3/development/u-boot.hab
@@ -0,0 +1 @@ +u-boot-5.2d43.hab \ No newline at end of file
diff --git a/bin/diamond3/diagnostics/u-boot-4.5a22.hab b/bin/diamond3/diagnostics/u-boot-4.5a22.hab new file mode 100644 index 0000000..befc3ad --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-4.5a22.imx b/bin/diamond3/diagnostics/u-boot-4.5a22.imx new file mode 100644 index 0000000..5230021 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-4.5a22.imx Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.hab b/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.hab new file mode 100644 index 0000000..2622cce --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.imx b/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.imx new file mode 100644 index 0000000..7cd73d3 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-4.5d1-amb401-2.imx Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-5.2d43.hab b/bin/diamond3/diagnostics/u-boot-5.2d43.hab new file mode 100644 index 0000000..80c3550 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-5.2d43.imx b/bin/diamond3/diagnostics/u-boot-5.2d43.imx new file mode 100644 index 0000000..2c8b49d --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-5.2d43.imx Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-sdp-4.5a22.hab b/bin/diamond3/diagnostics/u-boot-sdp-4.5a22.hab new file mode 100644 index 0000000..4dc63a1 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-sdp-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-sdp-4.5d1-amb401-2.hab b/bin/diamond3/diagnostics/u-boot-sdp-4.5d1-amb401-2.hab new file mode 100644 index 0000000..ce02213 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-sdp-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-sdp-5.2d43.hab b/bin/diamond3/diagnostics/u-boot-sdp-5.2d43.hab new file mode 100644 index 0000000..bf6101d --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-sdp-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/diagnostics/u-boot-sdp.hab b/bin/diamond3/diagnostics/u-boot-sdp.hab new file mode 120000 index 0000000..a3cf33c --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot-sdp.hab
@@ -0,0 +1 @@ +u-boot-sdp-5.2d43.hab \ No newline at end of file
diff --git a/bin/diamond3/diagnostics/u-boot.hab b/bin/diamond3/diagnostics/u-boot.hab new file mode 120000 index 0000000..da84890 --- /dev/null +++ b/bin/diamond3/diagnostics/u-boot.hab
@@ -0,0 +1 @@ +u-boot-5.2d43.hab \ No newline at end of file
diff --git a/bin/diamond3/release/u-boot-4.5a14.hab b/bin/diamond3/release/u-boot-4.5a14.hab new file mode 100644 index 0000000..cd260c0 --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5a14.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-4.5a14.imx b/bin/diamond3/release/u-boot-4.5a14.imx new file mode 100644 index 0000000..114a316 --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5a14.imx Binary files differ
diff --git a/bin/diamond3/release/u-boot-4.5a22.hab b/bin/diamond3/release/u-boot-4.5a22.hab new file mode 100644 index 0000000..b22eecc --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-4.5a22.imx b/bin/diamond3/release/u-boot-4.5a22.imx new file mode 100644 index 0000000..1791a1b --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5a22.imx Binary files differ
diff --git a/bin/diamond3/release/u-boot-4.5d1-amb401-2.hab b/bin/diamond3/release/u-boot-4.5d1-amb401-2.hab new file mode 100644 index 0000000..960be38 --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-4.5d1-amb401-2.imx b/bin/diamond3/release/u-boot-4.5d1-amb401-2.imx new file mode 100644 index 0000000..7ba0b36 --- /dev/null +++ b/bin/diamond3/release/u-boot-4.5d1-amb401-2.imx Binary files differ
diff --git a/bin/diamond3/release/u-boot-5.2d43.hab b/bin/diamond3/release/u-boot-5.2d43.hab new file mode 100644 index 0000000..3c6ce90 --- /dev/null +++ b/bin/diamond3/release/u-boot-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-5.2d43.imx b/bin/diamond3/release/u-boot-5.2d43.imx new file mode 100644 index 0000000..95176db --- /dev/null +++ b/bin/diamond3/release/u-boot-5.2d43.imx Binary files differ
diff --git a/bin/diamond3/release/u-boot-sdp-4.5a14.hab b/bin/diamond3/release/u-boot-sdp-4.5a14.hab new file mode 100644 index 0000000..4b9c689 --- /dev/null +++ b/bin/diamond3/release/u-boot-sdp-4.5a14.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-sdp-4.5a22.hab b/bin/diamond3/release/u-boot-sdp-4.5a22.hab new file mode 100644 index 0000000..488a91b --- /dev/null +++ b/bin/diamond3/release/u-boot-sdp-4.5a22.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-sdp-4.5d1-amb401-2.hab b/bin/diamond3/release/u-boot-sdp-4.5d1-amb401-2.hab new file mode 100644 index 0000000..514a759 --- /dev/null +++ b/bin/diamond3/release/u-boot-sdp-4.5d1-amb401-2.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-sdp-5.2d43.hab b/bin/diamond3/release/u-boot-sdp-5.2d43.hab new file mode 100644 index 0000000..2ad7edd --- /dev/null +++ b/bin/diamond3/release/u-boot-sdp-5.2d43.hab Binary files differ
diff --git a/bin/diamond3/release/u-boot-sdp.hab b/bin/diamond3/release/u-boot-sdp.hab new file mode 120000 index 0000000..a3cf33c --- /dev/null +++ b/bin/diamond3/release/u-boot-sdp.hab
@@ -0,0 +1 @@ +u-boot-sdp-5.2d43.hab \ No newline at end of file
diff --git a/bin/diamond3/release/u-boot.hab b/bin/diamond3/release/u-boot.hab new file mode 120000 index 0000000..da84890 --- /dev/null +++ b/bin/diamond3/release/u-boot.hab
@@ -0,0 +1 @@ +u-boot-5.2d43.hab \ No newline at end of file
diff --git a/u-boot-imx/.checkpatch.conf b/u-boot-imx/.checkpatch.conf new file mode 100644 index 0000000..35167e1 --- /dev/null +++ b/u-boot-imx/.checkpatch.conf
@@ -0,0 +1,23 @@ +# Not Linux, so don't expect a Linux tree. +--no-tree + +# Temporary for false positive in checkpatch +--ignore COMPLEX_MACRO + +# For CONFIG_SYS_I2C_NOPROBES +--ignore MULTISTATEMENT_MACRO_USE_DO_WHILE + +# For simple_strtoul +--ignore CONSIDER_KSTRTO + +# For min/max +--ignore MINMAX + +# enable more tests +--strict + +# Not Linux, so we don't recommend usleep_range() over udelay() +--ignore USLEEP_RANGE + +# Ignore networking block comment style +--ignore NETWORKING_BLOCK_COMMENT_STYLE
diff --git a/u-boot-imx/.mailmap b/u-boot-imx/.mailmap new file mode 100644 index 0000000..e1c6663 --- /dev/null +++ b/u-boot-imx/.mailmap
@@ -0,0 +1,27 @@ +# +# This list is used by git-shortlog to fix a few botched name translations +# in the git archive, either because the author's full name was messed up +# and/or not always written the same way, making contributions from the +# same person appearing not to be so or badly displayed. +# +# This file can be modified by hand or updated by the following command: +# scripts/mailmapper > tmp; mv tmp .mailmap +# + +Allen Martin <amartin@nvidia.com> +Andreas Bießmann <andreas.devel@googlemail.com> +Aneesh V <aneesh@ti.com> +Dirk Behme <dirk.behme@googlemail.com> +Fabio Estevam <fabio.estevam@freescale.com> +Jagannadha Sutradharudu Teki <402jagan@gmail.com> +Markus Klotzbuecher <mk@denx.de> +Prabhakar Kushwaha <prabhakar@freescale.com> +Rajeshwari Shinde <rajeshwari.s@samsung.com> +Sandeep Paulraj <s-paulraj@ti.com> +Shaohui Xie <Shaohui.Xie@freescale.com> +Stefan Roese <stroese> +Stefano Babic <sbabic@denx.de> +TsiChung Liew <Tsi-Chung.Liew@freescale.com> +Wolfgang Denk <wdenk> +York Sun <yorksun@freescale.com> +Ćukasz Majewski <l.majewski@samsung.com>
diff --git a/u-boot-imx/.travis.yml b/u-boot-imx/.travis.yml new file mode 100644 index 0000000..4e20e09 --- /dev/null +++ b/u-boot-imx/.travis.yml
@@ -0,0 +1,220 @@ +# Copyright Roger Meier <r.meier@siemens.com> +# SPDX-License-Identifier: GPL-2.0+ + +# build U-Boot on Travis CI - https://travis-ci.org/ + +language: c + +cache: + - apt + +install: + # install U-Boot build dependencies + - sudo apt-get install -qq cppcheck sloccount sparse bc libsdl-dev build-essential + # install latest device tree compiler + - git clone --depth=1 https://git.kernel.org/pub/scm/utils/dtc/dtc.git /tmp/dtc + - make -j4 -C /tmp/dtc + # prepare buildman environment + - export BUILDMAN_ROOT="root:" + - export BUILDMAN_MIPS="mips:" + - export BUILDMAN_PPC="ppc:" + - export BUILDMAN_ARM="arm:" + - export BUILDMAN_SANDBOX="sandbox:" + - echo -e "[toolchain]\n${BUILDMAN_ROOT} /\n" > ~/.buildman + - echo -e "${BUILDMAN_MIPS} /opt/eldk-5.4/mips/sysroots/i686-eldk-linux/usr/bin/mips32-linux/\n" >> ~/.buildman + - echo -e "${BUILDMAN_PPC} /opt/eldk-5.4/powerpc/sysroots/i686-eldk-linux/usr/bin/powerpc-linux/\n" >> ~/.buildman + - echo -e "${BUILDMAN_ARM} /opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/\n" >> ~/.buildman + - echo -e "${BUILDMAN_SANDBOX} /usr/bin/gcc\n" >> ~/.buildman + - export BUILDMAN_ALIAS="x86:" + - export BUILDMAN_ALIAS_ARM="arm:" + - echo -e "\n\n[toolchain-alias]\n${BUILDMAN_ALIAS} i386\n" >> ~/.buildman + - echo -e "${BUILDMAN_ALIAS_ARM} armv5te\n" >> ~/.buildman + - cat ~/.buildman + +env: + global: + - PATH=/tmp/dtc:$PATH + - BUILD_DIR=build + - CROSS_COMPILE="" + - HOSTCC="cc" + - HOSTCXX="c++" + - TEST_CONFIG_CMD="" + +before_script: + # install toolchains based on INSTALL_TOOLCHAIN} variable + - if [[ "${INSTALL_TOOLCHAIN}" == *arm* ]]; then wget ftp://ftp.denx.de/pub/eldk/5.4/targets/armv5te/eldk-eglibc-i686-arm-toolchain-gmae-5.4.sh ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *arm* ]]; then sh eldk-eglibc-i686-arm-toolchain-gmae-5.4.sh -y ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *arm* ]]; then ls -al /opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *avr32* ]]; then ./tools/buildman/buildman --fetch-arch avr32 ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *i386* ]]; then ./tools/buildman/buildman sandbox --fetch-arch i386 ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *m68k* ]]; then ./tools/buildman/buildman --fetch-arch m68k ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *mips* ]]; then wget ftp://ftp.denx.de/pub/eldk/5.4/targets/mips/eldk-eglibc-i686-mips-toolchain-gmae-5.4.sh ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *mips* ]]; then sh eldk-eglibc-i686-mips-toolchain-gmae-5.4.sh -y ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *ppc* ]]; then wget ftp://ftp.denx.de/pub/eldk/5.4/targets/powerpc/eldk-eglibc-i686-powerpc-toolchain-gmae-5.4.sh ; fi + - if [[ "${INSTALL_TOOLCHAIN}" == *ppc* ]]; then sh eldk-eglibc-i686-powerpc-toolchain-gmae-5.4.sh -y ; fi + +script: + # the execution sequence for each test + - echo ${TEST_CONFIG_CMD} + - ${TEST_CONFIG_CMD} + - echo ${TEST_CMD} + - ${TEST_CMD} + +matrix: + include: + # we need to build by vendor due to 50min time limit for builds + # each env setting here is a dedicated build + - env: + - TEST_CMD="./MAKEALL -a arm -v atmel" + INSTALL_TOOLCHAIN="arm" + CROSS_COMPILE="/opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/arm-linux-gnueabi-" + - env: + - TEST_CMD="./MAKEALL -a arm -v denx" + INSTALL_TOOLCHAIN="arm" + CROSS_COMPILE="/opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/arm-linux-gnueabi-" + - env: + - TEST_CMD="./MAKEALL -a arm -v freescale" + INSTALL_TOOLCHAIN="arm" + CROSS_COMPILE="/opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/arm-linux-gnueabi-" + - env: + - TEST_CMD="./MAKEALL -a arm -v siemens" + INSTALL_TOOLCHAIN="arm" + CROSS_COMPILE="/opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/arm-linux-gnueabi-" + - env: + - TEST_CMD="./MAKEALL -a arm -v ti" + INSTALL_TOOLCHAIN="arm" + CROSS_COMPILE="/opt/eldk-5.4/armv5te/sysroots/i686-eldk-linux/usr/bin/armv5te-linux-gnueabi/arm-linux-gnueabi-" + - env: + - TEST_CONFIG_CMD="make sandbox_defconfig" + TEST_CMD="make -j4" + HOSTCC = "gcc" + HOSTCXX = "g++" + - env: + - TEST_CONFIG_CMD="make sandbox_defconfig" + TEST_CMD="make -j4" + HOSTCC = "clang" + HOSTCXX = "clang++" + - env: + - TEST_CMD="./MAKEALL -a mips" + INSTALL_TOOLCHAIN="mips" + CROSS_COMPILE="/opt/eldk-5.4/mips/sysroots/i686-eldk-linux/usr/bin/mips32-linux/mips-linux-" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards arm1136" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards arm1176" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards arm720t" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards arm920t" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards atmel -x avr32" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards avr32" + INSTALL_TOOLCHAIN="avr32" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards davinci" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards denx" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards freescale -x powerpc,m68k,aarch64" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards freescale -x arm,m68k,aarch64" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards sandbox x86" + INSTALL_TOOLCHAIN="i386" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards kirkwood" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards m68k" + INSTALL_TOOLCHAIN="m68k" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mips" + INSTALL_TOOLCHAIN="mips" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc512x" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc5xx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc5xxx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc8260" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc83xx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc85xx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc86xx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman mpc8xx" + INSTALL_TOOLCHAIN="ppc" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards siemens" + INSTALL_TOOLCHAIN="arm" + - env: + - TEST_CONFIG_CMD="tools/buildman/buildman --list-tool-chains" + TEST_CMD="tools/buildman/buildman --list-error-boards ti" + INSTALL_TOOLCHAIN="arm" + + # QA jobs for code analytics + # static code analysis with cppcheck (we can add --enable=all later) + - env: + - TEST_CMD="cppcheck --force --quiet --inline-suppr ." + # search for TODO within source tree + - env: + - TEST_CMD="grep -r TODO ." + # search for FIXME within source tree + - env: + - TEST_CMD="grep -r FIXME ." + # search for HACK within source tree and ignore HACKKIT board + - env: + - TEST_CMD="grep -r HACK . | grep -v HACKKIT" + script: + - grep -r HACK . | grep -v HACKKIT + # some statistics about the code base + - env: + - TEST_CMD="sloccount ." + +notifications: + email: false + +# TODO make it perfect ;-r
diff --git a/u-boot-imx/Kbuild b/u-boot-imx/Kbuild new file mode 100644 index 0000000..465b930 --- /dev/null +++ b/u-boot-imx/Kbuild
@@ -0,0 +1,69 @@ +# +# Kbuild for top-level directory of U-Boot +# This file takes care of the following: +# 1) Generate generic-asm-offsets.h +# 2) Generate asm-offsets.h + +# Default sed regexp - multiline due to syntax constraints +define sed-y + "s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:; \ + /^->/{s:->#\(.*\):/* \1 */:; \ + s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:->::; p;}" +endef + +# Use filechk to avoid rebuilds when a header changes, but the resulting file +# does not +define filechk_offsets + (set -e; \ + echo "#ifndef $2"; \ + echo "#define $2"; \ + echo "/*"; \ + echo " * DO NOT MODIFY."; \ + echo " *"; \ + echo " * This file was generated by Kbuild"; \ + echo " */"; \ + echo ""; \ + sed -ne $(sed-y); \ + echo ""; \ + echo "#endif" ) +endef + +##### +# 1) Generate generic-asm-offsets.h + +generic-offsets-file := include/generated/generic-asm-offsets.h + +always := $(generic-offsets-file) +targets := $(generic-offsets-file) lib/asm-offsets.s + +# We use internal kbuild rules to avoid the "is up to date" message from make +lib/asm-offsets.s: lib/asm-offsets.c FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,cc_s_c) + +$(obj)/$(generic-offsets-file): lib/asm-offsets.s FORCE + $(call filechk,offsets,__GENERIC_ASM_OFFSETS_H__) + +##### +# 2) Generate asm-offsets.h +# + +ifneq ($(wildcard $(srctree)/arch/$(ARCH)/lib/asm-offsets.c),) +offsets-file := include/generated/asm-offsets.h +endif + +always += $(offsets-file) +targets += $(offsets-file) +targets += arch/$(ARCH)/lib/asm-offsets.s + +CFLAGS_asm-offsets.o := -DDO_DEPS_ONLY + +# We use internal kbuild rules to avoid the "is up to date" message from make +arch/$(ARCH)/lib/asm-offsets.s: arch/$(ARCH)/lib/asm-offsets.c FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,cc_s_c) + +$(obj)/$(offsets-file): arch/$(ARCH)/lib/asm-offsets.s FORCE + $(call filechk,offsets,__ASM_OFFSETS_H__)
diff --git a/u-boot-imx/Kconfig b/u-boot-imx/Kconfig new file mode 100644 index 0000000..41d4784 --- /dev/null +++ b/u-boot-imx/Kconfig
@@ -0,0 +1,206 @@ +# +# For a description of the syntax of this configuration file, +# see Documentation/kbuild/kconfig-language.txt. +# +mainmenu "U-Boot $UBOOTVERSION Configuration" + +config UBOOTVERSION + string + option env="UBOOTVERSION" + +# Allow defaults in arch-specific code to override any given here +source "arch/Kconfig" + +menu "General setup" + +config LOCALVERSION + string "Local version - append to U-Boot release" + help + Append an extra string to the end of your U-Boot version. + This will show up on your boot log, for example. + The string you set here will be appended after the contents of + any files with a filename matching localversion* in your + object and source tree, in that order. Your total string can + be a maximum of 64 characters. + +config LOCALVERSION_AUTO + bool "Automatically append version information to the version string" + default y + help + This will try to automatically determine if the current tree is a + release tree by looking for git tags that belong to the current + top of tree revision. + + A string of the format -gxxxxxxxx will be added to the localversion + if a git-based tree is found. The string generated by this will be + appended after any matching localversion* files, and after the value + set in CONFIG_LOCALVERSION. + + (The actual string used here is the first eight characters produced + by running the command: + + $ git rev-parse --verify HEAD + + which is done within the script "scripts/setlocalversion".) + +config CC_OPTIMIZE_FOR_SIZE + bool "Optimize for size" + default y + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller U-Boot image. + + This option is enabled by default for U-Boot. + +config SYS_MALLOC_F + bool "Enable malloc() pool before relocation" + default y if DM + help + Before relocation memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + +config SYS_MALLOC_F_LEN + hex "Size of malloc() pool before relocation" + depends on SYS_MALLOC_F + default 0x400 + help + Before relocation memory is very limited on many platforms. Still, + we can provide a small malloc() pool if needed. Driver model in + particular needs this to operate, so that it can allocate the + initial serial device and any others that are needed. + +menuconfig EXPERT + bool "Configure standard U-Boot features (expert users)" + default y + help + This option allows certain base U-Boot options and settings + to be disabled or tweaked. This is for specialized + environments which can tolerate a "non-standard" U-Boot. + Only use this if you really know what you are doing. + +if EXPERT + config SYS_MALLOC_CLEAR_ON_INIT + bool "Init with zeros the memory reserved for malloc (slow)" + default y + help + This setting is enabled by default. The reserved malloc + memory is initialized with zeros, so first malloc calls + will return the pointer to the zeroed memory. But this + slows the boot time. + + It is recommended to disable it, when CONFIG_SYS_MALLOC_LEN + value, has more than few MiB, e.g. when uses bzip2 or bmp logo. + Then the boot time can be significantly reduced. + Warning: + When disabling this, please check if malloc calls, maybe + should be replaced by calloc - if expects zeroed memory. +endif +endmenu # General setup + +menu "Boot images" + +config SUPPORT_SPL + bool + +config SUPPORT_TPL + bool + +config SPL + bool + depends on SUPPORT_SPL + prompt "Enable SPL" + help + If you want to build SPL as well as the normal image, say Y. + +config SPL_STACK_R + depends on SPL + bool "Enable SDRAM location for SPL stack" + help + SPL starts off execution in SRAM and thus typically has only a small + stack available. Since SPL sets up DRAM while in its board_init_f() + function, it is possible for the stack to move there before + board_init_r() is reached. This option enables a special SDRAM + location for the SPL stack. U-Boot SPL switches to this after + board_init_f() completes, and before board_init_r() starts. + +config SPL_STACK_R_ADDR + depends on SPL_STACK_R + hex "SDRAM location for SPL stack" + help + Specify the address in SDRAM for the SPL stack. This will be set up + before board_init_r() is called. + +config TPL + bool + depends on SPL && SUPPORT_TPL + prompt "Enable TPL" + help + If you want to build TPL as well as the normal image and SPL, say Y. + +config FIT + bool "Support Flattened Image Tree" + help + This option allows to boot the new uImage structrure, + Flattened Image Tree. FIT is formally a FDT, which can include + images of various types (kernel, FDT blob, ramdisk, etc.) + in a single blob. To boot this new uImage structure, + pass the the address of the blob to the "bootm" command. + +config FIT_VERBOSE + bool "Display verbose messages on FIT boot" + depends on FIT + +config FIT_SIGNATURE + bool "Enable signature verification of FIT uImages" + depends on FIT + depends on DM + select RSA + help + This option enables signature verification of FIT uImages, + using a hash signed and verified using RSA. If + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive + hashing is available using hardware, RSA library will use it. + See doc/uImage.FIT/signature.txt for more details. + +config SYS_EXTRA_OPTIONS + string "Extra Options (DEPRECATED)" + help + The old configuration infrastructure (= mkconfig + boards.cfg) + provided the extra options field. If you have something like + "HAS_BAR,BAZ=64", the optional options + #define CONFIG_HAS + #define CONFIG_BAZ 64 + will be defined in include/config.h. + This option was prepared for the smooth migration from the old + configuration to Kconfig. Since this option will be removed sometime, + new boards should not use this option. + +config SYS_TEXT_BASE + depends on SPARC || ARC + hex "Text Base" + help + TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture + +config SYS_CLK_FREQ + depends on ARC || ARCH_SUNXI + int "CPU clock frequency" + help + TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture + +endmenu # Boot images + +source "common/Kconfig" + +source "dts/Kconfig" + +source "net/Kconfig" + +source "drivers/Kconfig" + +source "fs/Kconfig" + +source "lib/Kconfig" + +source "test/Kconfig"
diff --git a/u-boot-imx/Licenses/Exceptions b/u-boot-imx/Licenses/Exceptions new file mode 100644 index 0000000..c9b3cd9 --- /dev/null +++ b/u-boot-imx/Licenses/Exceptions
@@ -0,0 +1,15 @@ + +GPL License Exception: + +Even though U-Boot in general is covered by the GPL-2.0/GPL-2.0+, +this does *not* cover the so-called "standalone" applications that +use U-Boot services by means of the jump table provided by U-Boot +exactly for this purpose - this is merely considered normal use of +U-Boot, and does *not* fall under the heading of "derived work". + + The header files "include/image.h" and "arch/*/include/asm/u-boot.h" +define interfaces to U-Boot. Including these (unmodified) header +files in another file is considered normal use of U-Boot, and does +*not* fall under the heading of "derived work". +-- Wolfgang Denk +
diff --git a/u-boot-imx/Licenses/README b/u-boot-imx/Licenses/README new file mode 100644 index 0000000..fe6dadc --- /dev/null +++ b/u-boot-imx/Licenses/README
@@ -0,0 +1,69 @@ + U-Boot is Free Software. It is copyrighted by Wolfgang Denk and +many others who contributed code (see the actual source code and the +git commit messages for details). You can redistribute U-Boot and/or +modify it under the terms of version 2 of the GNU General Public +License as published by the Free Software Foundation. Most of it can +also be distributed, at your option, under any later version of the +GNU General Public License -- see individual files for exceptions. + + NOTE! This license does *not* cover the so-called "standalone" +applications that use U-Boot services by means of the jump table +provided by U-Boot exactly for this purpose - this is merely +considered normal use of U-Boot, and does *not* fall under the +heading of "derived work" -- see file Licenses/Exceptions for +details. + + Also note that the GPL and the other licenses are copyrighted by +the Free Software Foundation and other organizations, but the +instance of code that they refer to (the U-Boot source code) is +copyrighted by me and others who actually wrote it. +-- Wolfgang Denk + + +Like many other projects, U-Boot has a tradition of including big +blocks of License headers in all files. This not only blows up the +source code with mostly redundant information, but also makes it very +difficult to generate License Clearing Reports. An additional problem +is that even the same licenses are referred to by a number of +slightly varying text blocks (full, abbreviated, different +indentation, line wrapping and/or white space, with obsolete address +information, ...) which makes automatic processing a nightmare. + +To make this easier, such license headers in the source files will be +replaced with a single line reference to Unique License Identifiers +as defined by the Linux Foundation's SPDX project [1]. For example, +in a source file the full "GPL v2.0 or later" header text will be +replaced by a single line: + + SPDX-License-Identifier: GPL-2.0+ + +Ideally, the license terms of all files in the source tree should be +defined by such License Identifiers; in no case a file can contain +more than one such License Identifier list. + +If a "SPDX-License-Identifier:" line references more than one Unique +License Identifier, then this means that the respective file can be +used under the terms of either of these licenses, i. e. with + + SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + +you can chose between GPL-2.0+ and BSD-3-Clause licensing. + +We use the SPDX Unique License Identifiers here; these are available +at [2]. + +[1] http://spdx.org/ +[2] http://spdx.org/licenses/ + +Full name SPDX Identifier OSI Approved File name URI +======================================================================================================================================= +GNU General Public License v2.0 only GPL-2.0 Y gpl-2.0.txt http://www.gnu.org/licenses/gpl-2.0.txt +GNU General Public License v2.0 or later GPL-2.0+ Y gpl-2.0.txt http://www.gnu.org/licenses/gpl-2.0.txt +GNU Library General Public License v2 or later LGPL-2.0+ Y lgpl-2.0.txt http://www.gnu.org/licenses/old-licenses/lgpl-2.0.txt +GNU Lesser General Public License v2.1 or later LGPL-2.1+ Y lgpl-2.1.txt http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt +eCos license version 2.0 eCos-2.0 eCos-2.0.txt http://www.gnu.org/licenses/ecos-license.html +BSD 2-Clause License BSD-2-Clause Y bsd-2-clause.txt http://spdx.org/licenses/BSD-2-Clause +BSD 3-clause "New" or "Revised" License BSD-3-Clause Y bsd-3-clause.txt http://spdx.org/licenses/BSD-3-Clause#licenseText +IBM PIBS (PowerPC Initialization and IBM-pibs ibm-pibs.txt + Boot Software) license +ISC License ISC Y isc.txt https://spdx.org/licenses/ISC
diff --git a/u-boot-imx/Licenses/bsd-2-clause.txt b/u-boot-imx/Licenses/bsd-2-clause.txt new file mode 100644 index 0000000..af69764 --- /dev/null +++ b/u-boot-imx/Licenses/bsd-2-clause.txt
@@ -0,0 +1,25 @@ +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following +conditions are met: + +1. Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. +2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "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 COPYRIGHT OWNER OR +CONTRIBUTORS 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.
diff --git a/u-boot-imx/Licenses/bsd-3-clause.txt b/u-boot-imx/Licenses/bsd-3-clause.txt new file mode 100644 index 0000000..aac5e2a --- /dev/null +++ b/u-boot-imx/Licenses/bsd-3-clause.txt
@@ -0,0 +1,24 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer, + without modification. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The names of the above-listed copyright holders may not be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR +CONTRIBUTORS 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.
diff --git a/u-boot-imx/Licenses/eCos-2.0.txt b/u-boot-imx/Licenses/eCos-2.0.txt new file mode 100644 index 0000000..8a12e20 --- /dev/null +++ b/u-boot-imx/Licenses/eCos-2.0.txt
@@ -0,0 +1,43 @@ + Note that this license is not endorsed by the Free Software Foundation. + It is available here as a convenience to readers of [1]the license + list. + +The eCos license version 2.0 + + This file is part of eCos, the Embedded Configurable Operating System. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + + eCos 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. + + eCos 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 eCos; if not, write to the Free Software Foundation, Inc., 51 + Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + As a special exception, if other files instantiate templates or use + macros or inline functions from this file, or you compile this file and + link it with other works to produce a work based on this file, this + file does not by itself cause the resulting work to be covered by the + GNU General Public License. However the source code for this file must + still be made available in accordance with section (3) of the GNU + General Public License. + + This exception does not invalidate any other reasons why a work based + on this file might be covered by the GNU General Public License. + + Alternative licenses for eCos may be arranged by contacting Red Hat, + Inc. at http://sources.redhat.com/ecos/ecos-license/ + ------------------------------------------- + + ####ECOSGPLCOPYRIGHTEND#### + +References + + 1. http://www.gnu.org/licenses/license-list.html
diff --git a/u-boot-imx/Licenses/gpl-2.0.txt b/u-boot-imx/Licenses/gpl-2.0.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/u-boot-imx/Licenses/gpl-2.0.txt
@@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License.
diff --git a/u-boot-imx/Licenses/ibm-pibs.txt b/u-boot-imx/Licenses/ibm-pibs.txt new file mode 100644 index 0000000..4cd7523 --- /dev/null +++ b/u-boot-imx/Licenses/ibm-pibs.txt
@@ -0,0 +1,17 @@ +This source code has been made available to you by IBM on an AS-IS +basis. Anyone receiving this source is licensed under IBM +copyrights to use it in any way he or she deems fit, including +copying it, modifying it, compiling it, and redistributing it either +with or without modifications. No license under IBM patents or +patent applications is to be implied by the copyright license. + +Any user of this software should understand that IBM cannot provide +technical support for this software and will not be responsible for +any consequences resulting from the use of this software. + +Any person who transfers this source code or any derivative work +must include the IBM copyright notice, this paragraph, and the +preceding two paragraphs in the transferred software. + +COPYRIGHT I B M CORPORATION 1995 +LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
diff --git a/u-boot-imx/Licenses/isc.txt b/u-boot-imx/Licenses/isc.txt new file mode 100644 index 0000000..4b7c2ba --- /dev/null +++ b/u-boot-imx/Licenses/isc.txt
@@ -0,0 +1,17 @@ +ISC License: +Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") +Copyright (c) 1995-2003 by Internet Software Consortium + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE +FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE.
diff --git a/u-boot-imx/Licenses/lgpl-2.0.txt b/u-boot-imx/Licenses/lgpl-2.0.txt new file mode 100644 index 0000000..5bc8fb2 --- /dev/null +++ b/u-boot-imx/Licenses/lgpl-2.0.txt
@@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it!
diff --git a/u-boot-imx/Licenses/lgpl-2.1.txt b/u-boot-imx/Licenses/lgpl-2.1.txt new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/u-boot-imx/Licenses/lgpl-2.1.txt
@@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it!
diff --git a/u-boot-imx/MAINTAINERS b/u-boot-imx/MAINTAINERS new file mode 100644 index 0000000..26d0d27 --- /dev/null +++ b/u-boot-imx/MAINTAINERS
@@ -0,0 +1,427 @@ +Descriptions of section entries: + + P: Person (obsolete) + M: Mail patches to: FullName <address@domain> + L: Mailing list that is relevant to this area + W: Web-page with status/info + Q: Patchwork web based patch tracking system site + T: SCM tree type and location. + Type is one of: git, hg, quilt, stgit, topgit + S: Status, one of the following: + Supported: Someone is actually paid to look after this. + Maintained: Someone actually looks after it. + Odd Fixes: It has a maintainer but they don't have time to do + much other than throw the odd patch in. See below.. + Orphan: No current maintainer [but maybe you could take the + role as you write your new code]. + Obsolete: Old code. Something tagged obsolete generally means + it has been replaced by a better system and you + should be using that. + F: Files and directories with wildcard patterns. + A trailing slash includes all files and subdirectory files. + F: drivers/net/ all files in and below drivers/net + F: drivers/net/* all files in drivers/net, but not below + F: */net/* all files in "any top level directory"/net + One pattern per line. Multiple F: lines acceptable. + N: Files and directories with regex patterns. + N: [^a-z]tegra all files whose path contains the word tegra + One pattern per line. Multiple N: lines acceptable. + scripts/get_maintainer.pl has different behavior for files that + match F: pattern and matches of N: patterns. By default, + get_maintainer will not look at git log history when an F: pattern + match occurs. When an N: match occurs, git log history is used + to also notify the people that have git commit signatures. + X: Files and directories that are NOT maintained, same rules as F: + Files exclusions are tested before file matches. + Can be useful for excluding a specific subdirectory, for instance: + F: net/ + X: net/ipv6/ + matches all files in and below net excluding net/ipv6/ + K: Keyword perl extended regex pattern to match content in a + patch or file. For instance: + K: of_get_profile + matches patches or files that contain "of_get_profile" + K: \b(printk|pr_(info|err))\b + matches patches or files that contain one or more of the words + printk, pr_info or pr_err + One regex pattern per line. Multiple K: lines acceptable. + +Note: For the hard of thinking, this list is meant to remain in alphabetical +order. If you could add yourselves to it in alphabetical order that would be +so much easier [Ed] + +Maintainers List (try to look for most precise areas first) + + ----------------------------------- +ARC +M: Alexey Brodkin <alexey.brodkin@synopsys.com> +S: Maintained +T: git git://git.denx.de/u-boot-arc.git +F: arch/arc/ + +ARM +M: Albert Aribaud <albert.u.boot@aribaud.net> +S: Maintained +T: git git://git.denx.de/u-boot-arm.git +F: arch/arm/ + +ARM ALTERA SOCFPGA +M: Marek Vasut <marex@denx.de> +S: Maintainted +T: git git://git.denx.de/u-boot-socfpga.git +F: arch/arm/cpu/armv7/socfpga/ +F: board/altera/socfpga/ + +ARM ATMEL AT91 +M: Andreas Bießmann <andreas.devel@googlemail.com> +S: Maintained +T: git git://git.denx.de/u-boot-atmel.git +F: arch/arm/mach-at91/ + +ARM FREESCALE IMX +M: Stefano Babic <sbabic@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-imx.git +F: arch/arm/cpu/arm1136/mx*/ +F: arch/arm/cpu/arm926ejs/mx*/ +F: arch/arm/cpu/arm926ejs/imx/ +F: arch/arm/cpu/armv7/mx*/ +F: arch/arm/cpu/armv7/vf610/ +F: arch/arm/cpu/imx-common/ +F: arch/arm/include/asm/arch-imx/ +F: arch/arm/include/asm/arch-mx*/ +F: arch/arm/include/asm/arch-vf610/ +F: arch/arm/include/asm/imx-common/ + +ARM MARVELL KIRKWOOD +M: Prafulla Wadaskar <prafulla@marvell.com> +M: Luka Perkov <luka.perkov@sartura.hr> +S: Maintained +T: git git://git.denx.de/u-boot-marvell.git +F: arch/arm/mach-kirkwood/ + +ARM MARVELL PXA +M: Marek Vasut <marex@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-pxa.git +F: arch/arm/cpu/pxa/ +F: arch/arm/include/asm/arch-pxa/ + +ARM SAMSUNG +M: Minkyu Kang <mk7.kang@samsung.com> +S: Maintained +T: git git://git.denx.de/u-boot-samsung.git +F: arch/arm/cpu/arm920t/s3c24x0/ +F: arch/arm/cpu/armv7/exynos/ +F: arch/arm/cpu/armv7/s5pc1xx/ +F: arch/arm/cpu/armv7/s5p-common/ +F: arch/arm/include/asm/arch-exynos/ +F: arch/arm/include/asm/arch-s3c24x0/ +F: arch/arm/include/asm/arch-s5pc1xx/ + +ARM STM SPEAR +M: Vipin Kumar <vipin.kumar@st.com> +S: Maintained +T: git git://git.denx.de/u-boot-stm.git +F: arch/arm/cpu/arm926ejs/spear/ +F: arch/arm/include/asm/arch-spear/ + +ARM STM STV0991 +M: Vikas Manocha <vikas.manocha@st.com> +S: Maintained +F: arch/arm/cpu/armv7/stv0991/ +F: arch/arm/include/asm/arch-stv0991/ + +ARM SUNXI +M: Ian Campbell <ijc@hellion.org.uk> +M: Hans De Goede <hdegoede@redhat.com> +S: Maintained +T: git git://git.denx.de/u-boot-sunxi.git +F: arch/arm/cpu/armv7/sunxi/ +F: arch/arm/include/asm/arch-sunxi/ + +ARM TEGRA +M: Tom Warren <twarren@nvidia.com> +S: Maintained +T: git git://git.denx.de/u-boot-tegra.git +F: arch/arm/mach-tegra/ +F: arch/arm/include/asm/arch-tegra*/ + +ARM TI +M: Tom Rini <trini@konsulko.com> +S: Maintained +T: git git://git.denx.de/u-boot-ti.git +F: arch/arm/mach-davinci/ +F: arch/arm/mach-keystone/ +F: arch/arm/cpu/arm926ejs/omap/ +F: arch/arm/cpu/armv7/omap*/ +F: arch/arm/include/asm/arch-omap*/ +F: arch/arm/include/asm/ti-common/ + +ARM UNIPHIER +M: Masahiro Yamada <yamada.masahiro@socionext.com> +S: Maintained +T: git git://git.denx.de/u-boot-uniphier.git +F: arch/arm/mach-uniphier/ +F: configs/ph1_*_defconfig +N: uniphier + +ARM ZYNQ +M: Michal Simek <monstr@monstr.eu> +S: Maintained +F: arch/arm/cpu/armv7/zynq/ +F: arch/arm/include/asm/arch-zynq/ + +ARM ZYNQMP +M: Michal Simek <michal.simek@xilinx.com> +S: Maintained +F: arch/arm/cpu/armv8/zynqmp/ +F: arch/arm/include/asm/arch-zynqmp/ + +AVR32 +M: Andreas Bießmann <andreas.devel@googlemail.com> +S: Maintained +T: git git://git.denx.de/u-boot-avr32.git +F: arch/avr32/ + +BLACKFIN +M: Sonic Zhang <sonic.adi@gmail.com> +S: Maintained +T: git git://git.denx.de/u-boot-blackfin.git +F: arch/blackfin/ + +BUILDMAN +M: Simon Glass <sjg@chromium.org> +S: Maintained +F: tools/buildman/ + +CFI FLASH +M: Stefan Roese <sr@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-cfi-flash.git +F: drivers/mtd/cfi_flash.c +F: drivers/mtd/jedec_flash.c + +COLDFIRE +M: Huan Wang <alison.wang@freescale.com> +M: Angelo Dureghello <angelo@sysam.it> +S: Maintained +T: git git://git.denx.de/u-boot-coldfire.git +F: arch/m68k/ + +DFU +M: Lukasz Majewski <l.majewski@samsung.com> +S: Maintained +T: git git://git.denx.de/u-boot-dfu.git +F: drivers/dfu/ +F: drivers/usb/gadget/ + +DRIVER MODEL +M: Simon Glass <sjg@chromium.org> +S: Maintained +T: git git://git.denx.de/u-boot-dm.git +F: drivers/core/ +F: include/dm/ +F: test/dm/ + +FLATTENED DEVICE TREE +M: Simon Glass <sjg@chromium.org> +S: Maintained +T: git git://git.denx.de/u-boot-fdt.git +F: lib/fdtdec* +F: lib/libfdt/ +F: include/fdt* +F: include/libfdt* +F. common/cmd_fdt.c +F: common/fdt_support.c + +FREEBSD +M: Rafal Jaworowski <raj@semihalf.com> +S: Maintained +T: git git://git.denx.de/u-boot-freebsd.git + +FREESCALE QORIQ +M: York Sun <yorksun@freescale.com> +S: Maintained +T: git git://git.denx.de/u-boot-fsl-qoriq.git + +I2C +M: Heiko Schocher <hs@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-i2c.git +F: drivers/i2c/ + +MICROBLAZE +M: Michal Simek <monstr@monstr.eu> +S: Maintained +T: git git://git.denx.de/u-boot-microblaze.git +F: arch/microblaze/ + +MIPS +M: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> +S: Maintained +T: git git://git.denx.de/u-boot-mips.git +F: arch/mips/ + +MMC +M: Pantelis Antoniou <panto@antoniou-consulting.com> +S: Maintained +T: git git://git.denx.de/u-boot-mmc.git +F: drivers/mmc/ + +OPENRISC +M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> +S: Maintained +F: arch/openrisc/ + +PATMAN +M: Simon Glass <sjg@chromium.org> +S: Maintained +F: tools/patman/ + +POWERPC +M: Wolfgang Denk <wd@denx.de> +S: Maintained +F: arch/powerpc/ + +POWERPC MPC5XXX +M: Wolfgang Denk <wd@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-mpc5xxx.git +F: arch/powerpc/cpu/mpc5*/ + +POWERPC MPC8XX +M: Wolfgang Denk <wd@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-mpc8xx.git +F: arch/powerpc/cpu/mpc8xx/ + +POWERPC MPC82XX +M: Wolfgang Denk <wd@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-mpc82xx.git +F: arch/powerpc/cpu/mpc82*/ + +POWERPC MPC83XX +M: Kim Phillips <kim.phillips@freescale.com> +S: Maintained +T: git git://git.denx.de/u-boot-mpc83xx.git +F: arch/powerpc/cpu/mpc83xx/ +F: arch/powerpc/include/asm/arch-mpc83xx/ + +POWERPC MPC85XX +M: York Sun <yorksun@freescale.com> +S: Maintained +T: git git://git.denx.de/u-boot-mpc85xx.git +F: arch/powerpc/cpu/mpc85xx/ + +POWERPC MPC86XX +M: York Sun <yorksun@freescale.com> +S: Maintained +T: git git://git.denx.de/u-boot-mpc86xx.git +F: arch/powerpc/cpu/mpc86xx/ + +POWERPC PPC4XX +M: Stefan Roese <sr@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-ppc4xx.git +F: arch/powerpc/cpu/ppc4xx/ + +NETWORK +M: Joe Hershberger <joe.hershberger@gmail.com> +S: Maintained +T: git git://git.denx.de/u-boot-net.git +F: drivers/net/ + +NAND FLASH +M: Scott Wood <scottwood@freescale.com> +S: Maintained +T: git git://git.denx.de/u-boot-nand-flash.git +F: drivers/mtd/nand/ + +NDS32 +M: Macpaul Lin <macpaul@andestech.com> +S: Maintained +T: git git://git.denx.de/u-boot-nds32.git +F: arch/nds32/ + +NIOS +M: Thomas Chou <thomas@wytron.com.tw> +S: Maintained +T: git git://git.denx.de/u-boot-nios.git +F: arch/nios2/ + +ONENAND +M: Lukasz Majewski <l.majewski@samsung.com> +S: Maintained +T: git git://git.denx.de/u-boot-onenand.git +F: drivers/mtd/onenand/ + +SANDBOX +M: Simon Glass <sjg@chromium.org> +S: Maintained +F: arch/sandbox/ + +SH +M: Nobuhiro Iwamatsu <iwamatsu@nigauri.org> +S: Maintained +T: git git://git.denx.de/u-boot-sh.git +F: arch/sh/ + +SPARC +M: Daniel Hellstrom <daniel@gaisler.com> +S: Maintained +T: git git://git.denx.de/u-boot-sparc.git +F: arch/sparc/ + +SPI +M: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com> +S: Maintained +T: git git://git.denx.de/u-boot-spi.git +F: drivers/mtd/spi/ +F: drivers/spi/ +F: include/spi* + +TESTING +M: Detlev Zundel <dzu@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-testing.git + +TQ GROUP +M: Martin Krause <martin.krause@tq-systems.de> +S: Maintained +T: git git://git.denx.de/u-boot-tq-group.git + +UBI +M: Kyungmin Park <kmpark@infradead.org> +M: Heiko Schocher <hs@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-ubi.git +F: drivers/mtd/ubi/ + +USB +M: Marek Vasut <marex@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-usb.git +F: drivers/usb/ + +VIDEO +M: Anatolij Gustschin <agust@denx.de> +S: Maintained +T: git git://git.denx.de/u-boot-video.git +F: drivers/video/ + +X86 +M: Simon Glass <sjg@chromium.org> +S: Maintained +T: git git://git.denx.de/u-boot-x86.git +F: arch/x86/ + +THE REST +M: Tom Rini <trini@konsulko.com> +L: u-boot@lists.denx.de +Q: http://patchwork.ozlabs.org/project/uboot/list/ +S: Maintained +T: git git://git.denx.de/u-boot.git +F: * +F: */
diff --git a/u-boot-imx/MAKEALL b/u-boot-imx/MAKEALL new file mode 100755 index 0000000..a6e378f --- /dev/null +++ b/u-boot-imx/MAKEALL
@@ -0,0 +1,840 @@ +#!/bin/bash +# Tool mainly for U-Boot Quality Assurance: build one or more board +# configurations with minimal verbosity, showing only warnings and +# errors. +# +# SPDX-License-Identifier: GPL-2.0+ + +usage() +{ + # if exiting with 0, write to stdout, else write to stderr + local ret=${1:-0} + [ "${ret}" -eq 1 ] && exec 1>&2 + cat <<-EOF + Usage: MAKEALL [options] [--] [boards-to-build] + + Options: + -a ARCH, --arch ARCH Build all boards with arch ARCH + -c CPU, --cpu CPU Build all boards with cpu CPU + -v VENDOR, --vendor VENDOR Build all boards with vendor VENDOR + -s SOC, --soc SOC Build all boards with soc SOC + -b BOARD, --board BOARD Build all boards with board name BOARD + -l, --list List all targets to be built + -m, --maintainers List all targets and maintainer email + -M, --mails List all targets and all affilated emails + -C, --check Enable build checking + -n, --continue Continue (skip boards already built) + -r, --rebuild-errors Rebuild any boards that errored + -h, --help This help output + + Selections by these options are logically ANDed; if the same option + is used repeatedly, such selections are ORed. So "-v FOO -v BAR" + will select all configurations where the vendor is either FOO or + BAR. Any additional arguments specified on the command line are + always build additionally. See the boards.cfg file for more info. + + If no boards are specified, then the default is "powerpc". + + Environment variables: + BUILD_NCPUS number of parallel make jobs (default: auto) + CROSS_COMPILE cross-compiler toolchain prefix (default: "") + CROSS_COMPILE_<ARCH> cross-compiler toolchain prefix for + architecture "ARCH". Substitute "ARCH" for any + supported architecture (default: "") + MAKEALL_LOGDIR output all logs to here (default: ./LOG/) + BUILD_DIR output build directory (default: ./) + BUILD_NBUILDS number of parallel targets (default: 1) + + Examples: + - build all Power Architecture boards: + MAKEALL -a powerpc + MAKEALL --arch powerpc + MAKEALL powerpc + - build all PowerPC boards manufactured by vendor "esd": + MAKEALL -a powerpc -v esd + - build all PowerPC boards manufactured either by "keymile" or "siemens": + MAKEALL -a powerpc -v keymile -v siemens + - build all Freescale boards with MPC83xx CPUs, plus all 4xx boards: + MAKEALL -c mpc83xx -v freescale 4xx + EOF + exit ${ret} +} + +SHORT_OPTS="ha:c:v:s:b:lmMCnr" +LONG_OPTS="help,arch:,cpu:,vendor:,soc:,board:,list,maintainers,mails,check,continue,rebuild-errors" + +# Option processing based on util-linux-2.13/getopt-parse.bash + +# Note that we use `"$@"' to let each command-line parameter expand to a +# separate word. The quotes around `$@' are essential! +# We need TEMP as the `eval set --' would nuke the return value of +# getopt. +TEMP=`getopt -o ${SHORT_OPTS} --long ${LONG_OPTS} \ + -n 'MAKEALL' -- "$@"` + +[ $? != 0 ] && usage 1 + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +SELECTED='' +ONLY_LIST='' +PRINT_MAINTS='' +MAINTAINERS_ONLY='' +CONTINUE='' +REBUILD_ERRORS='' + +while true ; do + case "$1" in + -a|--arch) + # echo "Option ARCH: argument \`$2'" + if [ "$opt_a" ] ; then + opt_a="${opt_a%)} || \$2 == \"$2\")" + else + opt_a="(\$2 == \"$2\")" + fi + SELECTED='y' + shift 2 ;; + -c|--cpu) + # echo "Option CPU: argument \`$2'" + if [ "$opt_c" ] ; then + opt_c="${opt_c%)} || \$3 == \"$2\" || \$3 ~ /$2:/)" + else + opt_c="(\$3 == \"$2\" || \$3 ~ /$2:/)" + fi + SELECTED='y' + shift 2 ;; + -s|--soc) + # echo "Option SoC: argument \`$2'" + if [ "$opt_s" ] ; then + opt_s="${opt_s%)} || \$4 == \"$2\" || \$4 ~ /$2/)" + else + opt_s="(\$4 == \"$2\" || \$4 ~ /$2/)" + fi + SELECTED='y' + shift 2 ;; + -v|--vendor) + # echo "Option VENDOR: argument \`$2'" + if [ "$opt_v" ] ; then + opt_v="${opt_v%)} || \$5 == \"$2\")" + else + opt_v="(\$5 == \"$2\")" + fi + SELECTED='y' + shift 2 ;; + -b|--board) + # echo "Option BOARD: argument \`$2'" + if [ "$opt_b" ] ; then + opt_b="${opt_b%)} || \$6 == \"$2\" || \$7 == \"$2\")" + else + # We need to check the 7th field too + # for boards whose 6th field is "-" + opt_b="(\$6 == \"$2\" || \$7 == \"$2\")" + fi + SELECTED='y' + shift 2 ;; + -C|--check) + CHECK='C=1' + shift ;; + -n|--continue) + CONTINUE='y' + shift ;; + -r|--rebuild-errors) + REBUILD_ERRORS='y' + shift ;; + -l|--list) + ONLY_LIST='y' + shift ;; + -m|--maintainers) + ONLY_LIST='y' + PRINT_MAINTS='y' + MAINTAINERS_ONLY='y' + shift ;; + -M|--mails) + ONLY_LIST='y' + PRINT_MAINTS='y' + shift ;; + -h|--help) + usage ;; + --) + shift ; break ;; + *) + echo "Internal error!" >&2 ; exit 1 ;; + esac +done + +GNU_MAKE=$(scripts/show-gnu-make) || { + echo "GNU Make not found" >&2 + exit 1 +} + +# echo "Remaining arguments:" +# for arg do echo '--> '"\`$arg'" ; done + +tools/genboardscfg.py || { + echo "Failed to generate boards.cfg" >&2 + exit 1 +} + +FILTER="\$1 !~ /^#/" +[ "$opt_a" ] && FILTER="${FILTER} && $opt_a" +[ "$opt_c" ] && FILTER="${FILTER} && $opt_c" +[ "$opt_s" ] && FILTER="${FILTER} && $opt_s" +[ "$opt_v" ] && FILTER="${FILTER} && $opt_v" +[ "$opt_b" ] && FILTER="${FILTER} && $opt_b" + +if [ "$SELECTED" ] ; then + SELECTED=$(awk '('"$FILTER"') { print $7 }' boards.cfg) + + # Make sure some boards from boards.cfg are actually found + if [ -z "$SELECTED" ] ; then + echo "Error: No boards selected, invalid arguments" + exit 1 + fi +fi + +######################################################################### + +# Print statistics when we exit +trap exit 1 2 3 15 +trap print_stats 0 + +# Determine number of CPU cores if no default was set +: ${BUILD_NCPUS:="`getconf _NPROCESSORS_ONLN`"} + +if [ "$BUILD_NCPUS" -gt 1 ] +then + JOBS="-j $((BUILD_NCPUS + 1))" +else + JOBS="" +fi + +if [ "${MAKEALL_LOGDIR}" ] ; then + LOG_DIR=${MAKEALL_LOGDIR} +else + LOG_DIR="LOG" +fi + +: ${BUILD_NBUILDS:=1} +BUILD_MANY=0 + +if [ "${BUILD_NBUILDS}" -gt 1 ] ; then + BUILD_MANY=1 + : ${BUILD_DIR:=./build} + mkdir -p "${BUILD_DIR}/ERR" + find "${BUILD_DIR}/ERR/" -type f -exec rm -f {} + +fi + +: ${BUILD_DIR:=.} + +OUTPUT_PREFIX="${BUILD_DIR}" + +[ -d ${LOG_DIR} ] || mkdir "${LOG_DIR}" || exit 1 +if [ "$CONTINUE" != 'y' -a "$REBUILD_ERRORS" != 'y' ] ; then + find "${LOG_DIR}/" -type f -exec rm -f {} + +fi + +LIST="" + +# Keep track of the number of builds and errors +ERR_CNT=0 +ERR_LIST="" +WRN_CNT=0 +WRN_LIST="" +TOTAL_CNT=0 +SKIP_CNT=0 +CURRENT_CNT=0 +OLDEST_IDX=1 +RC=0 + +# Helper funcs for parsing boards.cfg +targets_by_field() +{ + field=$1 + regexp=$2 + + awk '($1 !~ /^#/ && $'"$field"' ~ /^'"$regexp"'$/) { print $7 }' \ + boards.cfg +} + +targets_by_arch() { targets_by_field 2 "$@" ; } +targets_by_cpu() { targets_by_field 3 "$@" ; targets_by_field 3 "$@:.*" ; } +targets_by_soc() { targets_by_field 4 "$@" ; } + +######################################################################### +## MPC5xx Systems +######################################################################### + +LIST_5xx="$(targets_by_cpu mpc5xx)" + +######################################################################### +## MPC5xxx Systems +######################################################################### + +LIST_5xxx="$(targets_by_cpu mpc5xxx)" + +######################################################################### +## MPC512x Systems +######################################################################### + +LIST_512x="$(targets_by_cpu mpc512x)" + +######################################################################### +## MPC8xx Systems +######################################################################### + +LIST_8xx="$(targets_by_cpu mpc8xx)" + +######################################################################### +## PPC4xx Systems +######################################################################### + +LIST_4xx="$(targets_by_cpu ppc4xx)" + +######################################################################### +## MPC8260 Systems (includes 8250, 8255 etc.) +######################################################################### + +LIST_8260="$(targets_by_cpu mpc8260)" + +######################################################################### +## MPC83xx Systems (includes 8349, etc.) +######################################################################### + +LIST_83xx="$(targets_by_cpu mpc83xx)" + +######################################################################### +## MPC85xx Systems (includes 8540, 8560 etc.) +######################################################################### + +LIST_85xx="$(targets_by_cpu mpc85xx)" + +######################################################################### +## MPC86xx Systems +######################################################################### + +LIST_86xx="$(targets_by_cpu mpc86xx)" + +######################################################################### +## PowerPC groups +######################################################################### + +LIST_TSEC=" \ + ${LIST_83xx} \ + ${LIST_85xx} \ + ${LIST_86xx} \ +" + +LIST_powerpc=" \ + ${LIST_5xx} \ + ${LIST_512x} \ + ${LIST_5xxx} \ + ${LIST_8xx} \ + ${LIST_824x} \ + ${LIST_8260} \ + ${LIST_83xx} \ + ${LIST_85xx} \ + ${LIST_86xx} \ + ${LIST_4xx} \ +" + +# Alias "ppc" -> "powerpc" to not break compatibility with older scripts +# still using "ppc" instead of "powerpc" +LIST_ppc=" \ + ${LIST_powerpc} \ +" + +######################################################################### +## StrongARM Systems +######################################################################### + +LIST_SA="$(targets_by_cpu sa1100)" + +######################################################################### +## ARM7 Systems +######################################################################### + +LIST_ARM7="$(targets_by_cpu arm720t)" + +######################################################################### +## ARM9 Systems +######################################################################### + +LIST_ARM9="$(targets_by_cpu arm920t) \ + $(targets_by_cpu arm926ejs) \ + $(targets_by_cpu arm946es) \ +" + +######################################################################### +## ARM11 Systems +######################################################################### +LIST_ARM11="$(targets_by_cpu arm1136) \ + $(targets_by_cpu arm1176) \ +" + +######################################################################### +## ARMV7 Systems +######################################################################### + +LIST_ARMV7="$(targets_by_cpu armv7)" + +######################################################################### +## ARMV8 Systems +######################################################################### + +LIST_ARMV8="$(targets_by_cpu armv8)" + +######################################################################### +## AT91 Systems +######################################################################### + +LIST_at91="$(targets_by_soc at91)" + +######################################################################### +## Xscale Systems +######################################################################### + +LIST_pxa="$(targets_by_cpu pxa)" + +######################################################################### +## SPEAr Systems +######################################################################### + +LIST_spear="$(targets_by_soc spear)" + +######################################################################### +## ARM groups +######################################################################### + +LIST_arm="$(targets_by_arch arm | \ + for ARMV8_TARGET in $LIST_ARMV8; \ + do sed "/$ARMV8_TARGET/d"; \ + done) \ +" + +######################################################################### +## MIPS Systems (default = big endian) +######################################################################### + +LIST_mips="$(targets_by_arch mips)" + +######################################################################### +## OpenRISC Systems +######################################################################### + +LIST_openrisc="$(targets_by_arch openrisc)" + +######################################################################### +## x86 Systems +######################################################################### + +LIST_x86="$(targets_by_arch x86)" + +######################################################################### +## Nios-II Systems +######################################################################### + +LIST_nios2="$(targets_by_arch nios2)" + +######################################################################### +## MicroBlaze Systems +######################################################################### + +LIST_microblaze="$(targets_by_arch microblaze)" + +######################################################################### +## ColdFire Systems +######################################################################### + +LIST_m68k="$(targets_by_arch m68k)" +LIST_coldfire=${LIST_m68k} + +######################################################################### +## AVR32 Systems +######################################################################### + +LIST_avr32="$(targets_by_arch avr32)" + +######################################################################### +## Blackfin Systems +######################################################################### + +LIST_blackfin="$(targets_by_arch blackfin)" + +######################################################################### +## SH Systems +######################################################################### + +LIST_sh2="$(targets_by_cpu sh2)" +LIST_sh3="$(targets_by_cpu sh3)" +LIST_sh4="$(targets_by_cpu sh4)" + +LIST_sh="$(targets_by_arch sh)" + +######################################################################### +## SPARC Systems +######################################################################### + +LIST_sparc="$(targets_by_arch sparc)" + +######################################################################### +## NDS32 Systems +######################################################################### + +LIST_nds32="$(targets_by_arch nds32)" + +######################################################################### +## ARC Systems +######################################################################### + +LIST_arc="$(targets_by_arch arc)" + +#----------------------------------------------------------------------- + +get_target_location() { + local target=$1 + local BOARD_NAME="" + local CONFIG_NAME="" + local board="" + local vendor="" + + # Automatic mode + local line=`awk '\$7 == "'"$target"'" { print \$0 }' boards.cfg` + if [ -z "${line}" ] ; then echo "" ; return ; fi + + set ${line} + + CONFIG_NAME="${7%_defconfig}" + + [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_defconfig}" + + if [ $# -gt 5 ]; then + if [ "$6" = "-" ] ; then + board=${BOARD_NAME} + else + board="$6" + fi + fi + + [ $# -gt 4 ] && [ "$5" != "-" ] && vendor="$5" + [ $# -gt 6 ] && [ "$8" != "-" ] && { + tmp="${8%:*}" + if [ "$tmp" ] ; then + CONFIG_NAME="$tmp" + fi + } + + # Assign board directory to BOARDIR variable + if [ "${vendor}" == "-" ] ; then + BOARDDIR=${board} + else + BOARDDIR=${vendor}/${board} + fi + + echo "${CONFIG_NAME}:${BOARDDIR}:${BOARD_NAME}" +} + +get_target_maintainers() { + local name=`echo $1 | cut -d : -f 3` + + local line=`awk '\$7 == "'"$target"'" { print \$0 }' boards.cfg` + if [ -z "${line}" ]; then + echo "" + return ; + fi + + local mails=`echo ${line} | cut -d ' ' -f 9- | sed -e 's/[^<]*<//' -e 's/>.*</ /' -e 's/>[^>]*$//'` + [ "$mails" == "-" ] && mails="" + echo "$mails" +} + +get_target_arch() { + local target=$1 + + awk '$7 == "'$target'" { print $2 }' boards.cfg +} + +list_target() { + if [ "$PRINT_MAINTS" != 'y' ] ; then + echo "$1" + return + fi + + echo -n "$1:" + + local loc=`get_target_location $1` + + if [ -z "${loc}" ] ; then echo "ERROR" ; return ; fi + + local maintainers_result=`get_target_maintainers ${loc} | tr " " "\n"` + + if [ "$MAINTAINERS_ONLY" != 'y' ] ; then + + local dir=`echo ${loc} | cut -d ":" -f 2` + local cfg=`echo ${loc} | cut -d ":" -f 1` + local git_result=`git log --format=%aE board/${dir} \ + include/configs/${cfg}.h | grep "@"` + local git_result_recent=`echo ${git_result} | tr " " "\n" | \ + head -n 3` + local git_result_top=`echo ${git_result} | tr " " "\n" | \ + sort | uniq -c | sort -nr | head -n 3 | \ + sed "s/^ \+[0-9]\+ \+//"` + + echo -e "$git_result_recent\n$git_result_top\n$maintainers_result" | \ + sort -u | tr "\n" " " | sed "s/ $//" ; + else + echo -e "$maintainers_result" | sort -u | tr "\n" " " | \ + sed "s/ $//" ; + fi + + echo "" +} + +# Each finished build will have a file called ${donep}${n}, +# where n is the index of the build. Each build +# we've already noted as finished will have ${skipp}${n}. +# The code managing the build process will use this information +# to ensure that only BUILD_NBUILDS builds are in flight at once +donep="${LOG_DIR}/._done_" +skipp="${LOG_DIR}/._skip_" + +build_target_killed() { + echo "Aborted $target build." + # Remove the logs for this board since it was aborted + rm -f ${LOG_DIR}/$target.MAKELOG ${LOG_DIR}/$target.ERR + exit +} + +build_target() { + target=$1 + build_idx=$2 + + if [ "$ONLY_LIST" == 'y' ] ; then + list_target ${target} + return + fi + + if [ $BUILD_MANY == 1 ] ; then + output_dir="${OUTPUT_PREFIX}/${target}" + mkdir -p "${output_dir}" + trap build_target_killed TERM + else + output_dir="${OUTPUT_PREFIX}" + fi + + target_arch=$(get_target_arch ${target}) + eval cross_toolchain=\$CROSS_COMPILE_`echo $target_arch | tr '[:lower:]' '[:upper:]'` + if [ "${cross_toolchain}" ] ; then + MAKE="$GNU_MAKE CROSS_COMPILE=${cross_toolchain}" + elif [ "${CROSS_COMPILE}" ] ; then + MAKE="$GNU_MAKE CROSS_COMPILE=${CROSS_COMPILE}" + else + MAKE=$GNU_MAKE + fi + + if [ "${output_dir}" != "." ] ; then + MAKE="${MAKE} O=${output_dir}" + fi + + ${MAKE} mrproper >/dev/null + + echo "Building ${target} board..." + ${MAKE} -s ${target}_defconfig >/dev/null + + ${MAKE} ${JOBS} ${CHECK} all \ + >${LOG_DIR}/$target.MAKELOG 2> ${LOG_DIR}/$target.ERR + + # Check for 'make' errors + if [ ${PIPESTATUS[0]} -ne 0 ] ; then + RC=1 + fi + + OBJS=${output_dir}/u-boot + if [ -e ${output_dir}/spl/u-boot-spl ]; then + OBJS="${OBJS} ${output_dir}/spl/u-boot-spl" + fi + + ${CROSS_COMPILE}size ${OBJS} | tee -a ${LOG_DIR}/$target.MAKELOG + + if [ $BUILD_MANY == 1 ] ; then + trap - TERM + + ${MAKE} -s clean + + if [ -s ${LOG_DIR}/${target}.ERR ] ; then + cp ${LOG_DIR}/${target}.ERR ${OUTPUT_PREFIX}/ERR/${target} + else + rm ${LOG_DIR}/${target}.ERR + fi + else + if [ -s ${LOG_DIR}/${target}.ERR ] ; then + if grep -iw error ${LOG_DIR}/${target}.ERR ; then + : $(( ERR_CNT += 1 )) + ERR_LIST="${ERR_LIST} $target" + else + : $(( WRN_CNT += 1 )) + WRN_LIST="${WRN_LIST} $target" + fi + else + rm ${LOG_DIR}/${target}.ERR + fi + fi + + [ -e "${LOG_DIR}/${target}.ERR" ] && cat "${LOG_DIR}/${target}.ERR" + + touch "${donep}${build_idx}" +} + +manage_builds() { + search_idx=${OLDEST_IDX} + if [ "$ONLY_LIST" == 'y' ] ; then return ; fi + + while true; do + if [ -e "${donep}${search_idx}" ] ; then + : $(( CURRENT_CNT-- )) + [ ${OLDEST_IDX} -eq ${search_idx} ] && + : $(( OLDEST_IDX++ )) + + # Only want to count it once + rm -f "${donep}${search_idx}" + touch "${skipp}${search_idx}" + elif [ -e "${skipp}${search_idx}" ] ; then + [ ${OLDEST_IDX} -eq ${search_idx} ] && + : $(( OLDEST_IDX++ )) + fi + : $(( search_idx++ )) + if [ ${search_idx} -gt ${TOTAL_CNT} ] ; then + if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then + search_idx=${OLDEST_IDX} + sleep 1 + else + break + fi + fi + done +} + +build_targets() { + for t in "$@" ; do + # If a LIST_xxx var exists, use it. But avoid variable + # expansion in the eval when a board name contains certain + # characters that the shell interprets. + case ${t} in + *[-+=]*) list= ;; + *) list=$(eval echo '${LIST_'$t'}') ;; + esac + if [ -n "${list}" ] ; then + build_targets ${list} + else + : $((TOTAL_CNT += 1)) + : $((CURRENT_CNT += 1)) + rm -f "${donep}${TOTAL_CNT}" + rm -f "${skipp}${TOTAL_CNT}" + if [ "$CONTINUE" = 'y' -a -e ${LOG_DIR}/$t.MAKELOG ] ; then + : $((SKIP_CNT += 1)) + touch "${donep}${TOTAL_CNT}" + elif [ "$REBUILD_ERRORS" = 'y' -a ! -e ${LOG_DIR}/$t.ERR ] ; then + : $((SKIP_CNT += 1)) + touch "${donep}${TOTAL_CNT}" + else + if [ $BUILD_MANY == 1 ] ; then + build_target ${t} ${TOTAL_CNT} & + else + CUR_TGT="${t}" + build_target ${t} ${TOTAL_CNT} + CUR_TGT='' + fi + fi + fi + + # We maintain a running count of all the builds we have done. + # Each finished build will have a file called ${donep}${n}, + # where n is the index of the build. Each build + # we've already noted as finished will have ${skipp}${n}. + # We track the current index via TOTAL_CNT, and the oldest + # index. When we exceed the maximum number of parallel builds, + # We look from oldest to current for builds that have completed, + # and update the current count and oldest index as appropriate. + # If we've gone through the entire list, wait a second, and + # reprocess the entire list until we find a build that has + # completed + if [ ${CURRENT_CNT} -ge ${BUILD_NBUILDS} ] ; then + manage_builds + fi + done +} + +#----------------------------------------------------------------------- + +kill_children() { + local OS=$(uname -s) + local children="" + case "${OS}" in + "Darwin") + # Mac OS X is known to have BSD style ps + local pgid=$(ps -p $$ -o pgid | sed -e "/PGID/d") + children=$(ps -g $pgid -o pid | sed -e "/PID\|$$\|$pgid/d") + ;; + *) + # everything else tries the GNU style + local pgid=$(ps -p $$ --no-headers -o "%r" | tr -d ' ') + children=$(pgrep -g $pgid | sed -e "/$$\|$pgid/d") + ;; + esac + + kill $children 2> /dev/null + wait $children 2> /dev/null + + exit +} + +print_stats() { + if [ "$ONLY_LIST" == 'y' ] ; then return ; fi + + # Only count boards that completed + : $((TOTAL_CNT = `find ${skipp}* 2> /dev/null | wc -l`)) + + rm -f ${donep}* ${skipp}* + + if [ $BUILD_MANY == 1 ] && [ -e "${OUTPUT_PREFIX}/ERR" ] ; then + ERR_LIST=`grep -riwl error ${OUTPUT_PREFIX}/ERR/` + ERR_LIST=`for f in $ERR_LIST ; do echo -n " $(basename $f)" ; done` + ERR_CNT=`echo $ERR_LIST | wc -w | awk '{print $1}'` + WRN_LIST=`grep -riwL error ${OUTPUT_PREFIX}/ERR/` + WRN_LIST=`for f in $WRN_LIST ; do echo -n " $(basename $f)" ; done` + WRN_CNT=`echo $WRN_LIST | wc -w | awk '{print $1}'` + else + # Remove the logs for any board that was interrupted + rm -f ${LOG_DIR}/${CUR_TGT}.MAKELOG ${LOG_DIR}/${CUR_TGT}.ERR + fi + + : $((TOTAL_CNT -= ${SKIP_CNT})) + echo "" + echo "--------------------- SUMMARY ----------------------------" + if [ "$CONTINUE" = 'y' -o "$REBUILD_ERRORS" = 'y' ] ; then + echo "Boards skipped: ${SKIP_CNT}" + fi + echo "Boards compiled: ${TOTAL_CNT}" + if [ ${ERR_CNT} -gt 0 ] ; then + echo "Boards with errors: ${ERR_CNT} (${ERR_LIST} )" + fi + if [ ${WRN_CNT} -gt 0 ] ; then + echo "Boards with warnings but no errors: ${WRN_CNT} (${WRN_LIST} )" + fi + echo "----------------------------------------------------------" + + if [ $BUILD_MANY == 1 ] ; then + kill_children + fi + + exit $RC +} + +#----------------------------------------------------------------------- + +# Build target groups selected by options, plus any command line args +set -- ${SELECTED} "$@" +# run PowerPC by default +[ $# = 0 ] && set -- powerpc +build_targets "$@" +wait
diff --git a/u-boot-imx/Makefile b/u-boot-imx/Makefile new file mode 100644 index 0000000..950c960 --- /dev/null +++ b/u-boot-imx/Makefile
@@ -0,0 +1,1548 @@ +VERSION = 2015 +PATCHLEVEL = 04 +SUBLEVEL = +EXTRAVERSION = +NAME = + +# *DOCUMENTATION* +# To see a list of typical targets execute "make help" +# More info can be located in ./README +# Comments in this file are targeted only to the developer, do not +# expect to learn how to build the kernel reading this file. + +# Do not use make's built-in rules and variables +# (this increases performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -rR + +# Avoid funny character set dependencies +unexport LC_ALL +LC_COLLATE=C +LC_NUMERIC=C +export LC_COLLATE LC_NUMERIC + +# Avoid interference with shell env settings +unexport GREP_OPTIONS + +# We are using a recursive build, so we need to do a little thinking +# to get the ordering right. +# +# Most importantly: sub-Makefiles should only ever modify files in +# their own directory. If in some directory we have a dependency on +# a file in another dir (which doesn't happen often, but it's often +# unavoidable when linking the built-in.o targets which finally +# turn into vmlinux), we will call a sub make in that other dir, and +# after that we are sure that everything which is in that other dir +# is now up to date. +# +# The only cases where we need to modify files which have global +# effects are thus separated out and done before the recursive +# descending is started. They are now explicitly listed as the +# prepare rule. + +# Beautify output +# --------------------------------------------------------------------------- +# +# Normally, we echo the whole command before executing it. By making +# that echo $($(quiet)$(cmd)), we now have the possibility to set +# $(quiet) to choose other forms of output instead, e.g. +# +# quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@ +# cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< +# +# If $(quiet) is empty, the whole command will be printed. +# If it is set to "quiet_", only the short version will be printed. +# If it is set to "silent_", nothing will be printed at all, since +# the variable $(silent_cmd_cc_o_c) doesn't exist. +# +# A simple variant is to prefix commands with $(Q) - that's useful +# for commands that shall be hidden in non-verbose mode. +# +# $(Q)ln $@ :< +# +# If KBUILD_VERBOSE equals 0 then the above command will be hidden. +# If KBUILD_VERBOSE equals 1 then the above command is displayed. +# +# To put more focus on warnings, be less verbose as default +# Use 'make V=1' to see the full commands + +ifeq ("$(origin V)", "command line") + KBUILD_VERBOSE = $(V) +endif +ifndef KBUILD_VERBOSE + KBUILD_VERBOSE = 0 +endif + +ifeq ($(KBUILD_VERBOSE),1) + quiet = + Q = +else + quiet=quiet_ + Q = @ +endif + +# If the user is running make -s (silent mode), suppress echoing of +# commands + +ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 +ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) + quiet=silent_ +endif +else # make-3.8x +ifneq ($(filter s% -s%,$(MAKEFLAGS)),) + quiet=silent_ +endif +endif + +export quiet Q KBUILD_VERBOSE + +# kbuild supports saving output files in a separate directory. +# To locate output files in a separate directory two syntaxes are supported. +# In both cases the working directory must be the root of the kernel src. +# 1) O= +# Use "make O=dir/to/store/output/files/" +# +# 2) Set KBUILD_OUTPUT +# Set the environment variable KBUILD_OUTPUT to point to the directory +# where the output files shall be placed. +# export KBUILD_OUTPUT=dir/to/store/output/files/ +# make +# +# The O= assignment takes precedence over the KBUILD_OUTPUT environment +# variable. + +# KBUILD_SRC is set on invocation of make in OBJ directory +# KBUILD_SRC is not intended to be used by the regular user (for now) +ifeq ($(KBUILD_SRC),) + +# OK, Make called in directory where kernel src resides +# Do we want to locate output files in a separate directory? +ifeq ("$(origin O)", "command line") + KBUILD_OUTPUT := $(O) +endif + +# That's our default target when none is given on the command line +PHONY := _all +_all: + +# Cancel implicit rules on top Makefile +$(CURDIR)/Makefile Makefile: ; + +ifneq ($(KBUILD_OUTPUT),) +# Invoke a second make in the output directory, passing relevant variables +# check that the output directory actually exists +saved-output := $(KBUILD_OUTPUT) +KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \ + && /bin/pwd) +$(if $(KBUILD_OUTPUT),, \ + $(error failed to create output directory "$(saved-output)")) + +PHONY += $(MAKECMDGOALS) sub-make + +$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make + @: + +sub-make: FORCE + $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \ + -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS)) + +# Leave processing to above invocation of make +skip-makefile := 1 +endif # ifneq ($(KBUILD_OUTPUT),) +endif # ifeq ($(KBUILD_SRC),) + +# We process the rest of the Makefile if this is the final invocation of make +ifeq ($(skip-makefile),) + +# Do not print "Entering directory ...", +# but we want to display it when entering to the output directory +# so that IDEs/editors are able to understand relative filenames. +MAKEFLAGS += --no-print-directory + +# Call a source code checker (by default, "sparse") as part of the +# C compilation. +# +# Use 'make C=1' to enable checking of only re-compiled files. +# Use 'make C=2' to enable checking of *all* source files, regardless +# of whether they are re-compiled or not. +# +# See the file "Documentation/sparse.txt" for more details, including +# where to get the "sparse" utility. + +ifeq ("$(origin C)", "command line") + KBUILD_CHECKSRC = $(C) +endif +ifndef KBUILD_CHECKSRC + KBUILD_CHECKSRC = 0 +endif + +# Use make M=dir to specify directory of external module to build +# Old syntax make ... SUBDIRS=$PWD is still supported +# Setting the environment variable KBUILD_EXTMOD take precedence +ifdef SUBDIRS + KBUILD_EXTMOD ?= $(SUBDIRS) +endif + +ifeq ("$(origin M)", "command line") + KBUILD_EXTMOD := $(M) +endif + +# If building an external module we do not care about the all: rule +# but instead _all depend on modules +PHONY += all +ifeq ($(KBUILD_EXTMOD),) +_all: all +else +_all: modules +endif + +ifeq ($(KBUILD_SRC),) + # building in the source tree + srctree := . +else + ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR))) + # building in a subdirectory of the source tree + srctree := .. + else + srctree := $(KBUILD_SRC) + endif +endif +objtree := . +src := $(srctree) +obj := $(objtree) + +VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) + +export srctree objtree VPATH + +# Make sure CDPATH settings don't interfere +unexport CDPATH + +######################################################################### + +HOSTARCH := $(shell uname -m | \ + sed -e s/i.86/x86/ \ + -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/') + +export HOSTARCH HOSTOS + +######################################################################### + +# set default to nothing for native builds +ifeq ($(HOSTARCH),$(ARCH)) +CROSS_COMPILE ?= +endif + +KCONFIG_CONFIG ?= .config +export KCONFIG_CONFIG + +# SHELL used by kbuild +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) + +HOSTCC = cc +HOSTCXX = c++ +HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCXXFLAGS = -O2 + +ifeq ($(HOSTOS),cygwin) +HOSTCFLAGS += -ansi +endif + +# 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") + +# since Lion (10.7) ASLR is on by default, but we use linker generated lists +# in some host tools which is a problem then ... so disable ASLR for these +# tools +HOSTLDFLAGS += $(call os_x_before, 10, 7, "", "-Xlinker -no_pie") +endif + +# Decide whether to build built-in, modular, or both. +# Normally, just do built-in. + +KBUILD_MODULES := +KBUILD_BUILTIN := 1 + +# If we have only "make modules", don't compile built-in objects. +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are up to date before we record them. + +ifeq ($(MAKECMDGOALS),modules) + KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) +endif + +# If we have "make <whatever> modules", compile modules +# in addition to whatever we do anyway. +# Just "make" or "make all" shall build modules as well + +# U-Boot does not need modules +#ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) +# KBUILD_MODULES := 1 +#endif + +#ifeq ($(MAKECMDGOALS),) +# KBUILD_MODULES := 1 +#endif + +export KBUILD_MODULES KBUILD_BUILTIN +export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD + +# Look for make include files relative to root of kernel src +MAKEFLAGS += --include-dir=$(srctree) + +# We need some generic definitions (do not try to remake the file). +$(srctree)/scripts/Kbuild.include: ; +include $(srctree)/scripts/Kbuild.include + +# Make variables (CC, etc...) + +AS = $(CROSS_COMPILE)as +# Always use GNU ld +ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),) +LD = $(CROSS_COMPILE)ld.bfd +else +LD = $(CROSS_COMPILE)ld +endif +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +LDR = $(CROSS_COMPILE)ldr +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +AWK = awk +PERL = perl +PYTHON = python +DTC = dtc +CHECK = sparse + +CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ + -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__ $(CF) + +KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__ + +KBUILD_CFLAGS := -Wall -Wstrict-prototypes \ + -Wno-format-security \ + -fno-builtin -ffreestanding +KBUILD_AFLAGS := -D__ASSEMBLY__ + +# Read UBOOTRELEASE from include/config/uboot.release (if it exists) +UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null) +UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) + +export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION +export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR +export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC +export CPP AR NM LDR STRIP OBJCOPY OBJDUMP +export MAKE AWK PERL PYTHON +export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGS + +export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS +export KBUILD_CFLAGS KBUILD_AFLAGS + +# When compiling out-of-tree modules, put MODVERDIR in the module +# tree rather than in the kernel tree. The kernel tree might +# even be read-only. +export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions + +# Files to ignore in find ... statements + +export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \ + -name CVS -o -name .pc -o -name .hg -o -name .git \) \ + -prune -o +export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \ + --exclude CVS --exclude .pc --exclude .hg --exclude .git + +# =========================================================================== +# Rules shared between *config targets and build targets + +# Basic helpers built in scripts/ +PHONY += scripts_basic +scripts_basic: + $(Q)$(MAKE) $(build)=scripts/basic + $(Q)rm -f .tmp_quiet_recordmcount + +# To avoid any implicit rule to kick in, define an empty command. +scripts/basic/%: scripts_basic ; + +PHONY += outputmakefile +# outputmakefile generates a Makefile in the output directory, if using a +# separate output directory. This allows convenient use of make in the +# output directory. +outputmakefile: +ifneq ($(KBUILD_SRC),) + $(Q)ln -fsn $(srctree) source + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) +endif + +# To make sure we do not include .config for any of the *config targets +# catch them early, and hand them over to scripts/kconfig/Makefile +# It is allowed to specify more targets when calling make, including +# mixing *config targets and build targets. +# For example 'make oldconfig all'. +# Detect when mixed targets is specified, and make a second invocation +# of make so .config is not included in this case either (for *config). + +version_h := include/generated/version_autogenerated.h +timestamp_h := include/generated/timestamp_autogenerated.h + +no-dot-config-targets := clean clobber mrproper distclean \ + help %docs check% coccicheck \ + ubootversion backup + +config-targets := 0 +mixed-targets := 0 +dot-config := 1 + +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + dot-config := 0 + endif +endif + +ifeq ($(KBUILD_EXTMOD),) + ifneq ($(filter config %config,$(MAKECMDGOALS)),) + config-targets := 1 + ifneq ($(filter-out config %config,$(MAKECMDGOALS)),) + mixed-targets := 1 + endif + endif +endif + +ifeq ($(mixed-targets),1) +# =========================================================================== +# We're called with mixed targets (*config and build targets). +# Handle them one by one. + +PHONY += $(MAKECMDGOALS) __build_one_by_one + +$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one + @: + +__build_one_by_one: + $(Q)set -e; \ + for i in $(MAKECMDGOALS); do \ + $(MAKE) -f $(srctree)/Makefile $$i; \ + done + +else +ifeq ($(config-targets),1) +# =========================================================================== +# *config targets only - make sure prerequisites are updated, and descend +# in scripts/kconfig to make the *config target + +KBUILD_DEFCONFIG := sandbox_defconfig +export KBUILD_DEFCONFIG KBUILD_KCONFIG + +config: scripts_basic outputmakefile FORCE + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + +%config: scripts_basic outputmakefile FORCE + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + +else +# =========================================================================== +# Build targets only - this includes vmlinux, arch specific targets, clean +# targets and others. In general all targets except *config targets. + +ifeq ($(dot-config),1) +# Read in config +-include include/config/auto.conf + +# Read in dependencies to all Kconfig* files, make sure to run +# oldconfig if changes are detected. +-include include/config/auto.conf.cmd + +# To avoid any implicit rule to kick in, define an empty command +$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; + +# If .config is newer than include/config/auto.conf, someone tinkered +# with it and forgot to run make oldconfig. +# if auto.conf.cmd is missing then we are probably in a cleaned tree so +# we execute the config step to be sure to catch updated Kconfig files +include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd + $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig + @# If the following part fails, include/config/auto.conf should be + @# deleted so "make silentoldconfig" will be re-run on the next build. + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \ + { rm -f include/config/auto.conf; false; } + @# include/config.h has been updated after "make silentoldconfig". + @# We need to touch include/config/auto.conf so it gets newer + @# than include/config.h. + @# Otherwise, 'make silentoldconfig' would be invoked twice. + $(Q)touch include/config/auto.conf + +-include include/autoconf.mk +-include include/autoconf.mk.dep + +# We want to include arch/$(ARCH)/config.mk only when include/config/auto.conf +# is up-to-date. When we switch to a different board configuration, old CONFIG +# macros are still remaining in include/config/auto.conf. Without the following +# gimmick, wrong config.mk would be included leading nasty warnings/errors. +ifneq ($(wildcard $(KCONFIG_CONFIG)),) +ifneq ($(wildcard include/config/auto.conf),) +autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \ + include/config/auto.conf) +ifeq ($(autoconf_is_old),) +include $(srctree)/config.mk +include $(srctree)/arch/$(ARCH)/Makefile +endif +endif +endif + +# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use +# that (or fail if absent). Otherwise, search for a linker script in a +# standard location. + +ifndef LDSCRIPT + #LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug + ifdef CONFIG_SYS_LDSCRIPT + # need to strip off double quotes + LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%) + endif +endif + +# If there is no specified link script, we look in a number of places for it +ifndef LDSCRIPT + ifeq ($(wildcard $(LDSCRIPT)),) + LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds + endif + ifeq ($(wildcard $(LDSCRIPT)),) + LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds + endif + ifeq ($(wildcard $(LDSCRIPT)),) + LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot.lds + endif +endif + +else +# Dummy target needed, because used as prerequisite +include/config/auto.conf: ; +endif # $(dot-config) + +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE +KBUILD_CFLAGS += -Os +else +KBUILD_CFLAGS += -O2 +endif + +ifdef BUILD_TAG +KBUILD_CFLAGS += -DBUILD_TAG='"$(BUILD_TAG)"' +endif + +KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) + +KBUILD_CFLAGS += -g +# $(KBUILD_AFLAGS) sets -g, which causes gcc to pass a suitable -g<format> +# option to the assembler. +KBUILD_AFLAGS += -g + +# Report stack usage if supported +ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-stack-usage.sh $(CC)),y) + KBUILD_CFLAGS += -fstack-usage +endif + +KBUILD_CFLAGS += $(call cc-option,-Wno-format-nonliteral) + +# turn jbsr into jsr for m68k +ifeq ($(ARCH),m68k) +ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4) +KBUILD_AFLAGS += -Wa,-gstabs,-S +endif +endif + +# Prohibit date/time macros, which would make the build non-deterministic +KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) + +ifneq ($(CONFIG_SYS_TEXT_BASE),) +KBUILD_CPPFLAGS += -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) +endif + +export CONFIG_SYS_TEXT_BASE + +include $(srctree)/scripts/Makefile.extrawarn + +# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments +KBUILD_CPPFLAGS += $(KCPPFLAGS) +KBUILD_AFLAGS += $(KAFLAGS) +KBUILD_CFLAGS += $(KCFLAGS) + +# Use UBOOTINCLUDE when you must reference the include/ directory. +# Needed to be compatible with the O= option +UBOOTINCLUDE := \ + -Iinclude \ + $(if $(KBUILD_SRC), -I$(srctree)/include) \ + -I$(srctree)/arch/$(ARCH)/include \ + -include $(srctree)/include/linux/kconfig.h + +NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) +CHECKFLAGS += $(NOSTDINC_FLAGS) + +# FIX ME +cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \ + $(NOSTDINC_FLAGS) +c_flags := $(KBUILD_CFLAGS) $(cpp_flags) + +######################################################################### +# U-Boot objects....order is important (i.e. start must be first) + +HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n) + +libs-y += lib/ +libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ +libs-$(CONFIG_OF_EMBED) += dts/ +libs-y += fs/ +libs-y += net/ +libs-y += disk/ +libs-y += drivers/ +libs-y += drivers/dma/ +libs-y += drivers/gpio/ +libs-y += drivers/i2c/ +libs-y += drivers/mmc/ +libs-y += drivers/mtd/ +libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/ +libs-y += drivers/mtd/onenand/ +libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/ +libs-y += drivers/mtd/spi/ +libs-y += drivers/net/ +libs-y += drivers/net/phy/ +libs-y += drivers/pci/ +libs-y += drivers/power/ \ + drivers/power/fuel_gauge/ \ + drivers/power/mfd/ \ + drivers/power/pmic/ \ + drivers/power/battery/ +libs-y += drivers/spi/ +libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/ +libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/ +libs-y += drivers/serial/ +libs-y += drivers/usb/eth/ +libs-y += drivers/usb/gadget/ +libs-y += drivers/usb/host/ +libs-y += drivers/usb/musb/ +libs-y += drivers/usb/musb-new/ +libs-y += drivers/usb/phy/ +libs-y += drivers/usb/ulpi/ +libs-y += common/ +libs-$(CONFIG_API) += api/ +libs-$(CONFIG_HAS_POST) += post/ +libs-y += test/ +libs-y += test/dm/ + +libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) + +libs-y := $(sort $(libs-y)) + +u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples + +u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-)))) + +libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) + +u-boot-init := $(head-y) +u-boot-main := $(libs-y) + + +# Add GCC lib +ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y) +PLATFORM_LIBGCC = arch/$(ARCH)/lib/lib.a +else +PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(c_flags) -print-libgcc-file-name`) -lgcc +endif +PLATFORM_LIBS += $(PLATFORM_LIBGCC) +export PLATFORM_LIBS +export PLATFORM_LIBGCC + +# Special flags for CPP when processing the linker script. +# Pass the version down so we can handle backwards compatibility +# on the fly. +LDPPFLAGS += \ + -include $(srctree)/include/u-boot/u-boot.lds.h \ + -DCPUDIR=$(CPUDIR) \ + $(shell $(LD) --version | \ + sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p') + +######################################################################### +######################################################################### + +ifneq ($(CONFIG_BOARD_SIZE_LIMIT),) +BOARD_SIZE_CHECK = \ + @actual=`wc -c $@ | awk '{print $$1}'`; \ + limit=`printf "%d" $(CONFIG_BOARD_SIZE_LIMIT)`; \ + if test $$actual -gt $$limit; then \ + echo "$@ exceeds file size limit:" >&2 ; \ + echo " limit: $$limit bytes" >&2 ; \ + echo " actual: $$actual bytes" >&2 ; \ + echo " excess: $$((actual - limit)) bytes" >&2; \ + exit 1; \ + fi +else +BOARD_SIZE_CHECK = +endif + +# Statically apply RELA-style relocations (currently arm64 only) +ifneq ($(CONFIG_STATIC_RELA),) +# $(1) is u-boot ELF, $(2) is u-boot bin, $(3) is text base +DO_STATIC_RELA = \ + start=$$($(NM) $(1) | grep __rel_dyn_start | cut -f 1 -d ' '); \ + end=$$($(NM) $(1) | grep __rel_dyn_end | cut -f 1 -d ' '); \ + tools/relocate-rela $(2) $(3) $$start $$end +else +DO_STATIC_RELA = +endif + +# Always append ALL so that arch config.mk's can add custom ones +ALL-y += u-boot.srec u-boot.bin System.map binary_size_check + +ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin +ifeq ($(CONFIG_SPL_FSL_PBL),y) +ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin +else +ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl +endif +ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin +ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img +ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin +ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb u-boot-dtb.bin +ifeq ($(CONFIG_SPL_FRAMEWORK),y) +ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img +endif +ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb +ifneq ($(CONFIG_SPL_TARGET),) +ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%) +endif +ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf + +ifneq ($(BUILD_ROM),) +ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom +endif + +# enable combined SPL/u-boot/dtb rules for tegra +ifneq ($(CONFIG_TEGRA),) +ifeq ($(CONFIG_SPL),y) +ifeq ($(CONFIG_OF_SEPARATE),y) +ALL-y += u-boot-dtb-tegra.bin +else +ALL-y += u-boot-nodtb-tegra.bin +endif +endif +endif + +# Add optional build target if defined in board/cpu/soc headers +ifneq ($(CONFIG_BUILD_TARGET),) +ALL-y += $(CONFIG_BUILD_TARGET:"%"=%) +endif + +LDFLAGS_u-boot += $(LDFLAGS_FINAL) +ifneq ($(CONFIG_SYS_TEXT_BASE),) +LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE) +endif + +quiet_cmd_objcopy = OBJCOPY $@ +cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ + +quiet_cmd_mkimage = MKIMAGE $@ +cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) + +quiet_cmd_cat = CAT $@ +cmd_cat = cat $(filter-out $(PHONY), $^) > $@ + +append = cat $(filter-out $< $(PHONY), $^) >> $@ + +quiet_cmd_pad_cat = CAT $@ +cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@ + +all: $(ALL-y) +ifneq ($(CONFIG_SYS_GENERIC_BOARD),y) + @echo "===================== WARNING ======================" + @echo "Please convert this board to generic board." + @echo "Otherwise it will be removed by the end of 2014." + @echo "See doc/README.generic-board for further information" + @echo "====================================================" +endif +ifeq ($(CONFIG_DM_I2C_COMPAT),y) + @echo "===================== WARNING ======================" + @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove" + @echo "(possibly in a subsequent patch in your series)" + @echo "before sending patches to the mailing list." + @echo "====================================================" +endif + +PHONY += dtbs +dtbs dts/dt.dtb: checkdtc u-boot + $(Q)$(MAKE) $(build)=dts dtbs + +u-boot-dtb.bin: u-boot.bin dts/dt.dtb FORCE + $(call if_changed,cat) + +%.imx: %.bin + $(Q)$(MAKE) $(build)=arch/arm/imx-common $@ + +quiet_cmd_copy = COPY $@ + cmd_copy = cp $< $@ + +u-boot.dtb: dts/dt.dtb + $(call cmd,copy) + +OBJCOPYFLAGS_u-boot.hex := -O ihex + +OBJCOPYFLAGS_u-boot.srec := -O srec + +u-boot.hex u-boot.srec: u-boot FORCE + $(call if_changed,objcopy) + +OBJCOPYFLAGS_u-boot.bin := -O binary \ + $(if $(CONFIG_X86_RESET_VECTOR),-R .start16 -R .resetvec) + +binary_size_check: u-boot.bin FORCE + @file_size=$(shell wc -c u-boot.bin | awk '{print $$1}') ; \ + map_size=$(shell cat u-boot.map | \ + awk '/_image_copy_start/ {start = $$1} /_image_binary_end/ {end = $$1} END {if (start != "" && end != "") print "ibase=16; " toupper(end) " - " toupper(start)}' \ + | sed 's/0X//g' \ + | bc); \ + if [ "" != "$$map_size" ]; then \ + if test $$map_size -ne $$file_size; then \ + echo "u-boot.map shows a binary size of $$map_size" >&2 ; \ + echo " but u-boot.bin shows $$file_size" >&2 ; \ + exit 1; \ + fi \ + fi + +u-boot.bin: u-boot FORCE + $(call if_changed,objcopy) + $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE)) + $(BOARD_SIZE_CHECK) + +u-boot.ldr: u-boot + $(CREATE_LDR_ENV) + $(LDR) -T $(CONFIG_CPU) -c $@ $< $(LDR_FLAGS) + $(BOARD_SIZE_CHECK) + +OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex + +OBJCOPYFLAGS_u-boot.ldr.srec := -I binary -O srec + +u-boot.ldr.hex u-boot.ldr.srec: u-boot.ldr FORCE + $(call if_changed,objcopy) + +# +# U-Boot entry point, needed for booting of full-blown U-Boot +# from the SPL U-Boot version. +# +ifndef CONFIG_SYS_UBOOT_START +CONFIG_SYS_UBOOT_START := 0 +endif + +MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \ + -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" + +MKIMAGEFLAGS_u-boot.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \ + -T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) + +MKIMAGEFLAGS_u-boot-spl.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \ + -T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) + +MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \ + -R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage + +u-boot.img u-boot.kwb u-boot.pbl: u-boot.bin FORCE + $(call if_changed,mkimage) + +u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +MKIMAGEFLAGS_u-boot-dtb.img = $(MKIMAGEFLAGS_u-boot.img) + +u-boot-dtb.img: u-boot-dtb.bin FORCE + $(call if_changed,mkimage) + +u-boot.sha1: u-boot.bin + tools/ubsha1 u-boot.bin + +u-boot.dis: u-boot + $(OBJDUMP) -d $< > $@ + +ifdef CONFIG_TPL +SPL_PAYLOAD := tpl/u-boot-with-tpl.bin +else +SPL_PAYLOAD := u-boot.bin +endif + +OBJCOPYFLAGS_u-boot-with-spl.bin = -I binary -O binary \ + --pad-to=$(CONFIG_SPL_PAD_TO) +u-boot-with-spl.bin: spl/u-boot-spl.bin $(SPL_PAYLOAD) FORCE + $(call if_changed,pad_cat) + +MKIMAGEFLAGS_lpc32xx-spl.img = -T lpc32xximage -a $(CONFIG_SPL_TEXT_BASE) + +lpc32xx-spl.img: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +OBJCOPYFLAGS_lpc32xx-boot-0.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) + +lpc32xx-boot-0.bin: lpc32xx-spl.img + $(call if_changed,objcopy) + +OBJCOPYFLAGS_lpc32xx-boot-1.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) + +lpc32xx-boot-1.bin: lpc32xx-spl.img + $(call if_changed,objcopy) + +lpc32xx-full.bin: lpc32xx-boot-0.bin lpc32xx-boot-1.bin u-boot.img + $(call if_changed,cat) + +CLEAN_FILES += lpc32xx-* + +OBJCOPYFLAGS_u-boot-with-tpl.bin = -I binary -O binary \ + --pad-to=$(CONFIG_TPL_PAD_TO) +tpl/u-boot-with-tpl.bin: tpl/u-boot-tpl.bin u-boot.bin FORCE + $(call if_changed,pad_cat) + +SPL: spl/u-boot-spl.bin FORCE + $(Q)$(MAKE) $(build)=arch/arm/imx-common $@ + +u-boot-with-spl.imx u-boot-with-nand-spl.imx: SPL u-boot.bin FORCE + $(Q)$(MAKE) $(build)=arch/arm/imx-common $@ + +MKIMAGEFLAGS_u-boot.ubl = -n $(UBL_CONFIG) -T ublimage -e $(CONFIG_SYS_TEXT_BASE) + +u-boot.ubl: u-boot-with-spl.bin FORCE + $(call if_changed,mkimage) + +MKIMAGEFLAGS_u-boot-spl.ais = -s -n $(if $(CONFIG_AIS_CONFIG_FILE), \ + $(srctree)/$(CONFIG_AIS_CONFIG_FILE:"%"=%),"/dev/null") \ + -T aisimage -e $(CONFIG_SPL_TEXT_BASE) +spl/u-boot-spl.ais: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +OBJCOPYFLAGS_u-boot.ais = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) +u-boot.ais: spl/u-boot-spl.ais u-boot.img FORCE + $(call if_changed,pad_cat) + +u-boot-signed.sb: u-boot.bin spl/u-boot-spl.bin + $(Q)$(MAKE) $(build)=arch/arm/cpu/arm926ejs/mxs u-boot-signed.sb +u-boot.sb: u-boot.bin spl/u-boot-spl.bin + $(Q)$(MAKE) $(build)=arch/arm/cpu/arm926ejs/mxs u-boot.sb + +# On x600 (SPEAr600) U-Boot is appended to U-Boot SPL. +# Both images are created using mkimage (crc etc), so that the ROM +# bootloader can check its integrity. Padding needs to be done to the +# SPL image (with mkimage header) and not the binary. Otherwise the resulting image +# which is loaded/copied by the ROM bootloader to SRAM doesn't fit. +# The resulting image containing both U-Boot images is called u-boot.spr +MKIMAGEFLAGS_u-boot-spl.img = -A $(ARCH) -T firmware -C none \ + -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n XLOADER +spl/u-boot-spl.img: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +OBJCOPYFLAGS_u-boot.spr = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \ + --gap-fill=0xff +u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE + $(call if_changed,pad_cat) + +MKIMAGEFLAGS_u-boot-spl.gph = -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n SPL +spl/u-boot-spl.gph: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \ + --gap-fill=0 +u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE + $(call if_changed,pad_cat) + +MKIMAGEFLAGS_u-boot-nand.gph = -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -n U-Boot +u-boot-nand.gph: u-boot.bin FORCE + $(call if_changed,mkimage) + @dd if=/dev/zero bs=8 count=1 2>/dev/null >> $@ + +# x86 uses a large ROM. We fill it with 0xff, put the 16-bit stuff (including +# reset vector) at the top, Intel ME descriptor at the bottom, and U-Boot in +# the middle. +ifneq ($(CONFIG_X86_RESET_VECTOR),) +rom: u-boot.rom FORCE + +IFDTOOL=$(objtree)/tools/ifdtool +IFDTOOL_FLAGS = -f 0:$(objtree)/u-boot.dtb +IFDTOOL_FLAGS += -m 0x$(shell $(NM) u-boot |grep _dt_ucode_base_size |cut -d' ' -f1) +IFDTOOL_FLAGS += -U $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot.bin +IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin + +ifneq ($(CONFIG_HAVE_INTEL_ME),) +IFDTOOL_ME_FLAGS = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin +IFDTOOL_ME_FLAGS += -i ME:$(srctree)/board/$(BOARDDIR)/me.bin +endif + +ifneq ($(CONFIG_HAVE_MRC),) +IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_ADDR):$(srctree)/board/$(BOARDDIR)/mrc.bin +endif + +ifneq ($(CONFIG_HAVE_FSP),) +IFDTOOL_FLAGS += -w $(CONFIG_FSP_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_FSP_FILE) +endif + +ifneq ($(CONFIG_HAVE_CMC),) +IFDTOOL_FLAGS += -w $(CONFIG_CMC_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_CMC_FILE) +endif + +ifneq ($(CONFIG_X86_OPTION_ROM_ADDR),) +IFDTOOL_FLAGS += -w $(CONFIG_X86_OPTION_ROM_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_X86_OPTION_ROM_FILE) +endif + +quiet_cmd_ifdtool = IFDTOOL $@ +cmd_ifdtool = $(IFDTOOL) -c -r $(CONFIG_ROM_SIZE) u-boot.tmp; +ifneq ($(CONFIG_HAVE_INTEL_ME),) +cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_ME_FLAGS) u-boot.tmp; +endif +cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_FLAGS) u-boot.tmp; +cmd_ifdtool += mv u-boot.tmp $@ + +u-boot.rom: u-boot-x86-16bit.bin u-boot-dtb.bin + $(call if_changed,ifdtool) + +OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec +u-boot-x86-16bit.bin: u-boot FORCE + $(call if_changed,objcopy) +endif + +ifneq ($(CONFIG_SUNXI),) +OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \ + --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff +u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin \ + u-boot$(if $(CONFIG_OF_CONTROL),-dtb,).img FORCE + $(call if_changed,pad_cat) +endif + +ifneq ($(CONFIG_TEGRA),) +OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE) +u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE + $(call if_changed,pad_cat) + +ifeq ($(CONFIG_OF_SEPARATE),y) +u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb FORCE + $(call if_changed,cat) +endif +endif + +u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE + $(call if_changed,cat) + +#Add a target to create boot binary having SPL binary in PBI format +#concatenated with u-boot binary. It is need by PowerPC SoC having +#internal SRAM <= 512KB. +MKIMAGEFLAGS_u-boot-spl.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \ + -R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage \ + -A $(ARCH) -a $(CONFIG_SPL_TEXT_BASE) + +spl/u-boot-spl.pbl: spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage) + +ifeq ($(ARCH),arm) +UBOOT_BINLOAD := u-boot.img +else +UBOOT_BINLOAD := u-boot.bin +endif + +OBJCOPYFLAGS_u-boot-with-spl-pbl.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \ + --gap-fill=0xff + +u-boot-with-spl-pbl.bin: spl/u-boot-spl.pbl $(UBOOT_BINLOAD) FORCE + $(call if_changed,pad_cat) + +# PPC4xx needs the SPL at the end of the image, since the reset vector +# is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target +# and need to introduce a new build target with the full blown U-Boot +# at the start padded up to the start of the SPL image. And then concat +# the SPL image to the end. + +OBJCOPYFLAGS_u-boot-img-spl-at-end.bin := -I binary -O binary \ + --pad-to=$(CONFIG_UBOOT_PAD_TO) --gap-fill=0xff +u-boot-img-spl-at-end.bin: u-boot.img spl/u-boot-spl.bin FORCE + $(call if_changed,pad_cat) + +# Create a new ELF from a raw binary file. This is useful for arm64 +# where static relocation needs to be performed on the raw binary, +# but certain simulators only accept an ELF file (but don't do the +# relocation). +# FIXME refactor dts/Makefile to share target/arch detection +u-boot.elf: u-boot.bin + @$(OBJCOPY) -B aarch64 -I binary -O elf64-littleaarch64 \ + $< u-boot-elf.o + @$(LD) u-boot-elf.o -o $@ \ + --defsym=_start=$(CONFIG_SYS_TEXT_BASE) \ + -Ttext=$(CONFIG_SYS_TEXT_BASE) + +# Rule to link u-boot +# May be overridden by arch/$(ARCH)/config.mk +quiet_cmd_u-boot__ ?= LD $@ + cmd_u-boot__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ + -T u-boot.lds $(u-boot-init) \ + --start-group $(u-boot-main) --end-group \ + $(PLATFORM_LIBS) -Map u-boot.map + +quiet_cmd_smap = GEN common/system_map.o +cmd_smap = \ + smap=`$(call SYSTEM_MAP,u-boot) | \ + awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \ + $(CC) $(c_flags) -DSYSTEM_MAP="\"$${smap}\"" \ + -c $(srctree)/common/system_map.c -o common/system_map.o + +u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds + $(call if_changed,u-boot__) +ifeq ($(CONFIG_KALLSYMS),y) + $(call cmd,smap) + $(call cmd,u-boot__) common/system_map.o +endif + +# The actual objects are generated when descending, +# make sure no implicit rule kicks in +$(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; + +# Handle descending into subdirectories listed in $(vmlinux-dirs) +# Preset locale variables to speed up the build process. Limit locale +# tweaks to this spot to avoid wrong language settings when running +# make menuconfig etc. +# Error messages still appears in the original language + +PHONY += $(u-boot-dirs) +$(u-boot-dirs): prepare scripts + $(Q)$(MAKE) $(build)=$@ + +tools: prepare +# The "tools" are needed early +$(filter-out tools, $(u-boot-dirs)): tools +# The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC +# is "yes"), so compile examples after U-Boot is compiled. +examples: $(filter-out examples, $(u-boot-dirs)) + +define filechk_uboot.release + echo "$(UBOOTVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" +endef + +# Store (new) UBOOTRELEASE string in include/config/uboot.release +include/config/uboot.release: include/config/auto.conf FORCE + $(call filechk,uboot.release) + + +# Things we need to do before we recursively start building the kernel +# or the modules are listed in "prepare". +# A multi level approach is used. prepareN is processed before prepareN-1. +# archprepare is used in arch Makefiles and when processed asm symlink, +# version.h and scripts_basic is processed / created. + +# Listed in dependency order +PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 + +# prepare3 is used to check if we are building in a separate output directory, +# and if so do: +# 1) Check that make has not been executed in the kernel src $(srctree) +prepare3: include/config/uboot.release +ifneq ($(KBUILD_SRC),) + @$(kecho) ' Using $(srctree) as source for U-Boot' + $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ + echo >&2 " $(srctree) is not clean, please run 'make mrproper'"; \ + echo >&2 " in the '$(srctree)' directory.";\ + /bin/false; \ + fi; +endif + +# prepare2 creates a makefile if using a separate output directory +prepare2: prepare3 outputmakefile + +prepare1: prepare2 $(version_h) $(timestamp_h) \ + include/config/auto.conf +ifeq ($(CONFIG_HAVE_GENERIC_BOARD),) +ifeq ($(CONFIG_SYS_GENERIC_BOARD),y) + @echo >&2 " Your architecture does not support generic board." + @echo >&2 " Please undefine CONFIG_SYS_GENERIC_BOARD in your board config file." + @/bin/false +endif +endif +ifeq ($(wildcard $(LDSCRIPT)),) + @echo >&2 " Could not find linker script." + @/bin/false +endif + +archprepare: prepare1 scripts_basic + +prepare0: archprepare FORCE + $(Q)$(MAKE) $(build)=. + +# All the preparing.. +prepare: prepare0 + +# Generate some files +# --------------------------------------------------------------------------- + +define filechk_version.h + (echo \#define PLAIN_VERSION \"$(UBOOTRELEASE)\"; \ + echo \#define U_BOOT_VERSION \"U-Boot \" PLAIN_VERSION; \ + echo \#define CC_VERSION_STRING \"$$($(CC) --version | head -n 1)\"; \ + echo \#define LD_VERSION_STRING \"$$($(LD) --version | head -n 1)\"; ) +endef + +define filechk_timestamp.h + (LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \ + LC_ALL=C date +'#define U_BOOT_TIME "%T"') +endef + +$(version_h): include/config/uboot.release FORCE + $(call filechk,version.h) + +$(timestamp_h): $(srctree)/Makefile FORCE + $(call filechk,timestamp.h) + +# --------------------------------------------------------------------------- + +PHONY += depend dep +depend dep: + @echo '*** Warning: make $@ is unnecessary now.' + +# --------------------------------------------------------------------------- +quiet_cmd_cpp_lds = LDS $@ +cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ + -D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $< + +u-boot.lds: $(LDSCRIPT) prepare FORCE + $(call if_changed_dep,cpp_lds) + +spl/u-boot-spl.bin: spl/u-boot-spl + @: +spl/u-boot-spl: tools prepare + $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all + +spl/sunxi-spl.bin: spl/u-boot-spl + @: + +tpl/u-boot-tpl.bin: tools prepare + $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all + +TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include) + +FIND := find +FINDFLAGS := -L + +tags ctags: + ctags -w -o ctags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \ + -name '*.[chS]' -print` + +etags: + etags -a -o etags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \ + -name '*.[chS]' -print` +cscope: + $(FIND) $(FINDFLAGS) $(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 +System.map: u-boot + @$(call SYSTEM_MAP,$<) > $@ + +checkdtc: + @if test $(call dtc-version) -lt 0104; then \ + echo '*** Your dtc is too old, please upgrade to dtc 1.4 or newer'; \ + false; \ + fi + +######################################################################### + +# ARM relocations should all be R_ARM_RELATIVE (32-bit) or +# R_AARCH64_RELATIVE (64-bit). +checkarmreloc: u-boot + @RELOC="`$(CROSS_COMPILE)readelf -r -W $< | cut -d ' ' -f 4 | \ + grep R_A | sort -u`"; \ + if test "$$RELOC" != "R_ARM_RELATIVE" -a \ + "$$RELOC" != "R_AARCH64_RELATIVE"; then \ + echo "$< contains unexpected relocations: $$RELOC"; \ + false; \ + fi + +env: scripts_basic + $(Q)$(MAKE) $(build)=tools/$@ + +tools-only: scripts_basic $(version_h) $(timestamp_h) + $(Q)$(MAKE) $(build)=tools + +tools-all: export HOST_TOOLS_ALL=y +tools-all: env tools ; + +cross_tools: export CROSS_BUILD_TOOLS=y +cross_tools: tools ; + +.PHONY : CHANGELOG +CHANGELOG: + git log --no-merges U-Boot-1_1_5.. | \ + unexpand -a | sed -e 's/\s\s*$$//' > $@ + +include/license.h: tools/bin2header COPYING + cat COPYING | gzip -9 -c | ./tools/bin2header license_gzip > include/license.h +######################################################################### + +### +# Cleaning is done on three levels. +# make clean Delete most generated files +# Leave enough to build external modules +# make mrproper Delete the current configuration, and all generated files +# make distclean Remove editor backup files, patch leftover files and the like + +# Directories & files removed with 'make clean' +CLEAN_DIRS += $(MODVERDIR) \ + $(foreach d, spl tpl, $(patsubst %,$d/%, \ + $(filter-out include, $(shell ls -1 $d 2>/dev/null)))) + +CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h \ + boot* u-boot* MLO* SPL System.map + +# Directories & files removed with 'make mrproper' +MRPROPER_DIRS += include/config include/generated spl tpl \ + .tmp_objdiff +MRPROPER_FILES += .config .config.old include/autoconf.mk* include/config.h \ + ctags etags TAGS cscope* GPATH GTAGS GRTAGS GSYMS + +# clean - Delete most, but leave enough to build external modules +# +clean: rm-dirs := $(CLEAN_DIRS) +clean: rm-files := $(CLEAN_FILES) + +clean-dirs := $(foreach f,$(u-boot-alldirs),$(if $(wildcard $(srctree)/$f/Makefile),$f)) + +clean-dirs := $(addprefix _clean_, $(clean-dirs) doc/DocBook) + +PHONY += $(clean-dirs) clean archclean +$(clean-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) + +# TODO: Do not use *.cfgtmp +clean: $(clean-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) + @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '*.ko.*' -o -name '*.su' -o -name '*.cfgtmp' \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ + -o -name '*.symtypes' -o -name 'modules.order' \ + -o -name modules.builtin -o -name '.tmp_*.o.*' \ + -o -name '*.gcno' \) -type f -print | xargs rm -f + +# mrproper - Delete all generated files, including .config +# +mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS)) +mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) +mrproper-dirs := $(addprefix _mrproper_,scripts) + +PHONY += $(mrproper-dirs) mrproper archmrproper +$(mrproper-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) + +mrproper: clean $(mrproper-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) + @rm -f arch/*/include/asm/arch + +# distclean +# +PHONY += distclean + +distclean: mrproper + @find $(srctree) $(RCS_FIND_IGNORE) \ + \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ + -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ + -o -name '.*.rej' -o -name '*%' -o -name 'core' \ + -o -name '*.pyc' \) \ + -type f -print | xargs rm -f + @rm -f boards.cfg + +backup: + F=`basename $(srctree)` ; cd .. ; \ + gtar --force-local -zcvf `LC_ALL=C date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F + +help: + @echo 'Cleaning targets:' + @echo ' clean - Remove most generated files but keep the config' + @echo ' mrproper - Remove all generated files + config + various backup files' + @echo ' distclean - mrproper + remove editor backup and patch files' + @echo '' + @echo 'Configuration targets:' + @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help + @echo '' + @echo 'Other generic targets:' + @echo ' all - Build all necessary images depending on configuration' + @echo '* u-boot - Build the bare u-boot' + @echo ' dir/ - Build all files in dir and below' + @echo ' dir/file.[oisS] - Build specified target only' + @echo ' dir/file.lst - Build specified mixed source/assembly target only' + @echo ' (requires a recent binutils and recent build (System.map))' + @echo ' tags/ctags - Generate ctags file for editors' + @echo ' etags - Generate etags file for editors' + @echo ' cscope - Generate cscope index' + @echo ' ubootrelease - Output the release version string (use with make -s)' + @echo ' ubootversion - Output the version stored in Makefile (use with make -s)' + @echo '' + @echo 'Static analysers' + @echo ' checkstack - Generate a list of stack hogs' + @echo '' + @echo 'Documentation targets:' + @$(MAKE) -f $(srctree)/doc/DocBook/Makefile dochelp + @echo '' + @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build' + @echo ' make V=2 [targets] 2 => give reason for rebuild of target' + @echo ' make O=dir [targets] Locate all output files in "dir", including .config' + @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)' + @echo ' make C=2 [targets] Force check of all c source with $$CHECK' + @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' + @echo ' make W=n [targets] Enable extra gcc checks, n=1,2,3 where' + @echo ' 1: warnings which may be relevant and do not occur too often' + @echo ' 2: warnings which occur quite often but may still be relevant' + @echo ' 3: more obscure warnings, can most likely be ignored' + @echo ' Multiple levels can be combined with W=12 or W=123' + @echo '' + @echo 'Execute "make" or "make all" to build all targets marked with [*] ' + @echo 'For further info see the ./README file' + + +# Documentation targets +# --------------------------------------------------------------------------- +%docs: scripts_basic FORCE + $(Q)$(MAKE) $(build)=scripts build_docproc + $(Q)$(MAKE) $(build)=doc/DocBook $@ + +# Dummies... +PHONY += prepare scripts +prepare: ; +scripts: ; + +endif #ifeq ($(config-targets),1) +endif #ifeq ($(mixed-targets),1) + +PHONY += checkstack ubootrelease ubootversion + +checkstack: + $(OBJDUMP) -d u-boot $$(find . -name u-boot-spl) | \ + $(PERL) $(src)/scripts/checkstack.pl $(ARCH) + +ubootrelease: + @echo "$(UBOOTVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" + +ubootversion: + @echo $(UBOOTVERSION) + +# Single targets +# --------------------------------------------------------------------------- +# Single targets are compatible with: +# - build with mixed source and output +# - build with separate output dir 'make O=...' +# - external modules +# +# target-dir => where to store outputfile +# build-dir => directory in kernel source tree to use + +ifeq ($(KBUILD_EXTMOD),) + build-dir = $(patsubst %/,%,$(dir $@)) + target-dir = $(dir $@) +else + zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) + build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) + target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) +endif + +%.s: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.i: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.o: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.lst: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.s: %.S prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.o: %.S prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.symtypes: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) + +# Modules +/: prepare scripts FORCE + $(cmd_crmodverdir) + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) +%/: prepare scripts FORCE + $(cmd_crmodverdir) + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) +%.ko: prepare scripts FORCE + $(cmd_crmodverdir) + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) $(@:.ko=.o) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost + +# FIXME Should go into a make.lib or something +# =========================================================================== + +quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs))) + cmd_rmdirs = rm -rf $(rm-dirs) + +quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))) + cmd_rmfiles = rm -f $(rm-files) + +# read all saved command lines + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + $(cmd_files): ; # Do not try to update included dependency files + include $(cmd_files) +endif + +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir +# Usage: +# $(Q)$(MAKE) $(clean)=dir +clean := -f $(srctree)/scripts/Makefile.clean obj + +endif # skip-makefile + +PHONY += FORCE +FORCE: + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY)
diff --git a/u-boot-imx/README b/u-boot-imx/README new file mode 100644 index 0000000..555f27f --- /dev/null +++ b/u-boot-imx/README
@@ -0,0 +1,6704 @@ +# +# (C) Copyright 2000 - 2013 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +Summary: +======== + +This directory contains the source code for U-Boot, a boot loader for +Embedded boards based on PowerPC, ARM, MIPS and several other +processors, which can be installed in a boot ROM and used to +initialize and test the hardware or to download and run application +code. + +The development of U-Boot is closely related to Linux: some parts of +the source code originate in the Linux source tree, we have some +header files in common, and special provision has been made to +support booting of Linux images. + +Some attention has been paid to make this software easily +configurable and extendable. For instance, all monitor commands are +implemented with the same call interface, so that it's very easy to +add new commands. Also, instead of permanently adding rarely used +code (for instance hardware test utilities) to the monitor, you can +load and run it dynamically. + + +Status: +======= + +In general, all boards for which a configuration option exists in the +Makefile have been tested to some extent and can be considered +"working". In fact, many of them are used in production systems. + +In case of problems see the CHANGELOG and CREDITS files to find out +who contributed the specific port. The boards.cfg file lists board +maintainers. + +Note: There is no CHANGELOG file in the actual U-Boot source tree; +it can be created dynamically from the Git log using: + + make CHANGELOG + + +Where to get help: +================== + +In case you have questions about, problems with or contributions for +U-Boot you should send a message to the U-Boot mailing list at +<u-boot@lists.denx.de>. There is also an archive of previous traffic +on the mailing list - please search the archive before asking FAQ's. +Please see http://lists.denx.de/pipermail/u-boot and +http://dir.gmane.org/gmane.comp.boot-loaders.u-boot + + +Where to get source code: +========================= + +The U-Boot source code is maintained in the git repository at +git://www.denx.de/git/u-boot.git ; you can browse it online at +http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=summary + +The "snapshot" links on this page allow you to download tarballs of +any version you might be interested in. Official releases are also +available for FTP download from the ftp://ftp.denx.de/pub/u-boot/ +directory. + +Pre-built (and tested) images are available from +ftp://ftp.denx.de/pub/u-boot/images/ + + +Where we come from: +=================== + +- start from 8xxrom sources +- create PPCBoot project (http://sourceforge.net/projects/ppcboot) +- clean up code +- make it easier to add custom boards +- make it possible to add other [PowerPC] CPUs +- extend functions, especially: + * Provide extended interface to Linux boot loader + * S-Record download + * network boot + * PCMCIA / CompactFlash / ATA disk / SCSI ... boot +- create ARMBoot project (http://sourceforge.net/projects/armboot) +- add other CPU families (starting with ARM) +- create U-Boot project (http://sourceforge.net/projects/u-boot) +- current project page: see http://www.denx.de/wiki/U-Boot + + +Names and Spelling: +=================== + +The "official" name of this project is "Das U-Boot". The spelling +"U-Boot" shall be used in all written text (documentation, comments +in source files etc.). Example: + + This is the README file for the U-Boot project. + +File names etc. shall be based on the string "u-boot". Examples: + + include/asm-ppc/u-boot.h + + #include <asm/u-boot.h> + +Variable names, preprocessor constants etc. shall be either based on +the string "u_boot" or on "U_BOOT". Example: + + U_BOOT_VERSION u_boot_logo + IH_OS_U_BOOT u_boot_hush_start + + +Versioning: +=========== + +Starting with the release in October 2008, the names of the releases +were changed from numerical release numbers without deeper meaning +into a time stamp based numbering. Regular releases are identified by +names consisting of the calendar year and month of the release date. +Additional fields (if present) indicate release candidates or bug fix +releases in "stable" maintenance trees. + +Examples: + U-Boot v2009.11 - Release November 2009 + U-Boot v2009.11.1 - Release 1 in version November 2009 stable tree + U-Boot v2010.09-rc1 - Release candiate 1 for September 2010 release + + +Directory Hierarchy: +==================== + +/arch Architecture specific files + /arc Files generic to ARC architecture + /cpu CPU specific files + /arc700 Files specific to ARC 700 CPUs + /lib Architecture specific library files + /arm Files generic to ARM architecture + /cpu CPU specific files + /arm720t Files specific to ARM 720 CPUs + /arm920t Files specific to ARM 920 CPUs + /at91 Files specific to Atmel AT91RM9200 CPU + /imx Files specific to Freescale MC9328 i.MX CPUs + /s3c24x0 Files specific to Samsung S3C24X0 CPUs + /arm926ejs Files specific to ARM 926 CPUs + /arm1136 Files specific to ARM 1136 CPUs + /pxa Files specific to Intel XScale PXA CPUs + /sa1100 Files specific to Intel StrongARM SA1100 CPUs + /lib Architecture specific library files + /avr32 Files generic to AVR32 architecture + /cpu CPU specific files + /lib Architecture specific library files + /blackfin Files generic to Analog Devices Blackfin architecture + /cpu CPU specific files + /lib Architecture specific library files + /m68k Files generic to m68k architecture + /cpu CPU specific files + /mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs + /mcf5227x Files specific to Freescale ColdFire MCF5227x CPUs + /mcf532x Files specific to Freescale ColdFire MCF5329 CPUs + /mcf5445x Files specific to Freescale ColdFire MCF5445x CPUs + /mcf547x_8x Files specific to Freescale ColdFire MCF547x_8x CPUs + /lib Architecture specific library files + /microblaze Files generic to microblaze architecture + /cpu CPU specific files + /lib Architecture specific library files + /mips Files generic to MIPS architecture + /cpu CPU specific files + /mips32 Files specific to MIPS32 CPUs + /mips64 Files specific to MIPS64 CPUs + /lib Architecture specific library files + /nds32 Files generic to NDS32 architecture + /cpu CPU specific files + /n1213 Files specific to Andes Technology N1213 CPUs + /lib Architecture specific library files + /nios2 Files generic to Altera NIOS2 architecture + /cpu CPU specific files + /lib Architecture specific library files + /openrisc Files generic to OpenRISC architecture + /cpu CPU specific files + /lib Architecture specific library files + /powerpc Files generic to PowerPC architecture + /cpu CPU specific files + /mpc5xx Files specific to Freescale MPC5xx CPUs + /mpc5xxx Files specific to Freescale MPC5xxx CPUs + /mpc8xx Files specific to Freescale MPC8xx CPUs + /mpc8260 Files specific to Freescale MPC8260 CPUs + /mpc85xx Files specific to Freescale MPC85xx CPUs + /ppc4xx Files specific to AMCC PowerPC 4xx CPUs + /lib Architecture specific library files + /sh Files generic to SH architecture + /cpu CPU specific files + /sh2 Files specific to sh2 CPUs + /sh3 Files specific to sh3 CPUs + /sh4 Files specific to sh4 CPUs + /lib Architecture specific library files + /sparc Files generic to SPARC architecture + /cpu CPU specific files + /leon2 Files specific to Gaisler LEON2 SPARC CPU + /leon3 Files specific to Gaisler LEON3 SPARC CPU + /lib Architecture specific library files + /x86 Files generic to x86 architecture + /cpu CPU specific files + /lib Architecture specific library files +/api Machine/arch independent API for external apps +/board Board dependent files +/common Misc architecture independent functions +/disk Code for disk drive partition handling +/doc Documentation (don't expect too much) +/drivers Commonly used device drivers +/dts Contains Makefile for building internal U-Boot fdt. +/examples Example code for standalone applications, etc. +/fs Filesystem code (cramfs, ext2, jffs2, etc.) +/include Header Files +/lib Files generic to all architectures + /libfdt Library files to support flattened device trees + /lzma Library files to support LZMA decompression + /lzo Library files to support LZO decompression +/net Networking code +/post Power On Self Test +/spl Secondary Program Loader framework +/tools Tools to build S-Record or U-Boot images, etc. + +Software Configuration: +======================= + +Configuration is usually done using C preprocessor defines; the +rationale behind that is to avoid dead code whenever possible. + +There are two classes of configuration variables: + +* Configuration _OPTIONS_: + These are selectable by the user and have names beginning with + "CONFIG_". + +* Configuration _SETTINGS_: + These depend on the hardware etc. and should not be meddled with if + you don't know what you're doing; they have names beginning with + "CONFIG_SYS_". + +Later we will add a configuration tool - probably similar to or even +identical to what's used for the Linux kernel. Right now, we have to +do the configuration by hand, which means creating some symbolic +links and editing some configuration files. We use the TQM8xxL boards +as an example here. + + +Selection of Processor Architecture and Board Type: +--------------------------------------------------- + +For all supported boards there are ready-to-use default +configurations available; just type "make <board_name>_defconfig". + +Example: For a TQM823L module type: + + cd u-boot + make TQM823L_defconfig + +For the Cogent platform, you need to specify the CPU type as well; +e.g. "make cogent_mpc8xx_defconfig". And also configure the cogent +directory according to the instructions in cogent/README. + + +Sandbox Environment: +-------------------- + +U-Boot can be built natively to run on a Linux host using the 'sandbox' +board. This allows feature development which is not board- or architecture- +specific to be undertaken on a native platform. The sandbox is also used to +run some of U-Boot's tests. + +See board/sandbox/README.sandbox for more details. + + +Board Initialisation Flow: +-------------------------- + +This is the intended start-up flow for boards. This should apply for both +SPL and U-Boot proper (i.e. they both follow the same rules). At present SPL +mostly uses a separate code path, but the funtion names and roles of each +function are the same. Some boards or architectures may not conform to this. +At least most ARM boards which use CONFIG_SPL_FRAMEWORK conform to this. + +Execution starts with start.S with three functions called during init after +that. The purpose and limitations of each is described below. + +lowlevel_init(): + - purpose: essential init to permit execution to reach board_init_f() + - no global_data or BSS + - there is no stack (ARMv7 may have one but it will soon be removed) + - must not set up SDRAM or use console + - must only do the bare minimum to allow execution to continue to + board_init_f() + - this is almost never needed + - return normally from this function + +board_init_f(): + - purpose: set up the machine ready for running board_init_r(): + i.e. SDRAM and serial UART + - global_data is available + - stack is in SRAM + - BSS is not available, so you cannot use global/static variables, + only stack variables and global_data + + Non-SPL-specific notes: + - dram_init() is called to set up DRAM. If already done in SPL this + can do nothing + + SPL-specific notes: + - you can override the entire board_init_f() function with your own + version as needed. + - preloader_console_init() can be called here in extremis + - should set up SDRAM, and anything needed to make the UART work + - these is no need to clear BSS, it will be done by crt0.S + - must return normally from this function (don't call board_init_r() + directly) + +Here the BSS is cleared. For SPL, if CONFIG_SPL_STACK_R is defined, then at +this point the stack and global_data are relocated to below +CONFIG_SPL_STACK_R_ADDR. For non-SPL, U-Boot is relocated to run at the top of +memory. + +board_init_r(): + - purpose: main execution, common code + - global_data is available + - SDRAM is available + - BSS is available, all static/global variables can be used + - execution eventually continues to main_loop() + + Non-SPL-specific notes: + - U-Boot is relocated to the top of memory and is now running from + there. + + SPL-specific notes: + - stack is optionally in SDRAM, if CONFIG_SPL_STACK_R is defined and + CONFIG_SPL_STACK_R_ADDR points into SDRAM + - preloader_console_init() can be called here - typically this is + done by defining CONFIG_SPL_BOARD_INIT and then supplying a + spl_board_init() function containing this call + - loads U-Boot or (in falcon mode) Linux + + + +Configuration Options: +---------------------- + +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 TQM823L module, all configuration settings are in +"include/configs/TQM823L.h". + + +Many of the options are named exactly as the corresponding Linux +kernel configuration options. The intention is to make it easier to +build a config tool - later. + + +The following options need to be configured: + +- CPU Type: Define exactly one, e.g. CONFIG_MPC85XX. + +- Board Type: Define exactly one, e.g. CONFIG_MPC8540ADS. + +- CPU Daughterboard Type: (if CONFIG_ATSTK1000 is defined) + Define exactly one, e.g. CONFIG_ATSTK1002 + +- CPU Module Type: (if CONFIG_COGENT is defined) + Define exactly one of + CONFIG_CMA286_60_OLD +--- FIXME --- not tested yet: + CONFIG_CMA286_60, CONFIG_CMA286_21, CONFIG_CMA286_60P, + CONFIG_CMA287_23, CONFIG_CMA287_50 + +- Motherboard Type: (if CONFIG_COGENT is defined) + Define exactly one of + CONFIG_CMA101, CONFIG_CMA102 + +- Motherboard I/O Modules: (if CONFIG_COGENT is defined) + Define one or more of + CONFIG_CMA302 + +- Motherboard Options: (if CONFIG_CMA101 or CONFIG_CMA102 are defined) + Define one or more of + CONFIG_LCD_HEARTBEAT - update a character position on + the LCD display every second with + a "rotator" |\-/|\-/ + +- Marvell Family Member + CONFIG_SYS_MVFS - define it if you want to enable + multiple fs option at one time + for marvell soc family + +- 8xx CPU Options: (if using an MPC8xx CPU) + CONFIG_8xx_GCLK_FREQ - deprecated: CPU clock if + get_gclk_freq() cannot work + e.g. if there is no 32KHz + reference PIT/RTC clock + CONFIG_8xx_OSCLK - PLL input clock (either EXTCLK + or XTAL/EXTAL) + +- 859/866/885 CPU options: (if using a MPC859 or MPC866 or MPC885 CPU): + CONFIG_SYS_8xx_CPUCLK_MIN + CONFIG_SYS_8xx_CPUCLK_MAX + CONFIG_8xx_CPUCLK_DEFAULT + See doc/README.MPC866 + + CONFIG_SYS_MEASURE_CPUCLK + + Define this to measure the actual CPU clock instead + of relying on the correctness of the configured + values. Mostly useful for board bringup to make sure + the PLL is locked at the intended frequency. Note + that this requires a (stable) reference clock (32 kHz + RTC clock or CONFIG_SYS_8XX_XIN) + + CONFIG_SYS_DELAYED_ICACHE + + Define this option if you want to enable the + ICache only when Code runs from RAM. + +- 85xx CPU Options: + CONFIG_SYS_PPC64 + + Specifies that the core is a 64-bit PowerPC implementation (implements + the "64" category of the Power ISA). This is necessary for ePAPR + compliance, among other possible reasons. + + CONFIG_SYS_FSL_TBCLK_DIV + + Defines the core time base clock divider ratio compared to the + system clock. On most PQ3 devices this is 8, on newer QorIQ + devices it can be 16 or 32. The ratio varies from SoC to Soc. + + CONFIG_SYS_FSL_PCIE_COMPAT + + Defines the string to utilize when trying to match PCIe device + tree nodes for the given platform. + + CONFIG_SYS_PPC_E500_DEBUG_TLB + + Enables a temporary TLB entry to be used during boot to work + around limitations in e500v1 and e500v2 external debugger + support. This reduces the portions of the boot code where + breakpoints and single stepping do not work. The value of this + symbol should be set to the TLB1 entry to be used for this + purpose. + + CONFIG_SYS_FSL_ERRATUM_A004510 + + Enables a workaround for erratum A004510. If set, + then CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV and + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY must be set. + + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 (optional) + + Defines one or two SoC revisions (low 8 bits of SVR) + for which the A004510 workaround should be applied. + + The rest of SVR is either not relevant to the decision + of whether the erratum is present (e.g. p2040 versus + p2041) or is implied by the build target, which controls + whether CONFIG_SYS_FSL_ERRATUM_A004510 is set. + + See Freescale App Note 4493 for more information about + this erratum. + + CONFIG_A003399_NOR_WORKAROUND + Enables a workaround for IFC erratum A003399. It is only + required during NOR boot. + + CONFIG_A008044_WORKAROUND + Enables a workaround for T1040/T1042 erratum A008044. It is only + required during NAND boot and valid for Rev 1.0 SoC revision + + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + + This is the value to write into CCSR offset 0x18600 + according to the A004510 workaround. + + CONFIG_SYS_FSL_DSP_DDR_ADDR + This value denotes start offset of DDR memory which is + connected exclusively to the DSP cores. + + CONFIG_SYS_FSL_DSP_M2_RAM_ADDR + This value denotes start offset of M2 memory + which is directly connected to the DSP core. + + CONFIG_SYS_FSL_DSP_M3_RAM_ADDR + This value denotes start offset of M3 memory which is directly + connected to the DSP core. + + CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT + This value denotes start offset of DSP CCSR space. + + CONFIG_SYS_FSL_SINGLE_SOURCE_CLK + Single Source Clock is clocking mode present in some of FSL SoC's. + In this mode, a single differential clock is used to supply + clocks to the sysclock, ddrclock and usbclock. + + CONFIG_SYS_CPC_REINIT_F + This CONFIG is defined when the CPC is configured as SRAM at the + time of U-boot entry and is required to be re-initialized. + + CONFIG_DEEP_SLEEP + Indicates this SoC supports deep sleep feature. If deep sleep is + supported, core will start to execute uboot when wakes up. + +- Generic CPU options: + CONFIG_SYS_GENERIC_GLOBAL_DATA + Defines global data is initialized in generic board board_init_f(). + If this macro is defined, global data is created and cleared in + generic board board_init_f(). Without this macro, architecture/board + should initialize global data before calling board_init_f(). + + CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN + + Defines the endianess of the CPU. Implementation of those + values is arch specific. + + CONFIG_SYS_FSL_DDR + Freescale DDR driver in use. This type of DDR controller is + found in mpc83xx, mpc85xx, mpc86xx as well as some ARM core + SoCs. + + CONFIG_SYS_FSL_DDR_ADDR + Freescale DDR memory-mapped register base. + + CONFIG_SYS_FSL_DDR_EMU + Specify emulator support for DDR. Some DDR features such as + deskew training are not available. + + CONFIG_SYS_FSL_DDRC_GEN1 + Freescale DDR1 controller. + + CONFIG_SYS_FSL_DDRC_GEN2 + Freescale DDR2 controller. + + CONFIG_SYS_FSL_DDRC_GEN3 + Freescale DDR3 controller. + + CONFIG_SYS_FSL_DDRC_GEN4 + Freescale DDR4 controller. + + CONFIG_SYS_FSL_DDRC_ARM_GEN3 + Freescale DDR3 controller for ARM-based SoCs. + + CONFIG_SYS_FSL_DDR1 + Board config to use DDR1. It can be enabled for SoCs with + Freescale DDR1 or DDR2 controllers, depending on the board + implemetation. + + CONFIG_SYS_FSL_DDR2 + Board config to use DDR2. It can be eanbeld for SoCs with + Freescale DDR2 or DDR3 controllers, depending on the board + implementation. + + CONFIG_SYS_FSL_DDR3 + Board config to use DDR3. It can be enabled for SoCs with + Freescale DDR3 or DDR3L controllers. + + CONFIG_SYS_FSL_DDR3L + Board config to use DDR3L. It can be enabled for SoCs with + DDR3L controllers. + + CONFIG_SYS_FSL_DDR4 + Board config to use DDR4. It can be enabled for SoCs with + DDR4 controllers. + + CONFIG_SYS_FSL_IFC_BE + Defines the IFC controller register space as Big Endian + + CONFIG_SYS_FSL_IFC_LE + Defines the IFC controller register space as Little Endian + + CONFIG_SYS_FSL_PBL_PBI + It enables addition of RCW (Power on reset configuration) in built image. + Please refer doc/README.pblimage for more details + + CONFIG_SYS_FSL_PBL_RCW + It adds PBI(pre-boot instructions) commands in u-boot build image. + PBI commands can be used to configure SoC before it starts the execution. + Please refer doc/README.pblimage for more details + + CONFIG_SPL_FSL_PBL + It adds a target to create boot binary having SPL binary in PBI format + concatenated with u-boot binary. + + CONFIG_SYS_FSL_DDR_BE + Defines the DDR controller register space as Big Endian + + CONFIG_SYS_FSL_DDR_LE + Defines the DDR controller register space as Little Endian + + CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY + Physical address from the view of DDR controllers. It is the + same as CONFIG_SYS_DDR_SDRAM_BASE for all Power SoCs. But + it could be different for ARM SoCs. + + CONFIG_SYS_FSL_DDR_INTLV_256B + DDR controller interleaving on 256-byte. This is a special + interleaving mode, handled by Dickens for Freescale layerscape + SoCs with ARM core. + + CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS + Number of controllers used as main memory. + + CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS + Number of controllers used for other than main memory. + + CONFIG_SYS_FSL_SEC_BE + Defines the SEC controller register space as Big Endian + + CONFIG_SYS_FSL_SEC_LE + Defines the SEC controller register space as Little Endian + +- Intel Monahans options: + CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO + + Defines the Monahans run mode to oscillator + ratio. Valid values are 8, 16, 24, 31. The core + frequency is this value multiplied by 13 MHz. + + CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO + + Defines the Monahans turbo mode to oscillator + ratio. Valid values are 1 (default if undefined) and + 2. The core frequency as calculated above is multiplied + by this value. + +- MIPS CPU options: + CONFIG_SYS_INIT_SP_OFFSET + + Offset relative to CONFIG_SYS_SDRAM_BASE for initial stack + pointer. This is needed for the temporary stack before + relocation. + + CONFIG_SYS_MIPS_CACHE_MODE + + Cache operation mode for the MIPS CPU. + See also arch/mips/include/asm/mipsregs.h. + Possible values are: + CONF_CM_CACHABLE_NO_WA + CONF_CM_CACHABLE_WA + CONF_CM_UNCACHED + CONF_CM_CACHABLE_NONCOHERENT + CONF_CM_CACHABLE_CE + CONF_CM_CACHABLE_COW + CONF_CM_CACHABLE_CUW + CONF_CM_CACHABLE_ACCELERATED + + CONFIG_SYS_XWAY_EBU_BOOTCFG + + Special option for Lantiq XWAY SoCs for booting from NOR flash. + See also arch/mips/cpu/mips32/start.S. + + CONFIG_XWAY_SWAP_BYTES + + Enable compilation of tools/xway-swap-bytes needed for Lantiq + XWAY SoCs for booting from NOR flash. The U-Boot image needs to + be swapped if a flash programmer is used. + +- ARM options: + CONFIG_SYS_EXCEPTION_VECTORS_HIGH + + Select high exception vectors of the ARM core, e.g., do not + clear the V bit of the c1 register of CP15. + + CONFIG_SYS_THUMB_BUILD + + Use this flag to build U-Boot using the Thumb instruction + set for ARM architectures. Thumb instruction set provides + better code density. For ARM architectures that support + Thumb2 this flag will result in Thumb2 code generated by + GCC. + + CONFIG_ARM_ERRATA_716044 + CONFIG_ARM_ERRATA_742230 + CONFIG_ARM_ERRATA_743622 + CONFIG_ARM_ERRATA_751472 + CONFIG_ARM_ERRATA_794072 + CONFIG_ARM_ERRATA_761320 + CONFIG_ARM_ERRATA_845369 + + If set, the workarounds for these ARM errata are applied early + during U-Boot startup. Note that these options force the + workarounds to be applied; no CPU-type/version detection + exists, unlike the similar options in the Linux kernel. Do not + set these options unless they apply! + + NOTE: The following can be machine specific errata. These + do have ability to provide rudimentary version and machine + specific checks, but expect no product checks. + CONFIG_ARM_ERRATA_430973 + CONFIG_ARM_ERRATA_454179 + CONFIG_ARM_ERRATA_621766 + CONFIG_ARM_ERRATA_798870 + +- Tegra SoC options: + CONFIG_TEGRA_SUPPORT_NON_SECURE + + Support executing U-Boot in non-secure (NS) mode. Certain + impossible actions will be skipped if the CPU is in NS mode, + such as ARM architectural timer initialization. + +- Linux Kernel Interface: + CONFIG_CLOCKS_IN_MHZ + + U-Boot stores all clock information in Hz + internally. For binary compatibility with older Linux + kernels (which expect the clocks passed in the + bd_info data to be in MHz) the environment variable + "clocks_in_mhz" can be defined so that U-Boot + converts clock data to MHZ before passing it to the + Linux kernel. + When CONFIG_CLOCKS_IN_MHZ is defined, a definition of + "clocks_in_mhz=1" is automatically included in the + default environment. + + CONFIG_MEMSIZE_IN_BYTES [relevant for MIPS only] + + When transferring memsize parameter to Linux, some versions + expect it to be in bytes, others in MB. + Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes. + + CONFIG_OF_LIBFDT + + New kernel versions are expecting firmware settings to be + passed using flattened device trees (based on open firmware + concepts). + + CONFIG_OF_LIBFDT + * New libfdt-based support + * Adds the "fdt" command + * The bootm command automatically updates the fdt + + OF_CPU - The proper name of the cpus node (only required for + MPC512X and MPC5xxx based boards). + OF_SOC - The proper name of the soc node (only required for + MPC512X and MPC5xxx based boards). + OF_TBCLK - The timebase frequency. + OF_STDOUT_PATH - The path to the console device + + boards with QUICC Engines require OF_QE to set UCC MAC + addresses + + CONFIG_OF_BOARD_SETUP + + Board code has addition modification that it wants to make + to the flat device tree before handing it off to the kernel + + CONFIG_OF_SYSTEM_SETUP + + Other code has addition modification that it wants to make + to the flat device tree before handing it off to the kernel. + This causes ft_system_setup() to be called before booting + the kernel. + + CONFIG_OF_BOOT_CPU + + This define fills in the correct boot CPU in the boot + param header, the default value is zero if undefined. + + CONFIG_OF_IDE_FIXUP + + U-Boot can detect if an IDE device is present or not. + If not, and this new config option is activated, U-Boot + removes the ATA node from the DTS before booting Linux, + so the Linux IDE driver does not probe the device and + crash. This is needed for buggy hardware (uc101) where + no pull down resistor is connected to the signal IDE5V_DD7. + + CONFIG_MACH_TYPE [relevant for ARM only][mandatory] + + This setting is mandatory for all boards that have only one + machine type and must be used to specify the machine type + number as it appears in the ARM machine registry + (see http://www.arm.linux.org.uk/developer/machines/). + Only boards that have multiple machine types supported + in a single configuration file and the machine type is + runtime discoverable, do not have to use this setting. + +- vxWorks boot parameters: + + bootvx constructs a valid bootline using the following + environments variables: bootfile, ipaddr, serverip, hostname. + It loads the vxWorks image pointed bootfile. + + CONFIG_SYS_VXWORKS_BOOT_DEVICE - The vxworks device name + CONFIG_SYS_VXWORKS_MAC_PTR - Ethernet 6 byte MA -address + CONFIG_SYS_VXWORKS_SERVERNAME - Name of the server + CONFIG_SYS_VXWORKS_BOOT_ADDR - Address of boot parameters + + CONFIG_SYS_VXWORKS_ADD_PARAMS + + Add it at the end of the bootline. E.g "u=username pw=secret" + + Note: If a "bootargs" environment is defined, it will overwride + the defaults discussed just above. + +- Cache Configuration: + CONFIG_SYS_ICACHE_OFF - Do not enable instruction cache in U-Boot + CONFIG_SYS_DCACHE_OFF - Do not enable data cache in U-Boot + CONFIG_SYS_L2CACHE_OFF- Do not enable L2 cache in U-Boot + +- Cache Configuration for ARM: + CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache + controller + CONFIG_SYS_PL310_BASE - Physical base address of PL310 + controller register space + +- Serial Ports: + CONFIG_PL010_SERIAL + + Define this if you want support for Amba PrimeCell PL010 UARTs. + + CONFIG_PL011_SERIAL + + Define this if you want support for Amba PrimeCell PL011 UARTs. + + CONFIG_PL011_CLOCK + + If you have Amba PrimeCell PL011 UARTs, set this variable to + the clock speed of the UARTs. + + CONFIG_PL01x_PORTS + + If you have Amba PrimeCell PL010 or PL011 UARTs on your board, + define this to a list of base addresses for each (supported) + port. See e.g. include/configs/versatile.h + + CONFIG_PL011_SERIAL_RLCR + + Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500) + have separate receive and transmit line control registers. Set + this variable to initialize the extra register. + + CONFIG_PL011_SERIAL_FLUSH_ON_INIT + + On some platforms (e.g. U8500) U-Boot is loaded by a second stage + boot loader that has already initialized the UART. Define this + variable to flush the UART at init time. + + CONFIG_SERIAL_HW_FLOW_CONTROL + + Define this variable to enable hw flow control in serial driver. + Current user of this option is drivers/serial/nsl16550.c driver + +- Console Interface: + Depending on board, define exactly one serial port + (like CONFIG_8xx_CONS_SMC1, CONFIG_8xx_CONS_SMC2, + CONFIG_8xx_CONS_SCC1, ...), or switch off the serial + console by defining CONFIG_8xx_CONS_NONE + + Note: if CONFIG_8xx_CONS_NONE is defined, the serial + port routines must be defined elsewhere + (i.e. serial_init(), serial_getc(), ...) + + CONFIG_CFB_CONSOLE + Enables console device for a color framebuffer. Needs following + defines (cf. smiLynxEM, i8042) + VIDEO_FB_LITTLE_ENDIAN graphic memory organisation + (default big endian) + VIDEO_HW_RECTFILL graphic chip supports + rectangle fill + (cf. smiLynxEM) + VIDEO_HW_BITBLT graphic chip supports + bit-blit (cf. smiLynxEM) + VIDEO_VISIBLE_COLS visible pixel columns + (cols=pitch) + VIDEO_VISIBLE_ROWS visible pixel rows + VIDEO_PIXEL_SIZE bytes per pixel + VIDEO_DATA_FORMAT graphic data format + (0-5, cf. cfb_console.c) + VIDEO_FB_ADRS framebuffer address + VIDEO_KBD_INIT_FCT keyboard int fct + (i.e. i8042_kbd_init()) + VIDEO_TSTC_FCT test char fct + (i.e. i8042_tstc) + VIDEO_GETC_FCT get char fct + (i.e. i8042_getc) + CONFIG_CONSOLE_CURSOR cursor drawing on/off + (requires blink timer + cf. i8042.c) + CONFIG_SYS_CONSOLE_BLINK_COUNT blink interval (cf. i8042.c) + CONFIG_CONSOLE_TIME display time/date info in + upper right corner + (requires CONFIG_CMD_DATE) + CONFIG_VIDEO_LOGO display Linux logo in + upper left corner + CONFIG_VIDEO_BMP_LOGO use bmp_logo.h instead of + linux_logo.h for logo. + Requires CONFIG_VIDEO_LOGO + CONFIG_CONSOLE_EXTRA_INFO + additional board info beside + the logo + + When CONFIG_CFB_CONSOLE_ANSI is defined, console will support + a limited number of ANSI escape sequences (cursor control, + erase functions and limited graphics rendition control). + + When CONFIG_CFB_CONSOLE is defined, video console is + default i/o. Serial console can be forced with + environment 'console=serial'. + + When CONFIG_SILENT_CONSOLE is defined, all console + messages (by U-Boot and Linux!) can be silenced with + the "silent" environment variable. See + doc/README.silent for more information. + + CONFIG_SYS_CONSOLE_BG_COL: define the backgroundcolor, default + is 0x00. + CONFIG_SYS_CONSOLE_FG_COL: define the foregroundcolor, default + is 0xa0. + +- Console Baudrate: + CONFIG_BAUDRATE - in bps + Select one of the baudrates listed in + CONFIG_SYS_BAUDRATE_TABLE, see below. + CONFIG_SYS_BRGCLK_PRESCALE, baudrate prescale + +- Console Rx buffer length + With CONFIG_SYS_SMC_RXBUFLEN it is possible to define + the maximum receive buffer length for the SMC. + This option is actual only for 82xx and 8xx possible. + If using CONFIG_SYS_SMC_RXBUFLEN also CONFIG_SYS_MAXIDLE + must be defined, to setup the maximum idle timeout for + the SMC. + +- Pre-Console Buffer: + Prior to the console being initialised (i.e. serial UART + initialised etc) all console output is silently discarded. + Defining CONFIG_PRE_CONSOLE_BUFFER will cause U-Boot to + buffer any console messages prior to the console being + initialised to a buffer of size CONFIG_PRE_CON_BUF_SZ + bytes located at CONFIG_PRE_CON_BUF_ADDR. The buffer is + a circular buffer, so if more than CONFIG_PRE_CON_BUF_SZ + bytes are output before the console is initialised, the + earlier bytes are discarded. + + 'Sane' compilers will generate smaller code if + CONFIG_PRE_CON_BUF_SZ is a power of 2 + +- Safe printf() functions + Define CONFIG_SYS_VSNPRINTF to compile in safe versions of + the printf() functions. These are defined in + include/vsprintf.h and include snprintf(), vsnprintf() and + so on. Code size increase is approximately 300-500 bytes. + If this option is not given then these functions will + silently discard their buffer size argument - this means + you are not getting any overflow checking in this case. + +- Boot Delay: CONFIG_BOOTDELAY - in seconds + Delay before automatically booting the default image; + set to -1 to disable autoboot. + set to -2 to autoboot with no delay and not check for abort + (even when CONFIG_ZERO_BOOTDELAY_CHECK is defined). + + See doc/README.autoboot for these options that + work with CONFIG_BOOTDELAY. None are required. + CONFIG_BOOT_RETRY_TIME + CONFIG_BOOT_RETRY_MIN + CONFIG_AUTOBOOT_KEYED + CONFIG_AUTOBOOT_PROMPT + CONFIG_AUTOBOOT_DELAY_STR + CONFIG_AUTOBOOT_STOP_STR + CONFIG_AUTOBOOT_DELAY_STR2 + CONFIG_AUTOBOOT_STOP_STR2 + CONFIG_ZERO_BOOTDELAY_CHECK + CONFIG_RESET_TO_RETRY + +- Autoboot Command: + CONFIG_BOOTCOMMAND + Only needed when CONFIG_BOOTDELAY is enabled; + define a command string that is automatically executed + when no character is read on the console interface + within "Boot Delay" after reset. + + CONFIG_BOOTARGS + This can be used to pass arguments to the bootm + command. The value of CONFIG_BOOTARGS goes into the + environment value "bootargs". + + CONFIG_RAMBOOT and CONFIG_NFSBOOT + The value of these goes into the environment as + "ramboot" and "nfsboot" respectively, and can be used + as a convenience, when switching between booting from + RAM and NFS. + +- Bootcount: + CONFIG_BOOTCOUNT_LIMIT + Implements a mechanism for detecting a repeating reboot + cycle, see: + http://www.denx.de/wiki/view/DULG/UBootBootCountLimit + + CONFIG_BOOTCOUNT_ENV + If no softreset save registers are found on the hardware + "bootcount" is stored in the environment. To prevent a + saveenv on all reboots, the environment variable + "upgrade_available" is used. If "upgrade_available" is + 0, "bootcount" is always 0, if "upgrade_available" is + 1 "bootcount" is incremented in the environment. + So the Userspace Applikation must set the "upgrade_available" + and "bootcount" variable to 0, if a boot was successfully. + +- Pre-Boot Commands: + CONFIG_PREBOOT + + When this option is #defined, the existence of the + environment variable "preboot" will be checked + immediately before starting the CONFIG_BOOTDELAY + countdown and/or running the auto-boot command resp. + entering interactive mode. + + This feature is especially useful when "preboot" is + automatically generated or modified. For an example + see the LWMON board specific code: here "preboot" is + modified when the user holds down a certain + combination of keys on the (special) keyboard when + booting the systems + +- Serial Download Echo Mode: + CONFIG_LOADS_ECHO + If defined to 1, all characters received during a + serial download (using the "loads" command) are + echoed back. This might be needed by some terminal + emulations (like "cu"), but may as well just take + time on others. This setting #define's the initial + value of the "loads_echo" environment variable. + +- Kgdb Serial Baudrate: (if CONFIG_CMD_KGDB is defined) + CONFIG_KGDB_BAUDRATE + Select one of the baudrates listed in + CONFIG_SYS_BAUDRATE_TABLE, see below. + +- Monitor Functions: + Monitor commands can be included or excluded + from the build by using the #include files + <config_cmd_all.h> and #undef'ing unwanted + commands, or using <config_cmd_default.h> + and augmenting with additional #define's + for wanted commands. + + The default command configuration includes all commands + except those marked below with a "*". + + CONFIG_CMD_AES AES 128 CBC encrypt/decrypt + CONFIG_CMD_ASKENV * ask for env variable + CONFIG_CMD_BDI bdinfo + CONFIG_CMD_BEDBUG * Include BedBug Debugger + CONFIG_CMD_BMP * BMP support + CONFIG_CMD_BSP * Board specific commands + CONFIG_CMD_BOOTD bootd + CONFIG_CMD_BOOTI * ARM64 Linux kernel Image support + CONFIG_CMD_CACHE * icache, dcache + CONFIG_CMD_CLK * clock command support + CONFIG_CMD_CONSOLE coninfo + CONFIG_CMD_CRC32 * crc32 + CONFIG_CMD_DATE * support for RTC, date/time... + CONFIG_CMD_DHCP * DHCP support + CONFIG_CMD_DIAG * Diagnostics + CONFIG_CMD_DS4510 * ds4510 I2C gpio commands + CONFIG_CMD_DS4510_INFO * ds4510 I2C info command + CONFIG_CMD_DS4510_MEM * ds4510 I2C eeprom/sram commansd + CONFIG_CMD_DS4510_RST * ds4510 I2C rst command + CONFIG_CMD_DTT * Digital Therm and Thermostat + CONFIG_CMD_ECHO echo arguments + CONFIG_CMD_EDITENV edit env variable + CONFIG_CMD_EEPROM * EEPROM read/write support + CONFIG_CMD_ELF * bootelf, bootvx + CONFIG_CMD_ENV_CALLBACK * display details about env callbacks + CONFIG_CMD_ENV_FLAGS * display details about env flags + CONFIG_CMD_ENV_EXISTS * check existence of env variable + CONFIG_CMD_EXPORTENV * export the environment + CONFIG_CMD_EXT2 * ext2 command support + CONFIG_CMD_EXT4 * ext4 command support + CONFIG_CMD_FS_GENERIC * filesystem commands (e.g. load, ls) + that work for multiple fs types + CONFIG_CMD_FS_UUID * Look up a filesystem UUID + CONFIG_CMD_SAVEENV saveenv + CONFIG_CMD_FDC * Floppy Disk Support + CONFIG_CMD_FAT * FAT command support + CONFIG_CMD_FLASH flinfo, erase, protect + CONFIG_CMD_FPGA FPGA device initialization support + CONFIG_CMD_FUSE * Device fuse support + CONFIG_CMD_GETTIME * Get time since boot + CONFIG_CMD_GO * the 'go' command (exec code) + CONFIG_CMD_GREPENV * search environment + CONFIG_CMD_HASH * calculate hash / digest + CONFIG_CMD_HWFLOW * RTS/CTS hw flow control + CONFIG_CMD_I2C * I2C serial bus support + CONFIG_CMD_IDE * IDE harddisk support + CONFIG_CMD_IMI iminfo + CONFIG_CMD_IMLS List all images found in NOR flash + CONFIG_CMD_IMLS_NAND * List all images found in NAND flash + CONFIG_CMD_IMMAP * IMMR dump support + CONFIG_CMD_IOTRACE * I/O tracing for debugging + CONFIG_CMD_IMPORTENV * import an environment + CONFIG_CMD_INI * import data from an ini file into the env + CONFIG_CMD_IRQ * irqinfo + CONFIG_CMD_ITEST Integer/string test of 2 values + CONFIG_CMD_JFFS2 * JFFS2 Support + CONFIG_CMD_KGDB * kgdb + CONFIG_CMD_LDRINFO * ldrinfo (display Blackfin loader) + CONFIG_CMD_LINK_LOCAL * link-local IP address auto-configuration + (169.254.*.*) + CONFIG_CMD_LOADB loadb + CONFIG_CMD_LOADS loads + CONFIG_CMD_MD5SUM * print md5 message digest + (requires CONFIG_CMD_MEMORY and CONFIG_MD5) + CONFIG_CMD_MEMINFO * Display detailed memory information + CONFIG_CMD_MEMORY md, mm, nm, mw, cp, cmp, crc, base, + loop, loopw + CONFIG_CMD_MEMTEST * mtest + CONFIG_CMD_MISC Misc functions like sleep etc + CONFIG_CMD_MMC * MMC memory mapped support + CONFIG_CMD_MII * MII utility commands + CONFIG_CMD_MTDPARTS * MTD partition support + CONFIG_CMD_NAND * NAND support + CONFIG_CMD_NET bootp, tftpboot, rarpboot + CONFIG_CMD_NFS NFS support + CONFIG_CMD_PCA953X * PCA953x I2C gpio commands + CONFIG_CMD_PCA953X_INFO * PCA953x I2C gpio info command + CONFIG_CMD_PCI * pciinfo + CONFIG_CMD_PCMCIA * PCMCIA support + CONFIG_CMD_PING * send ICMP ECHO_REQUEST to network + host + CONFIG_CMD_PORTIO * Port I/O + CONFIG_CMD_READ * Read raw data from partition + CONFIG_CMD_REGINFO * Register dump + CONFIG_CMD_RUN run command in env variable + CONFIG_CMD_SANDBOX * sb command to access sandbox features + CONFIG_CMD_SAVES * save S record dump + CONFIG_CMD_SCSI * SCSI Support + CONFIG_CMD_SDRAM * print SDRAM configuration information + (requires CONFIG_CMD_I2C) + CONFIG_CMD_SETGETDCR Support for DCR Register access + (4xx only) + CONFIG_CMD_SF * Read/write/erase SPI NOR flash + CONFIG_CMD_SHA1SUM * print sha1 memory digest + (requires CONFIG_CMD_MEMORY) + CONFIG_CMD_SOFTSWITCH * Soft switch setting command for BF60x + CONFIG_CMD_SOURCE "source" command Support + CONFIG_CMD_SPI * SPI serial bus support + CONFIG_CMD_TFTPSRV * TFTP transfer in server mode + CONFIG_CMD_TFTPPUT * TFTP put command (upload) + CONFIG_CMD_TIME * run command and report execution time (ARM specific) + CONFIG_CMD_TIMER * access to the system tick timer + CONFIG_CMD_USB * USB support + CONFIG_CMD_CDP * Cisco Discover Protocol support + CONFIG_CMD_MFSL * Microblaze FSL support + CONFIG_CMD_XIMG Load part of Multi Image + CONFIG_CMD_UUID * Generate random UUID or GUID string + + EXAMPLE: If you want all functions except of network + support you can write: + + #include "config_cmd_all.h" + #undef CONFIG_CMD_NET + + Other Commands: + fdt (flattened device tree) command: CONFIG_OF_LIBFDT + + Note: Don't enable the "icache" and "dcache" commands + (configuration option CONFIG_CMD_CACHE) unless you know + what you (and your U-Boot users) are doing. Data + cache cannot be enabled on systems like the 8xx or + 8260 (where accesses to the IMMR region must be + uncached), and it cannot be disabled on all other + systems where we (mis-) use the data cache to hold an + initial stack and some data. + + + XXX - this list needs to get updated! + +- Regular expression support: + CONFIG_REGEX + If this variable is defined, U-Boot is linked against + the SLRE (Super Light Regular Expression) library, + which adds regex support to some commands, as for + example "env grep" and "setexpr". + +- Device tree: + CONFIG_OF_CONTROL + If this variable is defined, U-Boot will use a device tree + to configure its devices, instead of relying on statically + compiled #defines in the board file. This option is + experimental and only available on a few boards. The device + tree is available in the global data as gd->fdt_blob. + + U-Boot needs to get its device tree from somewhere. This can + be done using one of the two options below: + + CONFIG_OF_EMBED + If this variable is defined, U-Boot will embed a device tree + binary in its image. This device tree file should be in the + board directory and called <soc>-<board>.dts. The binary file + is then picked up in board_init_f() and made available through + the global data structure as gd->blob. + + CONFIG_OF_SEPARATE + If this variable is defined, U-Boot will build a device tree + binary. It will be called u-boot.dtb. Architecture-specific + code will locate it at run-time. Generally this works by: + + cat u-boot.bin u-boot.dtb >image.bin + + and in fact, U-Boot does this for you, creating a file called + u-boot-dtb.bin which is useful in the common case. You can + still use the individual files if you need something more + exotic. + +- Watchdog: + CONFIG_WATCHDOG + If this variable is defined, it enables watchdog + support for the SoC. There must be support in the SoC + specific code for a watchdog. For the 8xx and 8260 + CPUs, the SIU Watchdog feature is enabled in the SYPCR + register. When supported for a specific SoC is + available, then no further board specific code should + be needed to use it. + + CONFIG_HW_WATCHDOG + When using a watchdog circuitry external to the used + SoC, then define this variable and provide board + specific code for the "hw_watchdog_reset" function. + + CONFIG_AT91_HW_WDT_TIMEOUT + specify the timeout in seconds. default 2 seconds. + +- U-Boot Version: + CONFIG_VERSION_VARIABLE + If this variable is defined, an environment variable + named "ver" is created by U-Boot showing the U-Boot + version as printed by the "version" command. + Any change to this variable will be reverted at the + next reset. + +- Real-Time Clock: + + When CONFIG_CMD_DATE is selected, the type of the RTC + has to be selected, too. Define exactly one of the + following options: + + CONFIG_RTC_MPC8xx - use internal RTC of MPC8xx + CONFIG_RTC_PCF8563 - use Philips PCF8563 RTC + CONFIG_RTC_MC13XXX - use MC13783 or MC13892 RTC + CONFIG_RTC_MC146818 - use MC146818 RTC + CONFIG_RTC_DS1307 - use Maxim, Inc. DS1307 RTC + CONFIG_RTC_DS1337 - use Maxim, Inc. DS1337 RTC + CONFIG_RTC_DS1338 - use Maxim, Inc. DS1338 RTC + CONFIG_RTC_DS1339 - use Maxim, Inc. DS1339 RTC + CONFIG_RTC_DS164x - use Dallas DS164x RTC + CONFIG_RTC_ISL1208 - use Intersil ISL1208 RTC + CONFIG_RTC_MAX6900 - use Maxim, Inc. MAX6900 RTC + CONFIG_SYS_RTC_DS1337_NOOSC - Turn off the OSC output for DS1337 + CONFIG_SYS_RV3029_TCR - enable trickle charger on + RV3029 RTC. + + Note that if the RTC uses I2C, then the I2C interface + must also be configured. See I2C Support, below. + +- GPIO Support: + CONFIG_PCA953X - use NXP's PCA953X series I2C GPIO + + The CONFIG_SYS_I2C_PCA953X_WIDTH option specifies a list of + chip-ngpio pairs that tell the PCA953X driver the number of + pins supported by a particular chip. + + Note that if the GPIO device uses I2C, then the I2C interface + must also be configured. See I2C Support, below. + +- I/O tracing: + When CONFIG_IO_TRACE is selected, U-Boot intercepts all I/O + accesses and can checksum them or write a list of them out + to memory. See the 'iotrace' command for details. This is + useful for testing device drivers since it can confirm that + the driver behaves the same way before and after a code + change. Currently this is supported on sandbox and arm. To + add support for your architecture, add '#include <iotrace.h>' + to the bottom of arch/<arch>/include/asm/io.h and test. + + Example output from the 'iotrace stats' command is below. + Note that if the trace buffer is exhausted, the checksum will + still continue to operate. + + iotrace is enabled + Start: 10000000 (buffer start address) + Size: 00010000 (buffer size) + Offset: 00000120 (current buffer offset) + Output: 10000120 (start + offset) + Count: 00000018 (number of trace records) + CRC32: 9526fb66 (CRC32 of all trace records) + +- Timestamp Support: + + When CONFIG_TIMESTAMP is selected, the timestamp + (date and time) of an image is printed by image + commands like bootm or iminfo. This option is + automatically enabled when you select CONFIG_CMD_DATE . + +- Partition Labels (disklabels) Supported: + Zero or more of the following: + CONFIG_MAC_PARTITION Apple's MacOS partition table. + CONFIG_DOS_PARTITION MS Dos partition table, traditional on the + Intel architecture, USB sticks, etc. + CONFIG_ISO_PARTITION ISO partition table, used on CDROM etc. + CONFIG_EFI_PARTITION GPT partition table, common when EFI is the + bootloader. Note 2TB partition limit; see + disk/part_efi.c + CONFIG_MTD_PARTITIONS Memory Technology Device partition table. + + If IDE or SCSI support is enabled (CONFIG_CMD_IDE or + CONFIG_CMD_SCSI) you must configure support for at + least one non-MTD partition type as well. + +- IDE Reset method: + CONFIG_IDE_RESET_ROUTINE - this is defined in several + board configurations files but used nowhere! + + CONFIG_IDE_RESET - is this is defined, IDE Reset will + be performed by calling the function + ide_set_reset(int reset) + which has to be defined in a board specific file + +- ATAPI Support: + CONFIG_ATAPI + + Set this to enable ATAPI support. + +- LBA48 Support + CONFIG_LBA48 + + Set this to enable support for disks larger than 137GB + Also look at CONFIG_SYS_64BIT_LBA. + Whithout these , LBA48 support uses 32bit variables and will 'only' + support disks up to 2.1TB. + + CONFIG_SYS_64BIT_LBA: + When enabled, makes the IDE subsystem use 64bit sector addresses. + Default is 32bit. + +- SCSI Support: + At the moment only there is only support for the + SYM53C8XX SCSI controller; define + CONFIG_SCSI_SYM53C8XX to enable it. + + CONFIG_SYS_SCSI_MAX_LUN [8], CONFIG_SYS_SCSI_MAX_SCSI_ID [7] and + CONFIG_SYS_SCSI_MAX_DEVICE [CONFIG_SYS_SCSI_MAX_SCSI_ID * + CONFIG_SYS_SCSI_MAX_LUN] can be adjusted to define the + maximum numbers of LUNs, SCSI ID's and target + devices. + CONFIG_SYS_SCSI_SYM53C8XX_CCF to fix clock timing (80Mhz) + + The environment variable 'scsidevs' is set to the number of + SCSI devices found during the last scan. + +- NETWORK Support (PCI): + CONFIG_E1000 + Support for Intel 8254x/8257x gigabit chips. + + CONFIG_E1000_SPI + Utility code for direct access to the SPI bus on Intel 8257x. + This does not do anything useful unless you set at least one + of CONFIG_CMD_E1000 or CONFIG_E1000_SPI_GENERIC. + + CONFIG_E1000_SPI_GENERIC + Allow generic access to the SPI bus on the Intel 8257x, for + example with the "sspi" command. + + CONFIG_CMD_E1000 + Management command for E1000 devices. When used on devices + with SPI support you can reprogram the EEPROM from U-Boot. + + CONFIG_E1000_FALLBACK_MAC + default MAC for empty EEPROM after production. + + CONFIG_EEPRO100 + Support for Intel 82557/82559/82559ER chips. + Optional CONFIG_EEPRO100_SROM_WRITE enables EEPROM + write routine for first time initialisation. + + CONFIG_TULIP + Support for Digital 2114x chips. + Optional CONFIG_TULIP_SELECT_MEDIA for board specific + modem chip initialisation (KS8761/QS6611). + + CONFIG_NATSEMI + Support for National dp83815 chips. + + CONFIG_NS8382X + Support for National dp8382[01] gigabit chips. + +- NETWORK Support (other): + + CONFIG_DRIVER_AT91EMAC + Support for AT91RM9200 EMAC. + + CONFIG_RMII + Define this to use reduced MII inteface + + CONFIG_DRIVER_AT91EMAC_QUIET + If this defined, the driver is quiet. + The driver doen't show link status messages. + + CONFIG_CALXEDA_XGMAC + Support for the Calxeda XGMAC device + + CONFIG_LAN91C96 + Support for SMSC's LAN91C96 chips. + + CONFIG_LAN91C96_BASE + Define this to hold the physical address + of the LAN91C96's I/O space + + CONFIG_LAN91C96_USE_32_BIT + Define this to enable 32 bit addressing + + CONFIG_SMC91111 + Support for SMSC's LAN91C111 chip + + CONFIG_SMC91111_BASE + Define this to hold the physical address + of the device (I/O space) + + CONFIG_SMC_USE_32_BIT + Define this if data bus is 32 bits + + CONFIG_SMC_USE_IOFUNCS + Define this to use i/o functions instead of macros + (some hardware wont work with macros) + + CONFIG_DRIVER_TI_EMAC + Support for davinci emac + + CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT + Define this if you have more then 3 PHYs. + + CONFIG_FTGMAC100 + Support for Faraday's FTGMAC100 Gigabit SoC Ethernet + + CONFIG_FTGMAC100_EGIGA + Define this to use GE link update with gigabit PHY. + Define this if FTGMAC100 is connected to gigabit PHY. + If your system has 10/100 PHY only, it might not occur + wrong behavior. Because PHY usually return timeout or + useless data when polling gigabit status and gigabit + control registers. This behavior won't affect the + correctnessof 10/100 link speed update. + + CONFIG_SMC911X + Support for SMSC's LAN911x and LAN921x chips + + CONFIG_SMC911X_BASE + Define this to hold the physical address + of the device (I/O space) + + CONFIG_SMC911X_32_BIT + Define this if data bus is 32 bits + + CONFIG_SMC911X_16_BIT + Define this if data bus is 16 bits. If your processor + automatically converts one 32 bit word to two 16 bit + words you may also try CONFIG_SMC911X_32_BIT. + + CONFIG_SH_ETHER + Support for Renesas on-chip Ethernet controller + + CONFIG_SH_ETHER_USE_PORT + Define the number of ports to be used + + CONFIG_SH_ETHER_PHY_ADDR + Define the ETH PHY's address + + CONFIG_SH_ETHER_CACHE_WRITEBACK + If this option is set, the driver enables cache flush. + +- PWM Support: + CONFIG_PWM_IMX + Support for PWM modul on the imx6. + +- TPM Support: + CONFIG_TPM + Support TPM devices. + + CONFIG_TPM_TIS_I2C + Support for i2c bus TPM devices. Only one device + per system is supported at this time. + + CONFIG_TPM_TIS_I2C_BUS_NUMBER + Define the the i2c bus number for the TPM device + + CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS + Define the TPM's address on the i2c bus + + CONFIG_TPM_TIS_I2C_BURST_LIMITATION + Define the burst count bytes upper limit + + CONFIG_TPM_ATMEL_TWI + Support for Atmel TWI TPM device. Requires I2C support. + + CONFIG_TPM_TIS_LPC + Support for generic parallel port TPM devices. Only one device + per system is supported at this time. + + CONFIG_TPM_TIS_BASE_ADDRESS + Base address where the generic TPM device is mapped + to. Contemporary x86 systems usually map it at + 0xfed40000. + + CONFIG_CMD_TPM + Add tpm monitor functions. + Requires CONFIG_TPM. If CONFIG_TPM_AUTH_SESSIONS is set, also + provides monitor access to authorized functions. + + CONFIG_TPM + Define this to enable the TPM support library which provides + functional interfaces to some TPM commands. + Requires support for a TPM device. + + CONFIG_TPM_AUTH_SESSIONS + Define this to enable authorized functions in the TPM library. + Requires CONFIG_TPM and CONFIG_SHA1. + +- USB Support: + At the moment only the UHCI host controller is + supported (PIP405, MIP405, MPC5200); define + CONFIG_USB_UHCI to enable it. + define CONFIG_USB_KEYBOARD to enable the USB Keyboard + and define CONFIG_USB_STORAGE to enable the USB + storage devices. + Note: + Supported are USB Keyboards and USB Floppy drives + (TEAC FD-05PUB). + MPC5200 USB requires additional defines: + CONFIG_USB_CLOCK + for 528 MHz Clock: 0x0001bbbb + CONFIG_PSC3_USB + for USB on PSC3 + CONFIG_USB_CONFIG + for differential drivers: 0x00001000 + for single ended drivers: 0x00005000 + for differential drivers on PSC3: 0x00000100 + for single ended drivers on PSC3: 0x00004100 + CONFIG_SYS_USB_EVENT_POLL + May be defined to allow interrupt polling + instead of using asynchronous interrupts + + CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the + txfilltuning field in the EHCI controller on reset. + + CONFIG_USB_DWC2_REG_ADDR the physical CPU address of the DWC2 + HW module registers. + +- USB Device: + Define the below if you wish to use the USB console. + Once firmware is rebuilt from a serial console issue the + command "setenv stdin usbtty; setenv stdout usbtty" and + attach your USB cable. The Unix command "dmesg" should print + it has found a new device. The environment variable usbtty + can be set to gserial or cdc_acm to enable your device to + appear to a USB host as a Linux gserial device or a + Common Device Class Abstract Control Model serial device. + If you select usbtty = gserial you should be able to enumerate + a Linux host by + # modprobe usbserial vendor=0xVendorID product=0xProductID + else if using cdc_acm, simply setting the environment + variable usbtty to be cdc_acm should suffice. The following + might be defined in YourBoardName.h + + CONFIG_USB_DEVICE + Define this to build a UDC device + + CONFIG_USB_TTY + Define this to have a tty type of device available to + talk to the UDC device + + CONFIG_USBD_HS + Define this to enable the high speed support for usb + device and usbtty. If this feature is enabled, a routine + int is_usbd_high_speed(void) + also needs to be defined by the driver to dynamically poll + whether the enumeration has succeded at high speed or full + speed. + + CONFIG_SYS_CONSOLE_IS_IN_ENV + Define this if you want stdin, stdout &/or stderr to + be set to usbtty. + + mpc8xx: + CONFIG_SYS_USB_EXTC_CLK 0xBLAH + Derive USB clock from external clock "blah" + - CONFIG_SYS_USB_EXTC_CLK 0x02 + + CONFIG_SYS_USB_BRG_CLK 0xBLAH + Derive USB clock from brgclk + - CONFIG_SYS_USB_BRG_CLK 0x04 + + If you have a USB-IF assigned VendorID then you may wish to + define your own vendor specific values either in BoardName.h + or directly in usbd_vendor_info.h. If you don't define + CONFIG_USBD_MANUFACTURER, CONFIG_USBD_PRODUCT_NAME, + CONFIG_USBD_VENDORID and CONFIG_USBD_PRODUCTID, then U-Boot + should pretend to be a Linux device to it's target host. + + CONFIG_USBD_MANUFACTURER + Define this string as the name of your company for + - CONFIG_USBD_MANUFACTURER "my company" + + CONFIG_USBD_PRODUCT_NAME + Define this string as the name of your product + - CONFIG_USBD_PRODUCT_NAME "acme usb device" + + CONFIG_USBD_VENDORID + Define this as your assigned Vendor ID from the USB + Implementors Forum. This *must* be a genuine Vendor ID + to avoid polluting the USB namespace. + - CONFIG_USBD_VENDORID 0xFFFF + + CONFIG_USBD_PRODUCTID + Define this as the unique Product ID + for your device + - CONFIG_USBD_PRODUCTID 0xFFFF + +- ULPI Layer Support: + The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via + the generic ULPI layer. The generic layer accesses the ULPI PHY + via the platform viewport, so you need both the genric layer and + the viewport enabled. Currently only Chipidea/ARC based + viewport is supported. + To enable the ULPI layer support, define CONFIG_USB_ULPI and + CONFIG_USB_ULPI_VIEWPORT in your board configuration file. + If your ULPI phy needs a different reference clock than the + standard 24 MHz then you have to define CONFIG_ULPI_REF_CLK to + the appropriate value in Hz. + +- MMC Support: + The MMC controller on the Intel PXA is supported. To + enable this define CONFIG_MMC. The MMC can be + accessed from the boot prompt by mapping the device + to physical memory similar to flash. Command line is + enabled with CONFIG_CMD_MMC. The MMC driver also works with + the FAT fs. This is enabled with CONFIG_CMD_FAT. + + CONFIG_SH_MMCIF + Support for Renesas on-chip MMCIF controller + + CONFIG_SH_MMCIF_ADDR + Define the base address of MMCIF registers + + CONFIG_SH_MMCIF_CLK + Define the clock frequency for MMCIF + + CONFIG_GENERIC_MMC + Enable the generic MMC driver + + CONFIG_SUPPORT_EMMC_BOOT + Enable some additional features of the eMMC boot partitions. + + CONFIG_SUPPORT_EMMC_RPMB + Enable the commands for reading, writing and programming the + key for the Replay Protection Memory Block partition in eMMC. + +- USB Device Firmware Update (DFU) class support: + CONFIG_DFU_FUNCTION + This enables the USB portion of the DFU USB class + + CONFIG_CMD_DFU + This enables the command "dfu" which is used to have + U-Boot create a DFU class device via USB. This command + requires that the "dfu_alt_info" environment variable be + set and define the alt settings to expose to the host. + + CONFIG_DFU_MMC + This enables support for exposing (e)MMC devices via DFU. + + CONFIG_DFU_NAND + This enables support for exposing NAND devices via DFU. + + CONFIG_DFU_RAM + This enables support for exposing RAM via DFU. + Note: DFU spec refer to non-volatile memory usage, but + allow usages beyond the scope of spec - here RAM usage, + one that would help mostly the developer. + + CONFIG_SYS_DFU_DATA_BUF_SIZE + Dfu transfer uses a buffer before writing data to the + raw storage device. Make the size (in bytes) of this buffer + configurable. The size of this buffer is also configurable + through the "dfu_bufsiz" environment variable. + + CONFIG_SYS_DFU_MAX_FILE_SIZE + When updating files rather than the raw storage device, + we use a static buffer to copy the file into and then write + the buffer once we've been given the whole file. Define + this to the maximum filesize (in bytes) for the buffer. + Default is 4 MiB if undefined. + + DFU_DEFAULT_POLL_TIMEOUT + Poll timeout [ms], is the timeout a device can send to the + host. The host must wait for this timeout before sending + a subsequent DFU_GET_STATUS request to the device. + + DFU_MANIFEST_POLL_TIMEOUT + Poll timeout [ms], which the device sends to the host when + entering dfuMANIFEST state. Host waits this timeout, before + sending again an USB request to the device. + +- USB Device Android Fastboot support: + CONFIG_CMD_FASTBOOT + This enables the command "fastboot" which enables the Android + fastboot mode for the platform's USB device. Fastboot is a USB + protocol for downloading images, flashing and device control + used on Android devices. + See doc/README.android-fastboot for more information. + + CONFIG_ANDROID_BOOT_IMAGE + This enables support for booting images which use the Android + image format header. + + CONFIG_USB_FASTBOOT_BUF_ADDR + The fastboot protocol requires a large memory buffer for + downloads. Define this to the starting RAM address to use for + downloaded images. + + CONFIG_USB_FASTBOOT_BUF_SIZE + The fastboot protocol requires a large memory buffer for + downloads. This buffer should be as large as possible for a + platform. Define this to the size available RAM for fastboot. + + CONFIG_FASTBOOT_FLASH + The fastboot protocol includes a "flash" command for writing + the downloaded image to a non-volatile storage device. Define + this to enable the "fastboot flash" command. + + CONFIG_FASTBOOT_FLASH_MMC_DEV + The fastboot "flash" command requires additional information + regarding the non-volatile storage device. Define this to + the eMMC device that fastboot should use to store the image. + + CONFIG_FASTBOOT_GPT_NAME + The fastboot "flash" command supports writing the downloaded + image to the Protective MBR and the Primary GUID Partition + Table. (Additionally, this downloaded image is post-processed + to generate and write the Backup GUID Partition Table.) + This occurs when the specified "partition name" on the + "fastboot flash" command line matches this value. + Default is GPT_ENTRY_NAME (currently "gpt") if undefined. + +- Journaling Flash filesystem support: + CONFIG_JFFS2_NAND, CONFIG_JFFS2_NAND_OFF, CONFIG_JFFS2_NAND_SIZE, + CONFIG_JFFS2_NAND_DEV + Define these for a default partition on a NAND device + + CONFIG_SYS_JFFS2_FIRST_SECTOR, + CONFIG_SYS_JFFS2_FIRST_BANK, CONFIG_SYS_JFFS2_NUM_BANKS + Define these for a default partition on a NOR device + + CONFIG_SYS_JFFS_CUSTOM_PART + Define this to create an own partition. You have to provide a + function struct part_info* jffs2_part_info(int part_num) + + If you define only one JFFS2 partition you may also want to + #define CONFIG_SYS_JFFS_SINGLE_PART 1 + to disable the command chpart. This is the default when you + have not defined a custom partition + +- FAT(File Allocation Table) filesystem write function support: + CONFIG_FAT_WRITE + + Define this to enable support for saving memory data as a + file in FAT formatted partition. + + This will also enable the command "fatwrite" enabling the + user to write files to FAT. + +CBFS (Coreboot Filesystem) support + CONFIG_CMD_CBFS + + Define this to enable support for reading from a Coreboot + filesystem. Available commands are cbfsinit, cbfsinfo, cbfsls + and cbfsload. + +- FAT(File Allocation Table) filesystem cluster size: + CONFIG_FS_FAT_MAX_CLUSTSIZE + + Define the max cluster size for fat operations else + a default value of 65536 will be defined. + +- Keyboard Support: + CONFIG_ISA_KEYBOARD + + Define this to enable standard (PC-Style) keyboard + support + + CONFIG_I8042_KBD + Standard PC keyboard driver with US (is default) and + GERMAN key layout (switch via environment 'keymap=de') support. + Export function i8042_kbd_init, i8042_tstc and i8042_getc + for cfb_console. Supports cursor blinking. + + CONFIG_CROS_EC_KEYB + Enables a Chrome OS keyboard using the CROS_EC interface. + This uses CROS_EC to communicate with a second microcontroller + which provides key scans on request. + +- Video support: + CONFIG_VIDEO + + Define this to enable video support (for output to + video). + + CONFIG_VIDEO_CT69000 + + Enable Chips & Technologies 69000 Video chip + + CONFIG_VIDEO_SMI_LYNXEM + Enable Silicon Motion SMI 712/710/810 Video chip. The + video output is selected via environment 'videoout' + (1 = LCD and 2 = CRT). If videoout is undefined, CRT is + assumed. + + For the CT69000 and SMI_LYNXEM drivers, videomode is + selected via environment 'videomode'. Two different ways + are possible: + - "videomode=num" 'num' is a standard LiLo mode numbers. + Following standard modes are supported (* is default): + + Colors 640x480 800x600 1024x768 1152x864 1280x1024 + -------------+--------------------------------------------- + 8 bits | 0x301* 0x303 0x305 0x161 0x307 + 15 bits | 0x310 0x313 0x316 0x162 0x319 + 16 bits | 0x311 0x314 0x317 0x163 0x31A + 24 bits | 0x312 0x315 0x318 ? 0x31B + -------------+--------------------------------------------- + (i.e. setenv videomode 317; saveenv; reset;) + + - "videomode=bootargs" all the video parameters are parsed + from the bootargs. (See drivers/video/videomodes.c) + + + CONFIG_VIDEO_SED13806 + Enable Epson SED13806 driver. This driver supports 8bpp + and 16bpp modes defined by CONFIG_VIDEO_SED13806_8BPP + or CONFIG_VIDEO_SED13806_16BPP + + CONFIG_FSL_DIU_FB + Enable the Freescale DIU video driver. Reference boards for + SOCs that have a DIU should define this macro to enable DIU + support, and should also define these other macros: + + CONFIG_SYS_DIU_ADDR + CONFIG_VIDEO + CONFIG_CMD_BMP + CONFIG_CFB_CONSOLE + CONFIG_VIDEO_SW_CURSOR + CONFIG_VGA_AS_SINGLE_DEVICE + CONFIG_VIDEO_LOGO + CONFIG_VIDEO_BMP_LOGO + + The DIU driver will look for the 'video-mode' environment + variable, and if defined, enable the DIU as a console during + boot. See the documentation file README.video for a + description of this variable. + + CONFIG_VIDEO_VGA + + Enable the VGA video / BIOS for x86. The alternative if you + are using coreboot is to use the coreboot frame buffer + driver. + + +- Keyboard Support: + CONFIG_KEYBOARD + + Define this to enable a custom keyboard support. + This simply calls drv_keyboard_init() which must be + defined in your board-specific files. + The only board using this so far is RBC823. + +- LCD Support: CONFIG_LCD + + Define this to enable LCD support (for output to LCD + display); also select one of the supported displays + by defining one of these: + + CONFIG_ATMEL_LCD: + + HITACHI TX09D70VM1CCA, 3.5", 240x320. + + CONFIG_NEC_NL6448AC33: + + NEC NL6448AC33-18. Active, color, single scan. + + CONFIG_NEC_NL6448BC20 + + NEC NL6448BC20-08. 6.5", 640x480. + Active, color, single scan. + + CONFIG_NEC_NL6448BC33_54 + + NEC NL6448BC33-54. 10.4", 640x480. + Active, color, single scan. + + CONFIG_SHARP_16x9 + + Sharp 320x240. Active, color, single scan. + It isn't 16x9, and I am not sure what it is. + + CONFIG_SHARP_LQ64D341 + + Sharp LQ64D341 display, 640x480. + Active, color, single scan. + + CONFIG_HLD1045 + + HLD1045 display, 640x480. + Active, color, single scan. + + CONFIG_OPTREX_BW + + Optrex CBL50840-2 NF-FW 99 22 M5 + or + Hitachi LMG6912RPFC-00T + or + Hitachi SP14Q002 + + 320x240. Black & white. + + Normally display is black on white background; define + CONFIG_SYS_WHITE_ON_BLACK to get it inverted. + + CONFIG_LCD_ALIGNMENT + + Normally the LCD is page-aligned (typically 4KB). If this is + defined then the LCD will be aligned to this value instead. + For ARM it is sometimes useful to use MMU_SECTION_SIZE + here, since it is cheaper to change data cache settings on + a per-section basis. + + CONFIG_CONSOLE_SCROLL_LINES + + When the console need to be scrolled, this is the number of + lines to scroll by. It defaults to 1. Increasing this makes + the console jump but can help speed up operation when scrolling + is slow. + + CONFIG_LCD_BMP_RLE8 + + Support drawing of RLE8-compressed bitmaps on the LCD. + + CONFIG_I2C_EDID + + Enables an 'i2c edid' command which can read EDID + information over I2C from an attached LCD display. + +- Splash Screen Support: CONFIG_SPLASH_SCREEN + + If this option is set, the environment is checked for + a variable "splashimage". If found, the usual display + of logo, copyright and system information on the LCD + is suppressed and the BMP image at the address + specified in "splashimage" is loaded instead. The + console is redirected to the "nulldev", too. This + allows for a "silent" boot where a splash screen is + loaded very quickly after power-on. + + CONFIG_SPLASHIMAGE_GUARD + + If this option is set, then U-Boot will prevent the environment + variable "splashimage" from being set to a problematic address + (see README.displaying-bmps). + This option is useful for targets where, due to alignment + restrictions, an improperly aligned BMP image will cause a data + abort. If you think you will not have problems with unaligned + accesses (for example because your toolchain prevents them) + there is no need to set this option. + + CONFIG_SPLASH_SCREEN_ALIGN + + If this option is set the splash image can be freely positioned + on the screen. Environment variable "splashpos" specifies the + position as "x,y". If a positive number is given it is used as + number of pixel from left/top. If a negative number is given it + is used as number of pixel from right/bottom. You can also + specify 'm' for centering the image. + + Example: + setenv splashpos m,m + => image at center of screen + + setenv splashpos 30,20 + => image at x = 30 and y = 20 + + setenv splashpos -10,m + => vertically centered image + at x = dspWidth - bmpWidth - 9 + +- Gzip compressed BMP image support: CONFIG_VIDEO_BMP_GZIP + + If this option is set, additionally to standard BMP + images, gzipped BMP images can be displayed via the + splashscreen support or the bmp command. + +- Run length encoded BMP image (RLE8) support: CONFIG_VIDEO_BMP_RLE8 + + If this option is set, 8-bit RLE compressed BMP images + can be displayed via the splashscreen support or the + bmp command. + +- Do compressing for memory range: + CONFIG_CMD_ZIP + + If this option is set, it would use zlib deflate method + to compress the specified memory at its best effort. + +- Compression support: + CONFIG_GZIP + + Enabled by default to support gzip compressed images. + + CONFIG_BZIP2 + + If this option is set, support for bzip2 compressed + images is included. If not, only uncompressed and gzip + compressed images are supported. + + NOTE: the bzip2 algorithm requires a lot of RAM, so + the malloc area (as defined by CONFIG_SYS_MALLOC_LEN) should + be at least 4MB. + + CONFIG_LZMA + + If this option is set, support for lzma compressed + images is included. + + Note: The LZMA algorithm adds between 2 and 4KB of code and it + requires an amount of dynamic memory that is given by the + formula: + + (1846 + 768 << (lc + lp)) * sizeof(uint16) + + Where lc and lp stand for, respectively, Literal context bits + and Literal pos bits. + + This value is upper-bounded by 14MB in the worst case. Anyway, + for a ~4MB large kernel image, we have lc=3 and lp=0 for a + total amount of (1846 + 768 << (3 + 0)) * 2 = ~41KB... that is + a very small buffer. + + Use the lzmainfo tool to determinate the lc and lp values and + then calculate the amount of needed dynamic memory (ensuring + the appropriate CONFIG_SYS_MALLOC_LEN value). + + CONFIG_LZO + + If this option is set, support for LZO compressed images + is included. + +- MII/PHY support: + CONFIG_PHY_ADDR + + The address of PHY on MII bus. + + CONFIG_PHY_CLOCK_FREQ (ppc4xx) + + The clock frequency of the MII bus + + CONFIG_PHY_GIGE + + If this option is set, support for speed/duplex + detection of gigabit PHY is included. + + CONFIG_PHY_RESET_DELAY + + Some PHY like Intel LXT971A need extra delay after + reset before any MII register access is possible. + For such PHY, set this option to the usec delay + required. (minimum 300usec for LXT971A) + + CONFIG_PHY_CMD_DELAY (ppc4xx) + + Some PHY like Intel LXT971A need extra delay after + command issued before MII status register can be read + +- Ethernet address: + CONFIG_ETHADDR + CONFIG_ETH1ADDR + CONFIG_ETH2ADDR + CONFIG_ETH3ADDR + CONFIG_ETH4ADDR + CONFIG_ETH5ADDR + + Define a default value for Ethernet address to use + for the respective Ethernet interface, in case this + is not determined automatically. + +- IP address: + CONFIG_IPADDR + + Define a default value for the IP address to use for + the default Ethernet interface, in case this is not + determined through e.g. bootp. + (Environment variable "ipaddr") + +- Server IP address: + CONFIG_SERVERIP + + Defines a default value for the IP address of a TFTP + server to contact when using the "tftboot" command. + (Environment variable "serverip") + + CONFIG_KEEP_SERVERADDR + + Keeps the server's MAC address, in the env 'serveraddr' + for passing to bootargs (like Linux's netconsole option) + +- Gateway IP address: + CONFIG_GATEWAYIP + + Defines a default value for the IP address of the + default router where packets to other networks are + sent to. + (Environment variable "gatewayip") + +- Subnet mask: + CONFIG_NETMASK + + Defines a default value for the subnet mask (or + routing prefix) which is used to determine if an IP + address belongs to the local subnet or needs to be + forwarded through a router. + (Environment variable "netmask") + +- Multicast TFTP Mode: + CONFIG_MCAST_TFTP + + Defines whether you want to support multicast TFTP as per + rfc-2090; for example to work with atftp. Lets lots of targets + tftp down the same boot image concurrently. Note: the Ethernet + driver in use must provide a function: mcast() to join/leave a + multicast group. + +- BOOTP Recovery Mode: + CONFIG_BOOTP_RANDOM_DELAY + + If you have many targets in a network that try to + boot using BOOTP, you may want to avoid that all + systems send out BOOTP requests at precisely the same + moment (which would happen for instance at recovery + from a power failure, when all systems will try to + boot, thus flooding the BOOTP server. Defining + CONFIG_BOOTP_RANDOM_DELAY causes a random delay to be + inserted before sending out BOOTP requests. The + following delays are inserted then: + + 1st BOOTP request: delay 0 ... 1 sec + 2nd BOOTP request: delay 0 ... 2 sec + 3rd BOOTP request: delay 0 ... 4 sec + 4th and following + BOOTP requests: delay 0 ... 8 sec + + CONFIG_BOOTP_ID_CACHE_SIZE + + BOOTP packets are uniquely identified using a 32-bit ID. The + server will copy the ID from client requests to responses and + U-Boot will use this to determine if it is the destination of + an incoming response. Some servers will check that addresses + aren't in use before handing them out (usually using an ARP + ping) and therefore take up to a few hundred milliseconds to + respond. Network congestion may also influence the time it + takes for a response to make it back to the client. If that + time is too long, U-Boot will retransmit requests. In order + to allow earlier responses to still be accepted after these + retransmissions, U-Boot's BOOTP client keeps a small cache of + IDs. The CONFIG_BOOTP_ID_CACHE_SIZE controls the size of this + cache. The default is to keep IDs for up to four outstanding + requests. Increasing this will allow U-Boot to accept offers + from a BOOTP client in networks with unusually high latency. + +- DHCP Advanced Options: + You can fine tune the DHCP functionality by defining + CONFIG_BOOTP_* symbols: + + CONFIG_BOOTP_SUBNETMASK + CONFIG_BOOTP_GATEWAY + CONFIG_BOOTP_HOSTNAME + CONFIG_BOOTP_NISDOMAIN + CONFIG_BOOTP_BOOTPATH + CONFIG_BOOTP_BOOTFILESIZE + CONFIG_BOOTP_DNS + CONFIG_BOOTP_DNS2 + CONFIG_BOOTP_SEND_HOSTNAME + CONFIG_BOOTP_NTPSERVER + CONFIG_BOOTP_TIMEOFFSET + CONFIG_BOOTP_VENDOREX + CONFIG_BOOTP_MAY_FAIL + + CONFIG_BOOTP_SERVERIP - TFTP server will be the serverip + environment variable, not the BOOTP server. + + CONFIG_BOOTP_MAY_FAIL - If the DHCP server is not found + after the configured retry count, the call will fail + instead of starting over. This can be used to fail over + to Link-local IP address configuration if the DHCP server + is not available. + + CONFIG_BOOTP_DNS2 - If a DHCP client requests the DNS + serverip from a DHCP server, it is possible that more + than one DNS serverip is offered to the client. + If CONFIG_BOOTP_DNS2 is enabled, the secondary DNS + serverip will be stored in the additional environment + variable "dnsip2". The first DNS serverip is always + stored in the variable "dnsip", when CONFIG_BOOTP_DNS + is defined. + + CONFIG_BOOTP_SEND_HOSTNAME - Some DHCP servers are capable + to do a dynamic update of a DNS server. To do this, they + need the hostname of the DHCP requester. + If CONFIG_BOOTP_SEND_HOSTNAME is defined, the content + of the "hostname" environment variable is passed as + option 12 to the DHCP server. + + CONFIG_BOOTP_DHCP_REQUEST_DELAY + + A 32bit value in microseconds for a delay between + receiving a "DHCP Offer" and sending the "DHCP Request". + This fixes a problem with certain DHCP servers that don't + respond 100% of the time to a "DHCP request". E.g. On an + AT91RM9200 processor running at 180MHz, this delay needed + to be *at least* 15,000 usec before a Windows Server 2003 + DHCP server would reply 100% of the time. I recommend at + least 50,000 usec to be safe. The alternative is to hope + that one of the retries will be successful but note that + the DHCP timeout and retry process takes a longer than + this delay. + + - Link-local IP address negotiation: + Negotiate with other link-local clients on the local network + for an address that doesn't require explicit configuration. + This is especially useful if a DHCP server cannot be guaranteed + to exist in all environments that the device must operate. + + See doc/README.link-local for more information. + + - CDP Options: + CONFIG_CDP_DEVICE_ID + + The device id used in CDP trigger frames. + + CONFIG_CDP_DEVICE_ID_PREFIX + + A two character string which is prefixed to the MAC address + of the device. + + CONFIG_CDP_PORT_ID + + A printf format string which contains the ascii name of + the port. Normally is set to "eth%d" which sets + eth0 for the first Ethernet, eth1 for the second etc. + + CONFIG_CDP_CAPABILITIES + + A 32bit integer which indicates the device capabilities; + 0x00000010 for a normal host which does not forwards. + + CONFIG_CDP_VERSION + + An ascii string containing the version of the software. + + CONFIG_CDP_PLATFORM + + An ascii string containing the name of the platform. + + CONFIG_CDP_TRIGGER + + A 32bit integer sent on the trigger. + + CONFIG_CDP_POWER_CONSUMPTION + + A 16bit integer containing the power consumption of the + device in .1 of milliwatts. + + CONFIG_CDP_APPLIANCE_VLAN_TYPE + + A byte containing the id of the VLAN. + +- Status LED: CONFIG_STATUS_LED + + Several configurations allow to display the current + status using a LED. For instance, the LED will blink + fast while running U-Boot code, stop blinking as + soon as a reply to a BOOTP request was received, and + start blinking slow once the Linux kernel is running + (supported by a status LED driver in the Linux + kernel). Defining CONFIG_STATUS_LED enables this + feature in U-Boot. + + Additional options: + + CONFIG_GPIO_LED + The status LED can be connected to a GPIO pin. + In such cases, the gpio_led driver can be used as a + status LED backend implementation. Define CONFIG_GPIO_LED + to include the gpio_led driver in the U-Boot binary. + + CONFIG_GPIO_LED_INVERTED_TABLE + Some GPIO connected LEDs may have inverted polarity in which + case the GPIO high value corresponds to LED off state and + GPIO low value corresponds to LED on state. + In such cases CONFIG_GPIO_LED_INVERTED_TABLE may be defined + with a list of GPIO LEDs that have inverted polarity. + +- CAN Support: CONFIG_CAN_DRIVER + + Defining CONFIG_CAN_DRIVER enables CAN driver support + on those systems that support this (optional) + feature, like the TQM8xxL modules. + +- I2C Support: CONFIG_SYS_I2C + + This enable the NEW i2c subsystem, and will allow you to use + i2c commands at the u-boot command line (as long as you set + CONFIG_CMD_I2C in CONFIG_COMMANDS) and communicate with i2c + based realtime clock chips or other i2c devices. See + common/cmd_i2c.c for a description of the command line + interface. + + ported i2c driver to the new framework: + - drivers/i2c/soft_i2c.c: + - activate first bus with CONFIG_SYS_I2C_SOFT define + CONFIG_SYS_I2C_SOFT_SPEED and CONFIG_SYS_I2C_SOFT_SLAVE + for defining speed and slave address + - activate second bus with I2C_SOFT_DECLARATIONS2 define + CONFIG_SYS_I2C_SOFT_SPEED_2 and CONFIG_SYS_I2C_SOFT_SLAVE_2 + for defining speed and slave address + - activate third bus with I2C_SOFT_DECLARATIONS3 define + CONFIG_SYS_I2C_SOFT_SPEED_3 and CONFIG_SYS_I2C_SOFT_SLAVE_3 + for defining speed and slave address + - activate fourth bus with I2C_SOFT_DECLARATIONS4 define + CONFIG_SYS_I2C_SOFT_SPEED_4 and CONFIG_SYS_I2C_SOFT_SLAVE_4 + for defining speed and slave address + + - drivers/i2c/fsl_i2c.c: + - activate i2c driver with CONFIG_SYS_I2C_FSL + define CONFIG_SYS_FSL_I2C_OFFSET for setting the register + offset CONFIG_SYS_FSL_I2C_SPEED for the i2c speed and + CONFIG_SYS_FSL_I2C_SLAVE for the slave addr of the first + bus. + - If your board supports a second fsl i2c bus, define + CONFIG_SYS_FSL_I2C2_OFFSET for the register offset + CONFIG_SYS_FSL_I2C2_SPEED for the speed and + CONFIG_SYS_FSL_I2C2_SLAVE for the slave address of the + second bus. + + - drivers/i2c/tegra_i2c.c: + - activate this driver with CONFIG_SYS_I2C_TEGRA + - This driver adds 4 i2c buses with a fix speed from + 100000 and the slave addr 0! + + - drivers/i2c/ppc4xx_i2c.c + - activate this driver with CONFIG_SYS_I2C_PPC4XX + - CONFIG_SYS_I2C_PPC4XX_CH0 activate hardware channel 0 + - CONFIG_SYS_I2C_PPC4XX_CH1 activate hardware channel 1 + + - drivers/i2c/i2c_mxc.c + - activate this driver with CONFIG_SYS_I2C_MXC + - define speed for bus 1 with CONFIG_SYS_MXC_I2C1_SPEED + - define slave for bus 1 with CONFIG_SYS_MXC_I2C1_SLAVE + - define speed for bus 2 with CONFIG_SYS_MXC_I2C2_SPEED + - define slave for bus 2 with CONFIG_SYS_MXC_I2C2_SLAVE + - define speed for bus 3 with CONFIG_SYS_MXC_I2C3_SPEED + - define slave for bus 3 with CONFIG_SYS_MXC_I2C3_SLAVE + If those defines are not set, default value is 100000 + for speed, and 0 for slave. + + - drivers/i2c/rcar_i2c.c: + - activate this driver with CONFIG_SYS_I2C_RCAR + - This driver adds 4 i2c buses + + - CONFIG_SYS_RCAR_I2C0_BASE for setting the register channel 0 + - CONFIG_SYS_RCAR_I2C0_SPEED for for the speed channel 0 + - CONFIG_SYS_RCAR_I2C1_BASE for setting the register channel 1 + - CONFIG_SYS_RCAR_I2C1_SPEED for for the speed channel 1 + - CONFIG_SYS_RCAR_I2C2_BASE for setting the register channel 2 + - CONFIG_SYS_RCAR_I2C2_SPEED for for the speed channel 2 + - CONFIG_SYS_RCAR_I2C3_BASE for setting the register channel 3 + - CONFIG_SYS_RCAR_I2C3_SPEED for for the speed channel 3 + - CONFIF_SYS_RCAR_I2C_NUM_CONTROLLERS for number of i2c buses + + - drivers/i2c/sh_i2c.c: + - activate this driver with CONFIG_SYS_I2C_SH + - This driver adds from 2 to 5 i2c buses + + - CONFIG_SYS_I2C_SH_BASE0 for setting the register channel 0 + - CONFIG_SYS_I2C_SH_SPEED0 for for the speed channel 0 + - CONFIG_SYS_I2C_SH_BASE1 for setting the register channel 1 + - CONFIG_SYS_I2C_SH_SPEED1 for for the speed channel 1 + - CONFIG_SYS_I2C_SH_BASE2 for setting the register channel 2 + - CONFIG_SYS_I2C_SH_SPEED2 for for the speed channel 2 + - CONFIG_SYS_I2C_SH_BASE3 for setting the register channel 3 + - CONFIG_SYS_I2C_SH_SPEED3 for for the speed channel 3 + - CONFIG_SYS_I2C_SH_BASE4 for setting the register channel 4 + - CONFIG_SYS_I2C_SH_SPEED4 for for the speed channel 4 + - CONFIG_SYS_I2C_SH_BASE5 for setting the register channel 5 + - CONFIG_SYS_I2C_SH_SPEED5 for for the speed channel 5 + - CONFIG_SYS_I2C_SH_NUM_CONTROLLERS for number of i2c buses + + - drivers/i2c/omap24xx_i2c.c + - activate this driver with CONFIG_SYS_I2C_OMAP24XX + - CONFIG_SYS_OMAP24_I2C_SPEED speed channel 0 + - CONFIG_SYS_OMAP24_I2C_SLAVE slave addr channel 0 + - CONFIG_SYS_OMAP24_I2C_SPEED1 speed channel 1 + - CONFIG_SYS_OMAP24_I2C_SLAVE1 slave addr channel 1 + - CONFIG_SYS_OMAP24_I2C_SPEED2 speed channel 2 + - CONFIG_SYS_OMAP24_I2C_SLAVE2 slave addr channel 2 + - CONFIG_SYS_OMAP24_I2C_SPEED3 speed channel 3 + - CONFIG_SYS_OMAP24_I2C_SLAVE3 slave addr channel 3 + - CONFIG_SYS_OMAP24_I2C_SPEED4 speed channel 4 + - CONFIG_SYS_OMAP24_I2C_SLAVE4 slave addr channel 4 + + - drivers/i2c/zynq_i2c.c + - activate this driver with CONFIG_SYS_I2C_ZYNQ + - set CONFIG_SYS_I2C_ZYNQ_SPEED for speed setting + - set CONFIG_SYS_I2C_ZYNQ_SLAVE for slave addr + + - drivers/i2c/s3c24x0_i2c.c: + - activate this driver with CONFIG_SYS_I2C_S3C24X0 + - This driver adds i2c buses (11 for Exynos5250, Exynos5420 + 9 i2c buses for Exynos4 and 1 for S3C24X0 SoCs from Samsung) + with a fix speed from 100000 and the slave addr 0! + + - drivers/i2c/ihs_i2c.c + - activate this driver with CONFIG_SYS_I2C_IHS + - CONFIG_SYS_I2C_IHS_CH0 activate hardware channel 0 + - CONFIG_SYS_I2C_IHS_SPEED_0 speed channel 0 + - CONFIG_SYS_I2C_IHS_SLAVE_0 slave addr channel 0 + - CONFIG_SYS_I2C_IHS_CH1 activate hardware channel 1 + - CONFIG_SYS_I2C_IHS_SPEED_1 speed channel 1 + - CONFIG_SYS_I2C_IHS_SLAVE_1 slave addr channel 1 + - CONFIG_SYS_I2C_IHS_CH2 activate hardware channel 2 + - CONFIG_SYS_I2C_IHS_SPEED_2 speed channel 2 + - CONFIG_SYS_I2C_IHS_SLAVE_2 slave addr channel 2 + - CONFIG_SYS_I2C_IHS_CH3 activate hardware channel 3 + - CONFIG_SYS_I2C_IHS_SPEED_3 speed channel 3 + - CONFIG_SYS_I2C_IHS_SLAVE_3 slave addr channel 3 + + additional defines: + + CONFIG_SYS_NUM_I2C_BUSES + Hold the number of i2c buses you want to use. If you + don't use/have i2c muxes on your i2c bus, this + is equal to CONFIG_SYS_NUM_I2C_ADAPTERS, and you can + omit this define. + + CONFIG_SYS_I2C_DIRECT_BUS + define this, if you don't use i2c muxes on your hardware. + if CONFIG_SYS_I2C_MAX_HOPS is not defined or == 0 you can + omit this define. + + CONFIG_SYS_I2C_MAX_HOPS + define how many muxes are maximal consecutively connected + on one i2c bus. If you not use i2c muxes, omit this + define. + + CONFIG_SYS_I2C_BUSES + hold a list of buses you want to use, only used if + CONFIG_SYS_I2C_DIRECT_BUS is not defined, for example + a board with CONFIG_SYS_I2C_MAX_HOPS = 1 and + CONFIG_SYS_NUM_I2C_BUSES = 9: + + CONFIG_SYS_I2C_BUSES {{0, {I2C_NULL_HOP}}, \ + {0, {{I2C_MUX_PCA9547, 0x70, 1}}}, \ + {0, {{I2C_MUX_PCA9547, 0x70, 2}}}, \ + {0, {{I2C_MUX_PCA9547, 0x70, 3}}}, \ + {0, {{I2C_MUX_PCA9547, 0x70, 4}}}, \ + {0, {{I2C_MUX_PCA9547, 0x70, 5}}}, \ + {1, {I2C_NULL_HOP}}, \ + {1, {{I2C_MUX_PCA9544, 0x72, 1}}}, \ + {1, {{I2C_MUX_PCA9544, 0x72, 2}}}, \ + } + + which defines + bus 0 on adapter 0 without a mux + bus 1 on adapter 0 with a PCA9547 on address 0x70 port 1 + bus 2 on adapter 0 with a PCA9547 on address 0x70 port 2 + bus 3 on adapter 0 with a PCA9547 on address 0x70 port 3 + bus 4 on adapter 0 with a PCA9547 on address 0x70 port 4 + bus 5 on adapter 0 with a PCA9547 on address 0x70 port 5 + bus 6 on adapter 1 without a mux + bus 7 on adapter 1 with a PCA9544 on address 0x72 port 1 + bus 8 on adapter 1 with a PCA9544 on address 0x72 port 2 + + If you do not have i2c muxes on your board, omit this define. + +- Legacy I2C Support: CONFIG_HARD_I2C + + NOTE: It is intended to move drivers to CONFIG_SYS_I2C which + provides the following compelling advantages: + + - more than one i2c adapter is usable + - approved multibus support + - better i2c mux support + + ** Please consider updating your I2C driver now. ** + + These enable legacy I2C serial bus commands. Defining + CONFIG_HARD_I2C will include the appropriate I2C driver + for the selected CPU. + + This will allow you to use i2c commands at the u-boot + command line (as long as you set CONFIG_CMD_I2C in + CONFIG_COMMANDS) and communicate with i2c based realtime + clock chips. See common/cmd_i2c.c for a description of the + command line interface. + + CONFIG_HARD_I2C selects a hardware I2C controller. + + There are several other quantities that must also be + defined when you define CONFIG_HARD_I2C. + + In both cases you will need to define CONFIG_SYS_I2C_SPEED + to be the frequency (in Hz) at which you wish your i2c bus + to run and CONFIG_SYS_I2C_SLAVE to be the address of this node (ie + the CPU's i2c node address). + + Now, the u-boot i2c code for the mpc8xx + (arch/powerpc/cpu/mpc8xx/i2c.c) sets the CPU up as a master node + and so its address should therefore be cleared to 0 (See, + eg, MPC823e User's Manual p.16-473). So, set + CONFIG_SYS_I2C_SLAVE to 0. + + CONFIG_SYS_I2C_INIT_MPC5XXX + + When a board is reset during an i2c bus transfer + chips might think that the current transfer is still + in progress. Reset the slave devices by sending start + commands until the slave device responds. + + That's all that's required for CONFIG_HARD_I2C. + + If you use the software i2c interface (CONFIG_SYS_I2C_SOFT) + then the following macros need to be defined (examples are + from include/configs/lwmon.h): + + I2C_INIT + + (Optional). Any commands necessary to enable the I2C + controller or configure ports. + + eg: #define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL) + + I2C_PORT + + (Only for MPC8260 CPU). The I/O port to use (the code + assumes both bits are on the same port). Valid values + are 0..3 for ports A..D. + + I2C_ACTIVE + + The code necessary to make the I2C data line active + (driven). If the data line is open collector, this + define can be null. + + eg: #define I2C_ACTIVE (immr->im_cpm.cp_pbdir |= PB_SDA) + + I2C_TRISTATE + + The code necessary to make the I2C data line tri-stated + (inactive). If the data line is open collector, this + define can be null. + + eg: #define I2C_TRISTATE (immr->im_cpm.cp_pbdir &= ~PB_SDA) + + I2C_READ + + Code that returns true if the I2C data line is high, + false if it is low. + + eg: #define I2C_READ ((immr->im_cpm.cp_pbdat & PB_SDA) != 0) + + I2C_SDA(bit) + + If <bit> is true, sets the I2C data line high. If it + is false, it clears it (low). + + eg: #define I2C_SDA(bit) \ + if(bit) immr->im_cpm.cp_pbdat |= PB_SDA; \ + else immr->im_cpm.cp_pbdat &= ~PB_SDA + + I2C_SCL(bit) + + If <bit> is true, sets the I2C clock line high. If it + is false, it clears it (low). + + eg: #define I2C_SCL(bit) \ + if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \ + else immr->im_cpm.cp_pbdat &= ~PB_SCL + + I2C_DELAY + + This delay is invoked four times per clock cycle so this + controls the rate of data transfer. The data rate thus + is 1 / (I2C_DELAY * 4). Often defined to be something + like: + + #define I2C_DELAY udelay(2) + + CONFIG_SOFT_I2C_GPIO_SCL / CONFIG_SOFT_I2C_GPIO_SDA + + If your arch supports the generic GPIO framework (asm/gpio.h), + then you may alternatively define the two GPIOs that are to be + used as SCL / SDA. Any of the previous I2C_xxx macros will + have GPIO-based defaults assigned to them as appropriate. + + You should define these to the GPIO value as given directly to + the generic GPIO functions. + + CONFIG_SYS_I2C_INIT_BOARD + + When a board is reset during an i2c bus transfer + chips might think that the current transfer is still + in progress. On some boards it is possible to access + the i2c SCLK line directly, either by using the + processor pin as a GPIO or by having a second pin + connected to the bus. If this option is defined a + custom i2c_init_board() routine in boards/xxx/board.c + is run early in the boot sequence. + + CONFIG_SYS_I2C_BOARD_LATE_INIT + + An alternative to CONFIG_SYS_I2C_INIT_BOARD. If this option is + defined a custom i2c_board_late_init() routine in + boards/xxx/board.c is run AFTER the operations in i2c_init() + is completed. This callpoint can be used to unreset i2c bus + using CPU i2c controller register accesses for CPUs whose i2c + controller provide such a method. It is called at the end of + i2c_init() to allow i2c_init operations to setup the i2c bus + controller on the CPU (e.g. setting bus speed & slave address). + + CONFIG_I2CFAST (PPC405GP|PPC405EP only) + + This option enables configuration of bi_iic_fast[] flags + in u-boot bd_info structure based on u-boot environment + variable "i2cfast". (see also i2cfast) + + CONFIG_I2C_MULTI_BUS + + This option allows the use of multiple I2C buses, each of which + must have a controller. At any point in time, only one bus is + active. To switch to a different bus, use the 'i2c dev' command. + Note that bus numbering is zero-based. + + CONFIG_SYS_I2C_NOPROBES + + This option specifies a list of I2C devices that will be skipped + when the 'i2c probe' command is issued. If CONFIG_I2C_MULTI_BUS + is set, specify a list of bus-device pairs. Otherwise, specify + a 1D array of device addresses + + e.g. + #undef CONFIG_I2C_MULTI_BUS + #define CONFIG_SYS_I2C_NOPROBES {0x50,0x68} + + will skip addresses 0x50 and 0x68 on a board with one I2C bus + + #define CONFIG_I2C_MULTI_BUS + #define CONFIG_SYS_I2C_MULTI_NOPROBES {{0,0x50},{0,0x68},{1,0x54}} + + will skip addresses 0x50 and 0x68 on bus 0 and address 0x54 on bus 1 + + CONFIG_SYS_SPD_BUS_NUM + + If defined, then this indicates the I2C bus number for DDR SPD. + If not defined, then U-Boot assumes that SPD is on I2C bus 0. + + CONFIG_SYS_RTC_BUS_NUM + + If defined, then this indicates the I2C bus number for the RTC. + If not defined, then U-Boot assumes that RTC is on I2C bus 0. + + CONFIG_SYS_DTT_BUS_NUM + + If defined, then this indicates the I2C bus number for the DTT. + If not defined, then U-Boot assumes that DTT is on I2C bus 0. + + CONFIG_SYS_I2C_DTT_ADDR: + + If defined, specifies the I2C address of the DTT device. + If not defined, then U-Boot uses predefined value for + specified DTT device. + + CONFIG_SOFT_I2C_READ_REPEATED_START + + defining this will force the i2c_read() function in + the soft_i2c driver to perform an I2C repeated start + between writing the address pointer and reading the + data. If this define is omitted the default behaviour + of doing a stop-start sequence will be used. Most I2C + devices can use either method, but some require one or + the other. + +- SPI Support: CONFIG_SPI + + Enables SPI driver (so far only tested with + SPI EEPROM, also an instance works with Crystal A/D and + D/As on the SACSng board) + + CONFIG_SH_SPI + + Enables the driver for SPI controller on SuperH. Currently + only SH7757 is supported. + + CONFIG_SPI_X + + Enables extended (16-bit) SPI EEPROM addressing. + (symmetrical to CONFIG_I2C_X) + + CONFIG_SOFT_SPI + + Enables a software (bit-bang) SPI driver rather than + using hardware support. This is a general purpose + driver that only requires three general I/O port pins + (two outputs, one input) to function. If this is + defined, the board configuration must define several + SPI configuration items (port pins to use, etc). For + an example, see include/configs/sacsng.h. + + CONFIG_HARD_SPI + + Enables a hardware SPI driver for general-purpose reads + and writes. As with CONFIG_SOFT_SPI, the board configuration + must define a list of chip-select function pointers. + Currently supported on some MPC8xxx processors. For an + example, see include/configs/mpc8349emds.h. + + CONFIG_MXC_SPI + + Enables the driver for the SPI controllers on i.MX and MXC + SoCs. Currently i.MX31/35/51 are supported. + + CONFIG_SYS_SPI_MXC_WAIT + Timeout for waiting until spi transfer completed. + default: (CONFIG_SYS_HZ/100) /* 10 ms */ + +- FPGA Support: CONFIG_FPGA + + Enables FPGA subsystem. + + CONFIG_FPGA_<vendor> + + Enables support for specific chip vendors. + (ALTERA, XILINX) + + CONFIG_FPGA_<family> + + Enables support for FPGA family. + (SPARTAN2, SPARTAN3, VIRTEX2, CYCLONE2, ACEX1K, ACEX) + + CONFIG_FPGA_COUNT + + Specify the number of FPGA devices to support. + + CONFIG_CMD_FPGA_LOADMK + + Enable support for fpga loadmk command + + CONFIG_CMD_FPGA_LOADP + + Enable support for fpga loadp command - load partial bitstream + + CONFIG_CMD_FPGA_LOADBP + + Enable support for fpga loadbp command - load partial bitstream + (Xilinx only) + + CONFIG_SYS_FPGA_PROG_FEEDBACK + + Enable printing of hash marks during FPGA configuration. + + CONFIG_SYS_FPGA_CHECK_BUSY + + Enable checks on FPGA configuration interface busy + status by the configuration function. This option + will require a board or device specific function to + be written. + + CONFIG_FPGA_DELAY + + If defined, a function that provides delays in the FPGA + configuration driver. + + CONFIG_SYS_FPGA_CHECK_CTRLC + Allow Control-C to interrupt FPGA configuration + + CONFIG_SYS_FPGA_CHECK_ERROR + + Check for configuration errors during FPGA bitfile + loading. For example, abort during Virtex II + configuration if the INIT_B line goes low (which + indicated a CRC error). + + CONFIG_SYS_FPGA_WAIT_INIT + + Maximum time to wait for the INIT_B line to de-assert + after PROB_B has been de-asserted during a Virtex II + FPGA configuration sequence. The default time is 500 + ms. + + CONFIG_SYS_FPGA_WAIT_BUSY + + Maximum time to wait for BUSY to de-assert during + Virtex II FPGA configuration. The default is 5 ms. + + CONFIG_SYS_FPGA_WAIT_CONFIG + + Time to wait after FPGA configuration. The default is + 200 ms. + +- Configuration Management: + CONFIG_BUILD_TARGET + + Some SoCs need special image types (e.g. U-Boot binary + with a special header) as build targets. By defining + CONFIG_BUILD_TARGET in the SoC / board header, this + special image will be automatically built upon calling + make / MAKEALL. + + CONFIG_IDENT_STRING + + If defined, this string will be added to the U-Boot + version information (U_BOOT_VERSION) + +- Vendor Parameter Protection: + + U-Boot considers the values of the environment + variables "serial#" (Board Serial Number) and + "ethaddr" (Ethernet Address) to be parameters that + are set once by the board vendor / manufacturer, and + protects these variables from casual modification by + the user. Once set, these variables are read-only, + and write or delete attempts are rejected. You can + change this behaviour: + + If CONFIG_ENV_OVERWRITE is #defined in your config + file, the write protection for vendor parameters is + completely disabled. Anybody can change or delete + these parameters. + + Alternatively, if you #define _both_ CONFIG_ETHADDR + _and_ CONFIG_OVERWRITE_ETHADDR_ONCE, a default + Ethernet address is installed in the environment, + which can be changed exactly ONCE by the user. [The + serial# is unaffected by this, i. e. it remains + read-only.] + + The same can be accomplished in a more flexible way + for any variable by configuring the type of access + to allow for those variables in the ".flags" variable + or define CONFIG_ENV_FLAGS_LIST_STATIC. + +- Protected RAM: + CONFIG_PRAM + + Define this variable to enable the reservation of + "protected RAM", i. e. RAM which is not overwritten + by U-Boot. Define CONFIG_PRAM to hold the number of + kB you want to reserve for pRAM. You can overwrite + this default value by defining an environment + variable "pram" to the number of kB you want to + reserve. Note that the board info structure will + still show the full amount of RAM. If pRAM is + reserved, a new environment variable "mem" will + automatically be defined to hold the amount of + remaining RAM in a form that can be passed as boot + argument to Linux, for instance like that: + + setenv bootargs ... mem=\${mem} + saveenv + + This way you can tell Linux not to use this memory, + either, which results in a memory region that will + not be affected by reboots. + + *WARNING* If your board configuration uses automatic + detection of the RAM size, you must make sure that + this memory test is non-destructive. So far, the + following board configurations are known to be + "pRAM-clean": + + IVMS8, IVML24, SPD8xx, TQM8xxL, + HERMES, IP860, RPXlite, LWMON, + FLAGADM, TQM8260 + +- Access to physical memory region (> 4GB) + Some basic support is provided for operations on memory not + normally accessible to U-Boot - e.g. some architectures + support access to more than 4GB of memory on 32-bit + machines using physical address extension or similar. + Define CONFIG_PHYSMEM to access this basic support, which + currently only supports clearing the memory. + +- Error Recovery: + CONFIG_PANIC_HANG + + Define this variable to stop the system in case of a + fatal error, so that you have to reset it manually. + This is probably NOT a good idea for an embedded + system where you want the system to reboot + automatically as fast as possible, but it may be + useful during development since you can try to debug + the conditions that lead to the situation. + + CONFIG_NET_RETRY_COUNT + + This variable defines the number of retries for + network operations like ARP, RARP, TFTP, or BOOTP + before giving up the operation. If not defined, a + default value of 5 is used. + + CONFIG_ARP_TIMEOUT + + Timeout waiting for an ARP reply in milliseconds. + + CONFIG_NFS_TIMEOUT + + Timeout in milliseconds used in NFS protocol. + If you encounter "ERROR: Cannot umount" in nfs command, + try longer timeout such as + #define CONFIG_NFS_TIMEOUT 10000UL + +- Command Interpreter: + CONFIG_AUTO_COMPLETE + + Enable auto completion of commands using TAB. + + CONFIG_SYS_PROMPT_HUSH_PS2 + + This defines the secondary prompt string, which is + printed when the command interpreter needs more input + to complete a command. Usually "> ". + + Note: + + In the current implementation, the local variables + space and global environment variables space are + separated. Local variables are those you define by + simply typing `name=value'. To access a local + variable later on, you have write `$name' or + `${name}'; to execute the contents of a variable + directly type `$name' at the command prompt. + + Global environment variables are those you use + setenv/printenv to work with. To run a command stored + in such a variable, you need to use the run command, + and you must not use the '$' sign to access them. + + To store commands and special characters in a + variable, please use double quotation marks + surrounding the whole text of the variable, instead + of the backslashes before semicolons and special + symbols. + +- Command Line Editing and History: + CONFIG_CMDLINE_EDITING + + Enable editing and History functions for interactive + command line input operations + +- Default Environment: + CONFIG_EXTRA_ENV_SETTINGS + + Define this to contain any number of null terminated + strings (variable = value pairs) that will be part of + the default environment compiled into the boot image. + + For example, place something like this in your + board's config file: + + #define CONFIG_EXTRA_ENV_SETTINGS \ + "myvar1=value1\0" \ + "myvar2=value2\0" + + Warning: This method is based on knowledge about the + internal format how the environment is stored by the + U-Boot code. This is NOT an official, exported + interface! Although it is unlikely that this format + will change soon, there is no guarantee either. + You better know what you are doing here. + + Note: overly (ab)use of the default environment is + discouraged. Make sure to check other ways to preset + the environment like the "source" command or the + boot command first. + + CONFIG_ENV_VARS_UBOOT_CONFIG + + Define this in order to add variables describing the + U-Boot build configuration to the default environment. + These will be named arch, cpu, board, vendor, and soc. + + Enabling this option will cause the following to be defined: + + - CONFIG_SYS_ARCH + - CONFIG_SYS_CPU + - CONFIG_SYS_BOARD + - CONFIG_SYS_VENDOR + - CONFIG_SYS_SOC + + CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + + Define this in order to add variables describing certain + run-time determined information about the hardware to the + environment. These will be named board_name, board_rev. + + CONFIG_DELAY_ENVIRONMENT + + Normally the environment is loaded when the board is + initialised so that it is available to U-Boot. This inhibits + that so that the environment is not available until + explicitly loaded later by U-Boot code. With CONFIG_OF_CONTROL + this is instead controlled by the value of + /config/load-environment. + +- DataFlash Support: + CONFIG_HAS_DATAFLASH + + Defining this option enables DataFlash features and + allows to read/write in Dataflash via the standard + commands cp, md... + +- Serial Flash support + CONFIG_CMD_SF + + Defining this option enables SPI flash commands + 'sf probe/read/write/erase/update'. + + Usage requires an initial 'probe' to define the serial + flash parameters, followed by read/write/erase/update + commands. + + The following defaults may be provided by the platform + to handle the common case when only a single serial + flash is present on the system. + + CONFIG_SF_DEFAULT_BUS Bus identifier + CONFIG_SF_DEFAULT_CS Chip-select + CONFIG_SF_DEFAULT_MODE (see include/spi.h) + CONFIG_SF_DEFAULT_SPEED in Hz + + CONFIG_CMD_SF_TEST + + Define this option to include a destructive SPI flash + test ('sf test'). + + CONFIG_SPI_FLASH_BAR Ban/Extended Addr Reg + + Define this option to use the Bank addr/Extended addr + support on SPI flashes which has size > 16Mbytes. + + CONFIG_SF_DUAL_FLASH Dual flash memories + + Define this option to use dual flash support where two flash + memories can be connected with a given cs line. + Currently Xilinx Zynq qspi supports these type of connections. + + CONFIG_SYS_SPI_ST_ENABLE_WP_PIN + enable the W#/Vpp signal to disable writing to the status + register on ST MICRON flashes like the N25Q128. + The status register write enable/disable bit, combined with + the W#/VPP signal provides hardware data protection for the + device as follows: When the enable/disable bit is set to 1, + and the W#/VPP signal is driven LOW, the status register + nonvolatile bits become read-only and the WRITE STATUS REGISTER + operation will not execute. The only way to exit this + hardware-protected mode is to drive W#/VPP HIGH. + +- SystemACE Support: + CONFIG_SYSTEMACE + + Adding this option adds support for Xilinx SystemACE + chips attached via some sort of local bus. The address + of the chip must also be defined in the + CONFIG_SYS_SYSTEMACE_BASE macro. For example: + + #define CONFIG_SYSTEMACE + #define CONFIG_SYS_SYSTEMACE_BASE 0xf0000000 + + When SystemACE support is added, the "ace" device type + becomes available to the fat commands, i.e. fatls. + +- TFTP Fixed UDP Port: + CONFIG_TFTP_PORT + + If this is defined, the environment variable tftpsrcp + is used to supply the TFTP UDP source port value. + If tftpsrcp isn't defined, the normal pseudo-random port + number generator is used. + + Also, the environment variable tftpdstp is used to supply + the TFTP UDP destination port value. If tftpdstp isn't + defined, the normal port 69 is used. + + The purpose for tftpsrcp is to allow a TFTP server to + blindly start the TFTP transfer using the pre-configured + target IP address and UDP port. This has the effect of + "punching through" the (Windows XP) firewall, allowing + the remainder of the TFTP transfer to proceed normally. + A better solution is to properly configure the firewall, + but sometimes that is not allowed. + +- Hashing support: + CONFIG_CMD_HASH + + This enables a generic 'hash' command which can produce + hashes / digests from a few algorithms (e.g. SHA1, SHA256). + + CONFIG_HASH_VERIFY + + Enable the hash verify command (hash -v). This adds to code + size a little. + + CONFIG_SHA1 - This option enables support of hashing using SHA1 + algorithm. The hash is calculated in software. + CONFIG_SHA256 - This option enables support of hashing using + SHA256 algorithm. The hash is calculated in software. + CONFIG_SHA_HW_ACCEL - This option enables hardware acceleration + for SHA1/SHA256 hashing. + This affects the 'hash' command and also the + hash_lookup_algo() function. + CONFIG_SHA_PROG_HW_ACCEL - This option enables + hardware-acceleration for SHA1/SHA256 progressive hashing. + Data can be streamed in a block at a time and the hashing + is performed in hardware. + + Note: There is also a sha1sum command, which should perhaps + be deprecated in favour of 'hash sha1'. + +- Freescale i.MX specific commands: + CONFIG_CMD_HDMIDETECT + This enables 'hdmidet' command which returns true if an + HDMI monitor is detected. This command is i.MX 6 specific. + + CONFIG_CMD_BMODE + This enables the 'bmode' (bootmode) command for forcing + a boot from specific media. + + This is useful for forcing the ROM's usb downloader to + activate upon a watchdog reset which is nice when iterating + on U-Boot. Using the reset button or running bmode normal + will set it back to normal. This command currently + supports i.MX53 and i.MX6. + +- Signing support: + CONFIG_RSA + + This enables the RSA algorithm used for FIT image verification + in U-Boot. See doc/uImage.FIT/signature.txt for more information. + + The Modular Exponentiation algorithm in RSA is implemented using + driver model. So CONFIG_DM needs to be enabled by default for this + library to function. + + The signing part is build into mkimage regardless of this + option. The software based modular exponentiation is built into + mkimage irrespective of this option. + +- bootcount support: + CONFIG_BOOTCOUNT_LIMIT + + This enables the bootcounter support, see: + http://www.denx.de/wiki/DULG/UBootBootCountLimit + + CONFIG_AT91SAM9XE + enable special bootcounter support on at91sam9xe based boards. + CONFIG_BLACKFIN + enable special bootcounter support on blackfin based boards. + CONFIG_SOC_DA8XX + enable special bootcounter support on da850 based boards. + CONFIG_BOOTCOUNT_RAM + enable support for the bootcounter in RAM + CONFIG_BOOTCOUNT_I2C + enable support for the bootcounter on an i2c (like RTC) device. + CONFIG_SYS_I2C_RTC_ADDR = i2c chip address + CONFIG_SYS_BOOTCOUNT_ADDR = i2c addr which is used for + the bootcounter. + CONFIG_BOOTCOUNT_ALEN = address len + +- Show boot progress: + CONFIG_SHOW_BOOT_PROGRESS + + Defining this option allows to add some board- + specific code (calling a user-provided function + "show_boot_progress(int)") that enables you to show + the system's boot progress on some display (for + example, some LED's) on your board. At the moment, + the following checkpoints are implemented: + +- Detailed boot stage timing + CONFIG_BOOTSTAGE + Define this option to get detailed timing of each stage + of the boot process. + + CONFIG_BOOTSTAGE_USER_COUNT + This is the number of available user bootstage records. + Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...) + a new ID will be allocated from this stash. If you exceed + the limit, recording will stop. + + CONFIG_BOOTSTAGE_REPORT + Define this to print a report before boot, similar to this: + + Timer summary in microseconds: + Mark Elapsed Stage + 0 0 reset + 3,575,678 3,575,678 board_init_f start + 3,575,695 17 arch_cpu_init A9 + 3,575,777 82 arch_cpu_init done + 3,659,598 83,821 board_init_r start + 3,910,375 250,777 main_loop + 29,916,167 26,005,792 bootm_start + 30,361,327 445,160 start_kernel + + CONFIG_CMD_BOOTSTAGE + Add a 'bootstage' command which supports printing a report + and un/stashing of bootstage data. + + CONFIG_BOOTSTAGE_FDT + Stash the bootstage information in the FDT. A root 'bootstage' + node is created with each bootstage id as a child. Each child + has a 'name' property and either 'mark' containing the + mark time in microsecond, or 'accum' containing the + accumulated time for that bootstage id in microseconds. + For example: + + bootstage { + 154 { + name = "board_init_f"; + mark = <3575678>; + }; + 170 { + name = "lcd"; + accum = <33482>; + }; + }; + + Code in the Linux kernel can find this in /proc/devicetree. + +Legacy uImage format: + + Arg Where When + 1 common/cmd_bootm.c before attempting to boot an image + -1 common/cmd_bootm.c Image header has bad magic number + 2 common/cmd_bootm.c Image header has correct magic number + -2 common/cmd_bootm.c Image header has bad checksum + 3 common/cmd_bootm.c Image header has correct checksum + -3 common/cmd_bootm.c Image data has bad checksum + 4 common/cmd_bootm.c Image data has correct checksum + -4 common/cmd_bootm.c Image is for unsupported architecture + 5 common/cmd_bootm.c Architecture check OK + -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi) + 6 common/cmd_bootm.c Image Type check OK + -6 common/cmd_bootm.c gunzip uncompression error + -7 common/cmd_bootm.c Unimplemented compression type + 7 common/cmd_bootm.c Uncompression OK + 8 common/cmd_bootm.c No uncompress/copy overwrite error + -9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX) + + 9 common/image.c Start initial ramdisk verification + -10 common/image.c Ramdisk header has bad magic number + -11 common/image.c Ramdisk header has bad checksum + 10 common/image.c Ramdisk header is OK + -12 common/image.c Ramdisk data has bad checksum + 11 common/image.c Ramdisk data has correct checksum + 12 common/image.c Ramdisk verification complete, start loading + -13 common/image.c Wrong Image Type (not PPC Linux ramdisk) + 13 common/image.c Start multifile image verification + 14 common/image.c No initial ramdisk, no multifile, continue. + + 15 arch/<arch>/lib/bootm.c All preparation done, transferring control to OS + + -30 arch/powerpc/lib/board.c Fatal error, hang the system + -31 post/post.c POST test failed, detected by post_output_backlog() + -32 post/post.c POST test failed, detected by post_run_single() + + 34 common/cmd_doc.c before loading a Image from a DOC device + -35 common/cmd_doc.c Bad usage of "doc" command + 35 common/cmd_doc.c correct usage of "doc" command + -36 common/cmd_doc.c No boot device + 36 common/cmd_doc.c correct boot device + -37 common/cmd_doc.c Unknown Chip ID on boot device + 37 common/cmd_doc.c correct chip ID found, device available + -38 common/cmd_doc.c Read Error on boot device + 38 common/cmd_doc.c reading Image header from DOC device OK + -39 common/cmd_doc.c Image header has bad magic number + 39 common/cmd_doc.c Image header has correct magic number + -40 common/cmd_doc.c Error reading Image from DOC device + 40 common/cmd_doc.c Image header has correct magic number + 41 common/cmd_ide.c before loading a Image from a IDE device + -42 common/cmd_ide.c Bad usage of "ide" command + 42 common/cmd_ide.c correct usage of "ide" command + -43 common/cmd_ide.c No boot device + 43 common/cmd_ide.c boot device found + -44 common/cmd_ide.c Device not available + 44 common/cmd_ide.c Device available + -45 common/cmd_ide.c wrong partition selected + 45 common/cmd_ide.c partition selected + -46 common/cmd_ide.c Unknown partition table + 46 common/cmd_ide.c valid partition table found + -47 common/cmd_ide.c Invalid partition type + 47 common/cmd_ide.c correct partition type + -48 common/cmd_ide.c Error reading Image Header on boot device + 48 common/cmd_ide.c reading Image Header from IDE device OK + -49 common/cmd_ide.c Image header has bad magic number + 49 common/cmd_ide.c Image header has correct magic number + -50 common/cmd_ide.c Image header has bad checksum + 50 common/cmd_ide.c Image header has correct checksum + -51 common/cmd_ide.c Error reading Image from IDE device + 51 common/cmd_ide.c reading Image from IDE device OK + 52 common/cmd_nand.c before loading a Image from a NAND device + -53 common/cmd_nand.c Bad usage of "nand" command + 53 common/cmd_nand.c correct usage of "nand" command + -54 common/cmd_nand.c No boot device + 54 common/cmd_nand.c boot device found + -55 common/cmd_nand.c Unknown Chip ID on boot device + 55 common/cmd_nand.c correct chip ID found, device available + -56 common/cmd_nand.c Error reading Image Header on boot device + 56 common/cmd_nand.c reading Image Header from NAND device OK + -57 common/cmd_nand.c Image header has bad magic number + 57 common/cmd_nand.c Image header has correct magic number + -58 common/cmd_nand.c Error reading Image from NAND device + 58 common/cmd_nand.c reading Image from NAND device OK + + -60 common/env_common.c Environment has a bad CRC, using default + + 64 net/eth.c starting with Ethernet configuration. + -64 net/eth.c no Ethernet found. + 65 net/eth.c Ethernet found. + + -80 common/cmd_net.c usage wrong + 80 common/cmd_net.c before calling NetLoop() + -81 common/cmd_net.c some error in NetLoop() occurred + 81 common/cmd_net.c NetLoop() back without error + -82 common/cmd_net.c size == 0 (File with size 0 loaded) + 82 common/cmd_net.c trying automatic boot + 83 common/cmd_net.c running "source" command + -83 common/cmd_net.c some error in automatic boot or "source" command + 84 common/cmd_net.c end without errors + +FIT uImage format: + + Arg Where When + 100 common/cmd_bootm.c Kernel FIT Image has correct format + -100 common/cmd_bootm.c Kernel FIT Image has incorrect format + 101 common/cmd_bootm.c No Kernel subimage unit name, using configuration + -101 common/cmd_bootm.c Can't get configuration for kernel subimage + 102 common/cmd_bootm.c Kernel unit name specified + -103 common/cmd_bootm.c Can't get kernel subimage node offset + 103 common/cmd_bootm.c Found configuration node + 104 common/cmd_bootm.c Got kernel subimage node offset + -104 common/cmd_bootm.c Kernel subimage hash verification failed + 105 common/cmd_bootm.c Kernel subimage hash verification OK + -105 common/cmd_bootm.c Kernel subimage is for unsupported architecture + 106 common/cmd_bootm.c Architecture check OK + -106 common/cmd_bootm.c Kernel subimage has wrong type + 107 common/cmd_bootm.c Kernel subimage type OK + -107 common/cmd_bootm.c Can't get kernel subimage data/size + 108 common/cmd_bootm.c Got kernel subimage data/size + -108 common/cmd_bootm.c Wrong image type (not legacy, FIT) + -109 common/cmd_bootm.c Can't get kernel subimage type + -110 common/cmd_bootm.c Can't get kernel subimage comp + -111 common/cmd_bootm.c Can't get kernel subimage os + -112 common/cmd_bootm.c Can't get kernel subimage load address + -113 common/cmd_bootm.c Image uncompress/copy overwrite error + + 120 common/image.c Start initial ramdisk verification + -120 common/image.c Ramdisk FIT image has incorrect format + 121 common/image.c Ramdisk FIT image has correct format + 122 common/image.c No ramdisk subimage unit name, using configuration + -122 common/image.c Can't get configuration for ramdisk subimage + 123 common/image.c Ramdisk unit name specified + -124 common/image.c Can't get ramdisk subimage node offset + 125 common/image.c Got ramdisk subimage node offset + -125 common/image.c Ramdisk subimage hash verification failed + 126 common/image.c Ramdisk subimage hash verification OK + -126 common/image.c Ramdisk subimage for unsupported architecture + 127 common/image.c Architecture check OK + -127 common/image.c Can't get ramdisk subimage data/size + 128 common/image.c Got ramdisk subimage data/size + 129 common/image.c Can't get ramdisk load address + -129 common/image.c Got ramdisk load address + + -130 common/cmd_doc.c Incorrect FIT image format + 131 common/cmd_doc.c FIT image format OK + + -140 common/cmd_ide.c Incorrect FIT image format + 141 common/cmd_ide.c FIT image format OK + + -150 common/cmd_nand.c Incorrect FIT image format + 151 common/cmd_nand.c FIT image format OK + +- legacy image format: + CONFIG_IMAGE_FORMAT_LEGACY + enables the legacy image format support in U-Boot. + + Default: + enabled if CONFIG_FIT_SIGNATURE is not defined. + + CONFIG_DISABLE_IMAGE_LEGACY + disable the legacy image format + + This define is introduced, as the legacy image format is + enabled per default for backward compatibility. + +- FIT image support: + CONFIG_FIT + Enable support for the FIT uImage format. + + CONFIG_FIT_BEST_MATCH + When no configuration is explicitly selected, default to the + one whose fdt's compatibility field best matches that of + U-Boot itself. A match is considered "best" if it matches the + most specific compatibility entry of U-Boot's fdt's root node. + The order of entries in the configuration's fdt is ignored. + + CONFIG_FIT_SIGNATURE + This option enables signature verification of FIT uImages, + using a hash signed and verified using RSA. If + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive + hashing is available using hardware, RSA library will use it. + See doc/uImage.FIT/signature.txt for more details. + + WARNING: When relying on signed FIT images with required + signature check the legacy image format is default + disabled. If a board need legacy image format support + enable this through CONFIG_IMAGE_FORMAT_LEGACY + + CONFIG_FIT_DISABLE_SHA256 + Supporting SHA256 hashes has quite an impact on binary size. + For constrained systems sha256 hash support can be disabled + with this option. + +- Standalone program support: + CONFIG_STANDALONE_LOAD_ADDR + + This option defines a board specific value for the + address where standalone program gets loaded, thus + overwriting the architecture dependent default + settings. + +- Frame Buffer Address: + CONFIG_FB_ADDR + + Define CONFIG_FB_ADDR if you want to use specific + address for frame buffer. This is typically the case + when using a graphics controller has separate video + memory. U-Boot will then place the frame buffer at + the given address instead of dynamically reserving it + in system RAM by calling lcd_setmem(), which grabs + the memory for the frame buffer depending on the + configured panel size. + + Please see board_init_f function. + +- Automatic software updates via TFTP server + CONFIG_UPDATE_TFTP + CONFIG_UPDATE_TFTP_CNT_MAX + CONFIG_UPDATE_TFTP_MSEC_MAX + + These options enable and control the auto-update feature; + for a more detailed description refer to doc/README.update. + +- MTD Support (mtdparts command, UBI support) + CONFIG_MTD_DEVICE + + Adds the MTD device infrastructure from the Linux kernel. + Needed for mtdparts command support. + + CONFIG_MTD_PARTITIONS + + Adds the MTD partitioning infrastructure from the Linux + kernel. Needed for UBI support. + +- UBI support + CONFIG_CMD_UBI + + Adds commands for interacting with MTD partitions formatted + with the UBI flash translation layer + + Requires also defining CONFIG_RBTREE + + CONFIG_UBI_SILENCE_MSG + + Make the verbose messages from UBI stop printing. This leaves + warnings and errors enabled. + + + CONFIG_MTD_UBI_WL_THRESHOLD + This parameter defines the maximum difference between the highest + erase counter value and the lowest erase counter value of eraseblocks + of UBI devices. When this threshold is exceeded, UBI starts performing + wear leveling by means of moving data from eraseblock with low erase + counter to eraseblocks with high erase counter. + + The default value should be OK for SLC NAND flashes, NOR flashes and + other flashes which have eraseblock life-cycle 100000 or more. + However, in case of MLC NAND flashes which typically have eraseblock + life-cycle less than 10000, the threshold should be lessened (e.g., + to 128 or 256, although it does not have to be power of 2). + + default: 4096 + + CONFIG_MTD_UBI_BEB_LIMIT + This option specifies the maximum bad physical eraseblocks UBI + expects on the MTD device (per 1024 eraseblocks). If the + underlying flash does not admit of bad eraseblocks (e.g. NOR + flash), this value is ignored. + + NAND datasheets often specify the minimum and maximum NVM + (Number of Valid Blocks) for the flashes' endurance lifetime. + The maximum expected bad eraseblocks per 1024 eraseblocks + then can be calculated as "1024 * (1 - MinNVB / MaxNVB)", + which gives 20 for most NANDs (MaxNVB is basically the total + count of eraseblocks on the chip). + + To put it differently, if this value is 20, UBI will try to + reserve about 1.9% of physical eraseblocks for bad blocks + handling. And that will be 1.9% of eraseblocks on the entire + NAND chip, not just the MTD partition UBI attaches. This means + that if you have, say, a NAND flash chip admits maximum 40 bad + eraseblocks, and it is split on two MTD partitions of the same + size, UBI will reserve 40 eraseblocks when attaching a + partition. + + default: 20 + + CONFIG_MTD_UBI_FASTMAP + Fastmap is a mechanism which allows attaching an UBI device + in nearly constant time. Instead of scanning the whole MTD device it + only has to locate a checkpoint (called fastmap) on the device. + The on-flash fastmap contains all information needed to attach + the device. Using fastmap makes only sense on large devices where + attaching by scanning takes long. UBI will not automatically install + a fastmap on old images, but you can set the UBI parameter + CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT to 1 if you want so. Please note + that fastmap-enabled images are still usable with UBI implementations + without fastmap support. On typical flash devices the whole fastmap + fits into one PEB. UBI will reserve PEBs to hold two fastmaps. + + CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT + Set this parameter to enable fastmap automatically on images + without a fastmap. + default: 0 + + CONFIG_MTD_UBI_FM_DEBUG + Enable UBI fastmap debug + default: 0 + +- UBIFS support + CONFIG_CMD_UBIFS + + Adds commands for interacting with UBI volumes formatted as + UBIFS. UBIFS is read-only in u-boot. + + Requires UBI support as well as CONFIG_LZO + + CONFIG_UBIFS_SILENCE_MSG + + Make the verbose messages from UBIFS stop printing. This leaves + warnings and errors enabled. + +- SPL framework + CONFIG_SPL + Enable building of SPL globally. + + CONFIG_SPL_LDSCRIPT + LDSCRIPT for linking the SPL binary. + + CONFIG_SPL_MAX_FOOTPRINT + Maximum size in memory allocated to the SPL, BSS included. + When defined, the linker checks that the actual memory + used by SPL from _start to __bss_end does not exceed it. + CONFIG_SPL_MAX_FOOTPRINT and CONFIG_SPL_BSS_MAX_SIZE + must not be both defined at the same time. + + CONFIG_SPL_MAX_SIZE + Maximum size of the SPL image (text, data, rodata, and + linker lists sections), BSS excluded. + When defined, the linker checks that the actual size does + not exceed it. + + CONFIG_SPL_TEXT_BASE + TEXT_BASE for linking the SPL binary. + + CONFIG_SPL_RELOC_TEXT_BASE + Address to relocate to. If unspecified, this is equal to + CONFIG_SPL_TEXT_BASE (i.e. no relocation is done). + + CONFIG_SPL_BSS_START_ADDR + Link address for the BSS within the SPL binary. + + CONFIG_SPL_BSS_MAX_SIZE + Maximum size in memory allocated to the SPL BSS. + When defined, the linker checks that the actual memory used + by SPL from __bss_start to __bss_end does not exceed it. + CONFIG_SPL_MAX_FOOTPRINT and CONFIG_SPL_BSS_MAX_SIZE + must not be both defined at the same time. + + CONFIG_SPL_STACK + Adress of the start of the stack SPL will use + + CONFIG_SPL_PANIC_ON_RAW_IMAGE + When defined, SPL will panic() if the image it has + loaded does not have a signature. + Defining this is useful when code which loads images + in SPL cannot guarantee that absolutely all read errors + will be caught. + An example is the LPC32XX MLC NAND driver, which will + consider that a completely unreadable NAND block is bad, + and thus should be skipped silently. + + CONFIG_SPL_RELOC_STACK + Adress of the start of the stack SPL will use after + relocation. If unspecified, this is equal to + CONFIG_SPL_STACK. + + CONFIG_SYS_SPL_MALLOC_START + Starting address of the malloc pool used in SPL. + + CONFIG_SYS_SPL_MALLOC_SIZE + The size of the malloc pool used in SPL. + + CONFIG_SPL_FRAMEWORK + Enable the SPL framework under common/. This framework + supports MMC, NAND and YMODEM loading of U-Boot and NAND + NAND loading of the Linux Kernel. + + CONFIG_SPL_OS_BOOT + Enable booting directly to an OS from SPL. + See also: doc/README.falcon + + CONFIG_SPL_DISPLAY_PRINT + For ARM, enable an optional function to print more information + about the running system. + + CONFIG_SPL_INIT_MINIMAL + Arch init code should be built for a very small image + + CONFIG_SPL_LIBCOMMON_SUPPORT + Support for common/libcommon.o in SPL binary + + CONFIG_SPL_LIBDISK_SUPPORT + Support for disk/libdisk.o in SPL binary + + CONFIG_SPL_I2C_SUPPORT + Support for drivers/i2c/libi2c.o in SPL binary + + CONFIG_SPL_GPIO_SUPPORT + Support for drivers/gpio/libgpio.o in SPL binary + + CONFIG_SPL_MMC_SUPPORT + Support for drivers/mmc/libmmc.o in SPL binary + + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS, + Address and partition on the MMC to load U-Boot from + when the MMC is being used in raw mode. + + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION + Partition on the MMC to load U-Boot from when the MMC is being + used in raw mode + + CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR + Sector to load kernel uImage from when MMC is being + used in raw mode (for Falcon mode) + + CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, + CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS + Sector and number of sectors to load kernel argument + parameters from when MMC is being used in raw mode + (for falcon mode) + + CONFIG_SYS_MMCSD_FS_BOOT_PARTITION + Partition on the MMC to load U-Boot from when the MMC is being + used in fs mode + + CONFIG_SPL_FAT_SUPPORT + Support for fs/fat/libfat.o in SPL binary + + CONFIG_SPL_EXT_SUPPORT + Support for EXT filesystem in SPL binary + + CONFIG_SPL_FS_LOAD_PAYLOAD_NAME + Filename to read to load U-Boot when reading from filesystem + + CONFIG_SPL_FS_LOAD_KERNEL_NAME + Filename to read to load kernel uImage when reading + from filesystem (for Falcon mode) + + CONFIG_SPL_FS_LOAD_ARGS_NAME + Filename to read to load kernel argument parameters + when reading from filesystem (for Falcon mode) + + CONFIG_SPL_MPC83XX_WAIT_FOR_NAND + Set this for NAND SPL on PPC mpc83xx targets, so that + start.S waits for the rest of the SPL to load before + continuing (the hardware starts execution after just + loading the first page rather than the full 4K). + + CONFIG_SPL_SKIP_RELOCATE + Avoid SPL relocation + + CONFIG_SPL_NAND_BASE + Include nand_base.c in the SPL. Requires + CONFIG_SPL_NAND_DRIVERS. + + CONFIG_SPL_NAND_DRIVERS + SPL uses normal NAND drivers, not minimal drivers. + + CONFIG_SPL_NAND_ECC + Include standard software ECC in the SPL + + CONFIG_SPL_NAND_SIMPLE + Support for NAND boot using simple NAND drivers that + expose the cmd_ctrl() interface. + + CONFIG_SPL_MTD_SUPPORT + Support for the MTD subsystem within SPL. Useful for + environment on NAND support within SPL. + + CONFIG_SPL_NAND_RAW_ONLY + Support to boot only raw u-boot.bin images. Use this only + if you need to save space. + + CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT + Set for the SPL on PPC mpc8xxx targets, support for + drivers/ddr/fsl/libddr.o in SPL binary. + + CONFIG_SPL_COMMON_INIT_DDR + Set for common ddr init with serial presence detect in + SPL binary. + + CONFIG_SYS_NAND_5_ADDR_CYCLE, CONFIG_SYS_NAND_PAGE_COUNT, + CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE, + CONFIG_SYS_NAND_BLOCK_SIZE, CONFIG_SYS_NAND_BAD_BLOCK_POS, + CONFIG_SYS_NAND_ECCPOS, CONFIG_SYS_NAND_ECCSIZE, + CONFIG_SYS_NAND_ECCBYTES + Defines the size and behavior of the NAND that SPL uses + to read U-Boot + + CONFIG_SPL_NAND_BOOT + Add support NAND boot + + CONFIG_SYS_NAND_U_BOOT_OFFS + Location in NAND to read U-Boot from + + CONFIG_SYS_NAND_U_BOOT_DST + Location in memory to load U-Boot to + + CONFIG_SYS_NAND_U_BOOT_SIZE + Size of image to load + + CONFIG_SYS_NAND_U_BOOT_START + Entry point in loaded image to jump to + + CONFIG_SYS_NAND_HW_ECC_OOBFIRST + Define this if you need to first read the OOB and then the + data. This is used, for example, on davinci platforms. + + CONFIG_SPL_OMAP3_ID_NAND + Support for an OMAP3-specific set of functions to return the + ID and MFR of the first attached NAND chip, if present. + + CONFIG_SPL_SERIAL_SUPPORT + Support for drivers/serial/libserial.o in SPL binary + + CONFIG_SPL_SPI_FLASH_SUPPORT + Support for drivers/mtd/spi/libspi_flash.o in SPL binary + + CONFIG_SPL_SPI_SUPPORT + Support for drivers/spi/libspi.o in SPL binary + + CONFIG_SPL_RAM_DEVICE + Support for running image already present in ram, in SPL binary + + CONFIG_SPL_LIBGENERIC_SUPPORT + Support for lib/libgeneric.o in SPL binary + + CONFIG_SPL_ENV_SUPPORT + Support for the environment operating in SPL binary + + CONFIG_SPL_NET_SUPPORT + Support for the net/libnet.o in SPL binary. + It conflicts with SPL env from storage medium specified by + CONFIG_ENV_IS_xxx but CONFIG_ENV_IS_NOWHERE + + CONFIG_SPL_PAD_TO + Image offset to which the SPL should be padded before appending + the SPL payload. By default, this is defined as + CONFIG_SPL_MAX_SIZE, or 0 if CONFIG_SPL_MAX_SIZE is undefined. + CONFIG_SPL_PAD_TO must be either 0, meaning to append the SPL + payload without any padding, or >= CONFIG_SPL_MAX_SIZE. + + CONFIG_SPL_TARGET + Final target image containing SPL and payload. Some SPLs + use an arch-specific makefile fragment instead, for + example if more than one image needs to be produced. + + CONFIG_FIT_SPL_PRINT + Printing information about a FIT image adds quite a bit of + code to SPL. So this is normally disabled in SPL. Use this + option to re-enable it. This will affect the output of the + bootm command when booting a FIT image. + +- TPL framework + CONFIG_TPL + Enable building of TPL globally. + + CONFIG_TPL_PAD_TO + Image offset to which the TPL should be padded before appending + the TPL payload. By default, this is defined as + CONFIG_SPL_MAX_SIZE, or 0 if CONFIG_SPL_MAX_SIZE is undefined. + CONFIG_SPL_PAD_TO must be either 0, meaning to append the SPL + payload without any padding, or >= CONFIG_SPL_MAX_SIZE. + +Modem Support: +-------------- + +[so far only for SMDK2400 boards] + +- Modem support enable: + CONFIG_MODEM_SUPPORT + +- RTS/CTS Flow control enable: + CONFIG_HWFLOW + +- Modem debug support: + CONFIG_MODEM_SUPPORT_DEBUG + + Enables debugging stuff (char screen[1024], dbg()) + for modem support. Useful only with BDI2000. + +- Interrupt support (PPC): + + There are common interrupt_init() and timer_interrupt() + for all PPC archs. interrupt_init() calls interrupt_init_cpu() + for CPU specific initialization. interrupt_init_cpu() + should set decrementer_count to appropriate value. If + CPU resets decrementer automatically after interrupt + (ppc4xx) it should set decrementer_count to zero. + timer_interrupt() calls timer_interrupt_cpu() for CPU + specific handling. If board has watchdog / status_led + / other_activity_monitor it works automatically from + general timer_interrupt(). + +- General: + + In the target system modem support is enabled when a + specific key (key combination) is pressed during + power-on. Otherwise U-Boot will boot normally + (autoboot). The key_pressed() function is called from + board_init(). Currently key_pressed() is a dummy + function, returning 1 and thus enabling modem + initialization. + + If there are no modem init strings in the + environment, U-Boot proceed to autoboot; the + previous output (banner, info printfs) will be + suppressed, though. + + See also: doc/README.Modem + +Board initialization settings: +------------------------------ + +During Initialization u-boot calls a number of board specific functions +to allow the preparation of board specific prerequisites, e.g. pin setup +before drivers are initialized. To enable these callbacks the +following configuration macros have to be defined. Currently this is +architecture specific, so please check arch/your_architecture/lib/board.c +typically in board_init_f() and board_init_r(). + +- CONFIG_BOARD_EARLY_INIT_F: Call board_early_init_f() +- CONFIG_BOARD_EARLY_INIT_R: Call board_early_init_r() +- CONFIG_BOARD_LATE_INIT: Call board_late_init() +- CONFIG_BOARD_POSTCLK_INIT: Call board_postclk_init() + +Configuration Settings: +----------------------- + +- CONFIG_SYS_SUPPORT_64BIT_DATA: Defined automatically if compiled as 64-bit. + Optionally it can be defined to support 64-bit memory commands. + +- CONFIG_SYS_LONGHELP: Defined when you want long help messages included; + undefine this when you're short of memory. + +- CONFIG_SYS_HELP_CMD_WIDTH: Defined when you want to override the default + width of the commands listed in the 'help' command output. + +- CONFIG_SYS_PROMPT: This is what U-Boot prints on the console to + prompt for user input. + +- CONFIG_SYS_CBSIZE: Buffer size for input from the Console + +- CONFIG_SYS_PBSIZE: Buffer size for Console output + +- CONFIG_SYS_MAXARGS: max. Number of arguments accepted for monitor commands + +- CONFIG_SYS_BARGSIZE: Buffer size for Boot Arguments which are passed to + the application (usually a Linux kernel) when it is + booted + +- CONFIG_SYS_BAUDRATE_TABLE: + List of legal baudrate settings for this board. + +- CONFIG_SYS_CONSOLE_INFO_QUIET + Suppress display of console information at boot. + +- CONFIG_SYS_CONSOLE_IS_IN_ENV + If the board specific function + extern int overwrite_console (void); + returns 1, the stdin, stderr and stdout are switched to the + serial port, else the settings in the environment are used. + +- CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE + Enable the call to overwrite_console(). + +- CONFIG_SYS_CONSOLE_ENV_OVERWRITE + Enable overwrite of previous console environment settings. + +- CONFIG_SYS_MEMTEST_START, CONFIG_SYS_MEMTEST_END: + Begin and End addresses of the area used by the + simple memory test. + +- CONFIG_SYS_ALT_MEMTEST: + Enable an alternate, more extensive memory test. + +- CONFIG_SYS_MEMTEST_SCRATCH: + Scratch address used by the alternate memory test + You only need to set this if address zero isn't writeable + +- CONFIG_SYS_MEM_TOP_HIDE (PPC only): + If CONFIG_SYS_MEM_TOP_HIDE is defined in the board config header, + this specified memory area will get subtracted from the top + (end) of RAM and won't get "touched" at all by U-Boot. By + fixing up gd->ram_size the Linux kernel should gets passed + the now "corrected" memory size and won't touch it either. + This should work for arch/ppc and arch/powerpc. Only Linux + board ports in arch/powerpc with bootwrapper support that + recalculate the memory size from the SDRAM controller setup + will have to get fixed in Linux additionally. + + This option can be used as a workaround for the 440EPx/GRx + CHIP 11 errata where the last 256 bytes in SDRAM shouldn't + be touched. + + WARNING: Please make sure that this value is a multiple of + the Linux page size (normally 4k). If this is not the case, + then the end address of the Linux memory will be located at a + non page size aligned address and this could cause major + problems. + +- CONFIG_SYS_LOADS_BAUD_CHANGE: + Enable temporary baudrate change while serial download + +- CONFIG_SYS_SDRAM_BASE: + Physical start address of SDRAM. _Must_ be 0 here. + +- CONFIG_SYS_MBIO_BASE: + Physical start address of Motherboard I/O (if using a + Cogent motherboard) + +- CONFIG_SYS_FLASH_BASE: + Physical start address of Flash memory. + +- CONFIG_SYS_MONITOR_BASE: + Physical start address of boot monitor code (set by + make config files to be same as the text base address + (CONFIG_SYS_TEXT_BASE) used when linking) - same as + CONFIG_SYS_FLASH_BASE when booting from flash. + +- CONFIG_SYS_MONITOR_LEN: + Size of memory reserved for monitor code, used to + determine _at_compile_time_ (!) if the environment is + embedded within the U-Boot image, or in a separate + flash sector. + +- CONFIG_SYS_MALLOC_LEN: + Size of DRAM reserved for malloc() use. + +- CONFIG_SYS_MALLOC_F_LEN + Size of the malloc() pool for use before relocation. If + this is defined, then a very simple malloc() implementation + will become available before relocation. The address is just + below the global data, and the stack is moved down to make + space. + + This feature allocates regions with increasing addresses + within the region. calloc() is supported, but realloc() + is not available. free() is supported but does nothing. + The memory will be freed (or in fact just forgotten) when + U-Boot relocates itself. + + Pre-relocation malloc() is only supported on ARM and sandbox + at present but is fairly easy to enable for other archs. + +- CONFIG_SYS_MALLOC_SIMPLE + Provides a simple and small malloc() and calloc() for those + boards which do not use the full malloc in SPL (which is + enabled with CONFIG_SYS_SPL_MALLOC_START). + +- CONFIG_SYS_NONCACHED_MEMORY: + Size of non-cached memory area. This area of memory will be + typically located right below the malloc() area and mapped + uncached in the MMU. This is useful for drivers that would + otherwise require a lot of explicit cache maintenance. For + some drivers it's also impossible to properly maintain the + cache. For example if the regions that need to be flushed + are not a multiple of the cache-line size, *and* padding + cannot be allocated between the regions to align them (i.e. + if the HW requires a contiguous array of regions, and the + size of each region is not cache-aligned), then a flush of + one region may result in overwriting data that hardware has + written to another region in the same cache-line. This can + happen for example in network drivers where descriptors for + buffers are typically smaller than the CPU cache-line (e.g. + 16 bytes vs. 32 or 64 bytes). + + Non-cached memory is only supported on 32-bit ARM at present. + +- CONFIG_SYS_BOOTM_LEN: + Normally compressed uImages are limited to an + uncompressed size of 8 MBytes. If this is not enough, + you can define CONFIG_SYS_BOOTM_LEN in your board config file + to adjust this setting to your needs. + +- CONFIG_SYS_BOOTMAPSZ: + Maximum size of memory mapped by the startup code of + the Linux kernel; all data that must be processed by + the Linux kernel (bd_info, boot arguments, FDT blob if + used) must be put below this limit, unless "bootm_low" + environment variable is defined and non-zero. In such case + all data for the Linux kernel must be between "bootm_low" + and "bootm_low" + CONFIG_SYS_BOOTMAPSZ. The environment + variable "bootm_mapsize" will override the value of + CONFIG_SYS_BOOTMAPSZ. If CONFIG_SYS_BOOTMAPSZ is undefined, + then the value in "bootm_size" will be used instead. + +- CONFIG_SYS_BOOT_RAMDISK_HIGH: + Enable initrd_high functionality. If defined then the + initrd_high feature is enabled and the bootm ramdisk subcommand + is enabled. + +- CONFIG_SYS_BOOT_GET_CMDLINE: + Enables allocating and saving kernel cmdline in space between + "bootm_low" and "bootm_low" + BOOTMAPSZ. + +- CONFIG_SYS_BOOT_GET_KBD: + Enables allocating and saving a kernel copy of the bd_info in + space between "bootm_low" and "bootm_low" + BOOTMAPSZ. + +- CONFIG_SYS_MAX_FLASH_BANKS: + Max number of Flash memory banks + +- CONFIG_SYS_MAX_FLASH_SECT: + Max number of sectors on a Flash chip + +- CONFIG_SYS_FLASH_ERASE_TOUT: + Timeout for Flash erase operations (in ms) + +- CONFIG_SYS_FLASH_WRITE_TOUT: + Timeout for Flash write operations (in ms) + +- CONFIG_SYS_FLASH_LOCK_TOUT + Timeout for Flash set sector lock bit operation (in ms) + +- CONFIG_SYS_FLASH_UNLOCK_TOUT + Timeout for Flash clear lock bits operation (in ms) + +- CONFIG_SYS_FLASH_PROTECTION + If defined, hardware flash sectors protection is used + instead of U-Boot software protection. + +- CONFIG_SYS_DIRECT_FLASH_TFTP: + + Enable TFTP transfers directly to flash memory; + without this option such a download has to be + performed in two steps: (1) download to RAM, and (2) + copy from RAM to flash. + + The two-step approach is usually more reliable, since + you can check if the download worked before you erase + the flash, but in some situations (when system RAM is + too limited to allow for a temporary copy of the + downloaded image) this option may be very useful. + +- CONFIG_SYS_FLASH_CFI: + Define if the flash driver uses extra elements in the + common flash structure for storing flash geometry. + +- CONFIG_FLASH_CFI_DRIVER + This option also enables the building of the cfi_flash driver + in the drivers directory + +- CONFIG_FLASH_CFI_MTD + This option enables the building of the cfi_mtd driver + in the drivers directory. The driver exports CFI flash + to the MTD layer. + +- CONFIG_SYS_FLASH_USE_BUFFER_WRITE + Use buffered writes to flash. + +- CONFIG_FLASH_SPANSION_S29WS_N + s29ws-n MirrorBit flash has non-standard addresses for buffered + write commands. + +- CONFIG_SYS_FLASH_QUIET_TEST + If this option is defined, the common CFI flash doesn't + print it's warning upon not recognized FLASH banks. This + is useful, if some of the configured banks are only + optionally available. + +- CONFIG_FLASH_SHOW_PROGRESS + If defined (must be an integer), print out countdown + digits and dots. Recommended value: 45 (9..1) for 80 + column displays, 15 (3..1) for 40 column displays. + +- CONFIG_FLASH_VERIFY + If defined, the content of the flash (destination) is compared + against the source after the write operation. An error message + will be printed when the contents are not identical. + Please note that this option is useless in nearly all cases, + since such flash programming errors usually are detected earlier + while unprotecting/erasing/programming. Please only enable + this option if you really know what you are doing. + +- CONFIG_SYS_RX_ETH_BUFFER: + Defines the number of Ethernet receive buffers. On some + Ethernet controllers it is recommended to set this value + to 8 or even higher (EEPRO100 or 405 EMAC), since all + buffers can be full shortly after enabling the interface + on high Ethernet traffic. + Defaults to 4 if not defined. + +- CONFIG_ENV_MAX_ENTRIES + + Maximum number of entries in the hash table that is used + internally to store the environment settings. The default + setting is supposed to be generous and should work in most + cases. This setting can be used to tune behaviour; see + lib/hashtable.c for details. + +- CONFIG_ENV_FLAGS_LIST_DEFAULT +- CONFIG_ENV_FLAGS_LIST_STATIC + Enable validation of the values given to environment variables when + calling env set. Variables can be restricted to only decimal, + hexadecimal, or boolean. If CONFIG_CMD_NET is also defined, + the variables can also be restricted to IP address or MAC address. + + The format of the list is: + type_attribute = [s|d|x|b|i|m] + access_attribute = [a|r|o|c] + attributes = type_attribute[access_attribute] + entry = variable_name[:attributes] + list = entry[,list] + + The type attributes are: + s - String (default) + d - Decimal + x - Hexadecimal + b - Boolean ([1yYtT|0nNfF]) + i - IP address + m - MAC address + + The access attributes are: + a - Any (default) + r - Read-only + o - Write-once + c - Change-default + + - CONFIG_ENV_FLAGS_LIST_DEFAULT + Define this to a list (string) to define the ".flags" + environment variable in the default or embedded environment. + + - CONFIG_ENV_FLAGS_LIST_STATIC + Define this to a list (string) to define validation that + should be done if an entry is not found in the ".flags" + environment variable. To override a setting in the static + list, simply add an entry for the same variable name to the + ".flags" variable. + +- CONFIG_ENV_ACCESS_IGNORE_FORCE + If defined, don't allow the -f switch to env set override variable + access flags. + +- CONFIG_SYS_GENERIC_BOARD + This selects the architecture-generic board system instead of the + architecture-specific board files. It is intended to move boards + to this new framework over time. Defining this will disable the + arch/foo/lib/board.c file and use common/board_f.c and + common/board_r.c instead. To use this option your architecture + must support it (i.e. must select HAVE_GENERIC_BOARD in arch/Kconfig). + If you find problems enabling this option on your board please report + the problem and send patches! + +- CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC (OMAP only) + This is set by OMAP boards for the max time that reset should + be asserted. See doc/README.omap-reset-time for details on how + the value can be calculated on a given board. + +- CONFIG_USE_STDINT + If stdint.h is available with your toolchain you can define this + option to enable it. You can provide option 'USE_STDINT=1' when + building U-Boot to enable this. + +The following definitions that deal with the placement and management +of environment data (variable area); in general, we support the +following configurations: + +- CONFIG_BUILD_ENVCRC: + + Builds up envcrc with the target environment so that external utils + may easily extract it and embed it in final U-Boot images. + +- CONFIG_ENV_IS_IN_FLASH: + + Define this if the environment is in flash memory. + + a) The environment occupies one whole flash sector, which is + "embedded" in the text segment with the U-Boot code. This + happens usually with "bottom boot sector" or "top boot + sector" type flash chips, which have several smaller + sectors at the start or the end. For instance, such a + layout can have sector sizes of 8, 2x4, 16, Nx32 kB. In + such a case you would place the environment in one of the + 4 kB sectors - with U-Boot code before and after it. With + "top boot sector" type flash chips, you would put the + environment in one of the last sectors, leaving a gap + between U-Boot and the environment. + + - CONFIG_ENV_OFFSET: + + Offset of environment data (variable area) to the + beginning of flash memory; for instance, with bottom boot + type flash chips the second sector can be used: the offset + for this sector is given here. + + CONFIG_ENV_OFFSET is used relative to CONFIG_SYS_FLASH_BASE. + + - CONFIG_ENV_ADDR: + + This is just another way to specify the start address of + the flash sector containing the environment (instead of + CONFIG_ENV_OFFSET). + + - CONFIG_ENV_SECT_SIZE: + + Size of the sector containing the environment. + + + b) Sometimes flash chips have few, equal sized, BIG sectors. + In such a case you don't want to spend a whole sector for + the environment. + + - CONFIG_ENV_SIZE: + + If you use this in combination with CONFIG_ENV_IS_IN_FLASH + and CONFIG_ENV_SECT_SIZE, you can specify to use only a part + of this flash sector for the environment. This saves + memory for the RAM copy of the environment. + + It may also save flash memory if you decide to use this + when your environment is "embedded" within U-Boot code, + since then the remainder of the flash sector could be used + for U-Boot code. It should be pointed out that this is + STRONGLY DISCOURAGED from a robustness point of view: + updating the environment in flash makes it always + necessary to erase the WHOLE sector. If something goes + wrong before the contents has been restored from a copy in + RAM, your target system will be dead. + + - CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SIZE_REDUND + + These settings describe a second storage area used to hold + a redundant copy of the environment data, so that there is + a valid backup copy in case there is a power failure during + a "saveenv" operation. + +BE CAREFUL! Any changes to the flash layout, and some changes to the +source code will make it necessary to adapt <board>/u-boot.lds* +accordingly! + + +- CONFIG_ENV_IS_IN_NVRAM: + + Define this if you have some non-volatile memory device + (NVRAM, battery buffered SRAM) which you want to use for the + environment. + + - CONFIG_ENV_ADDR: + - CONFIG_ENV_SIZE: + + These two #defines are used to determine the memory area you + want to use for environment. It is assumed that this memory + can just be read and written to, without any special + provision. + +BE CAREFUL! The first access to the environment happens quite early +in U-Boot initialization (when we try to get the setting of for the +console baudrate). You *MUST* have mapped your NVRAM area then, or +U-Boot will hang. + +Please note that even with NVRAM we still use a copy of the +environment in RAM: we could work on NVRAM directly, but we want to +keep settings there always unmodified except somebody uses "saveenv" +to save the current settings. + + +- CONFIG_ENV_IS_IN_EEPROM: + + Use this if you have an EEPROM or similar serial access + device and a driver for it. + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_SIZE: + + These two #defines specify the offset and size of the + environment area within the total memory of your EEPROM. + + - CONFIG_SYS_I2C_EEPROM_ADDR: + If defined, specified the chip address of the EEPROM device. + The default address is zero. + + - CONFIG_SYS_I2C_EEPROM_BUS: + If defined, specified the i2c bus of the EEPROM device. + + - CONFIG_SYS_EEPROM_PAGE_WRITE_BITS: + If defined, the number of bits used to address bytes in a + single page in the EEPROM device. A 64 byte page, for example + would require six bits. + + - CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS: + If defined, the number of milliseconds to delay between + page writes. The default is zero milliseconds. + + - CONFIG_SYS_I2C_EEPROM_ADDR_LEN: + The length in bytes of the EEPROM memory array address. Note + that this is NOT the chip address length! + + - CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW: + EEPROM chips that implement "address overflow" are ones + like Catalyst 24WC04/08/16 which has 9/10/11 bits of + address and the extra bits end up in the "chip address" bit + slots. This makes a 24WC08 (1Kbyte) chip look like four 256 + byte chips. + + Note that we consider the length of the address field to + still be one byte because the extra address bits are hidden + in the chip address. + + - CONFIG_SYS_EEPROM_SIZE: + The size in bytes of the EEPROM device. + + - CONFIG_ENV_EEPROM_IS_ON_I2C + define this, if you have I2C and SPI activated, and your + EEPROM, which holds the environment, is on the I2C bus. + + - CONFIG_I2C_ENV_EEPROM_BUS + if you have an Environment on an EEPROM reached over + I2C muxes, you can define here, how to reach this + EEPROM. For example: + + #define CONFIG_I2C_ENV_EEPROM_BUS 1 + + EEPROM which holds the environment, is reached over + a pca9547 i2c mux with address 0x70, channel 3. + +- CONFIG_ENV_IS_IN_DATAFLASH: + + Define this if you have a DataFlash memory device which you + want to use for the environment. + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_ADDR: + - CONFIG_ENV_SIZE: + + These three #defines specify the offset and size of the + environment area within the total memory of your DataFlash placed + at the specified address. + +- CONFIG_ENV_IS_IN_SPI_FLASH: + + Define this if you have a SPI Flash memory device which you + want to use for the environment. + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_SIZE: + + These two #defines specify the offset and size of the + environment area within the SPI Flash. CONFIG_ENV_OFFSET must be + aligned to an erase sector boundary. + + - CONFIG_ENV_SECT_SIZE: + + Define the SPI flash's sector size. + + - CONFIG_ENV_OFFSET_REDUND (optional): + + This setting describes a second storage area of CONFIG_ENV_SIZE + size used to hold a redundant copy of the environment data, so + that there is a valid backup copy in case there is a power failure + during a "saveenv" operation. CONFIG_ENV_OFFSET_RENDUND must be + aligned to an erase sector boundary. + + - CONFIG_ENV_SPI_BUS (optional): + - CONFIG_ENV_SPI_CS (optional): + + Define the SPI bus and chip select. If not defined they will be 0. + + - CONFIG_ENV_SPI_MAX_HZ (optional): + + Define the SPI max work clock. If not defined then use 1MHz. + + - CONFIG_ENV_SPI_MODE (optional): + + Define the SPI work mode. If not defined then use SPI_MODE_3. + +- CONFIG_ENV_IS_IN_REMOTE: + + Define this if you have a remote memory space which you + want to use for the local device's environment. + + - CONFIG_ENV_ADDR: + - CONFIG_ENV_SIZE: + + These two #defines specify the address and size of the + environment area within the remote memory space. The + local device can get the environment from remote memory + space by SRIO or PCIE links. + +BE CAREFUL! For some special cases, the local device can not use +"saveenv" command. For example, the local device will get the +environment stored in a remote NOR flash by SRIO or PCIE link, +but it can not erase, write this NOR flash by SRIO or PCIE interface. + +- CONFIG_ENV_IS_IN_NAND: + + Define this if you have a NAND device which you want to use + for the environment. + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_SIZE: + + These two #defines specify the offset and size of the environment + area within the first NAND device. CONFIG_ENV_OFFSET must be + aligned to an erase block boundary. + + - CONFIG_ENV_OFFSET_REDUND (optional): + + This setting describes a second storage area of CONFIG_ENV_SIZE + size used to hold a redundant copy of the environment data, so + that there is a valid backup copy in case there is a power failure + during a "saveenv" operation. CONFIG_ENV_OFFSET_RENDUND must be + aligned to an erase block boundary. + + - CONFIG_ENV_RANGE (optional): + + Specifies the length of the region in which the environment + can be written. This should be a multiple of the NAND device's + block size. Specifying a range with more erase blocks than + are needed to hold CONFIG_ENV_SIZE allows bad blocks within + the range to be avoided. + + - CONFIG_ENV_OFFSET_OOB (optional): + + Enables support for dynamically retrieving the offset of the + environment from block zero's out-of-band data. The + "nand env.oob" command can be used to record this offset. + Currently, CONFIG_ENV_OFFSET_REDUND is not supported when + using CONFIG_ENV_OFFSET_OOB. + +- CONFIG_NAND_ENV_DST + + Defines address in RAM to which the nand_spl code should copy the + environment. If redundant environment is used, it will be copied to + CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE. + +- CONFIG_ENV_IS_IN_UBI: + + Define this if you have an UBI volume that you want to use for the + environment. This has the benefit of wear-leveling the environment + accesses, which is important on NAND. + + - CONFIG_ENV_UBI_PART: + + Define this to a string that is the mtd partition containing the UBI. + + - CONFIG_ENV_UBI_VOLUME: + + Define this to the name of the volume that you want to store the + environment in. + + - CONFIG_ENV_UBI_VOLUME_REDUND: + + Define this to the name of another volume to store a second copy of + the environment in. This will enable redundant environments in UBI. + It is assumed that both volumes are in the same MTD partition. + + - CONFIG_UBI_SILENCE_MSG + - CONFIG_UBIFS_SILENCE_MSG + + You will probably want to define these to avoid a really noisy system + when storing the env in UBI. + +- CONFIG_ENV_IS_IN_FAT: + Define this if you want to use the FAT file system for the environment. + + - FAT_ENV_INTERFACE: + + Define this to a string that is the name of the block device. + + - FAT_ENV_DEV_AND_PART: + + Define this to a string to specify the partition of the device. It can + be as following: + + "D:P", "D:0", "D", "D:" or "D:auto" (D, P are integers. And P >= 1) + - "D:P": device D partition P. Error occurs if device D has no + partition table. + - "D:0": device D. + - "D" or "D:": device D partition 1 if device D has partition + table, or the whole device D if has no partition + table. + - "D:auto": first partition in device D with bootable flag set. + If none, first valid partition in device D. If no + partition table then means device D. + + - FAT_ENV_FILE: + + It's a string of the FAT file name. This file use to store the + environment. + + - CONFIG_FAT_WRITE: + This should be defined. Otherwise it cannot save the environment file. + +- CONFIG_ENV_IS_IN_MMC: + + Define this if you have an MMC device which you want to use for the + environment. + + - CONFIG_SYS_MMC_ENV_DEV: + + Specifies which MMC device the environment is stored in. + + - CONFIG_SYS_MMC_ENV_PART (optional): + + Specifies which MMC partition the environment is stored in. If not + set, defaults to partition 0, the user area. Common values might be + 1 (first MMC boot partition), 2 (second MMC boot partition). + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_SIZE: + + These two #defines specify the offset and size of the environment + area within the specified MMC device. + + If offset is positive (the usual case), it is treated as relative to + the start of the MMC partition. If offset is negative, it is treated + as relative to the end of the MMC partition. This can be useful if + your board may be fitted with different MMC devices, which have + different sizes for the MMC partitions, and you always want the + environment placed at the very end of the partition, to leave the + maximum possible space before it, to store other data. + + These two values are in units of bytes, but must be aligned to an + MMC sector boundary. + + - CONFIG_ENV_OFFSET_REDUND (optional): + + Specifies a second storage area, of CONFIG_ENV_SIZE size, used to + hold a redundant copy of the environment data. This provides a + valid backup copy in case the other copy is corrupted, e.g. due + to a power failure during a "saveenv" operation. + + This value may also be positive or negative; this is handled in the + same way as CONFIG_ENV_OFFSET. + + This value is also in units of bytes, but must also be aligned to + an MMC sector boundary. + + - CONFIG_ENV_SIZE_REDUND (optional): + + This value need not be set, even when CONFIG_ENV_OFFSET_REDUND is + set. If this value is set, it must be set to the same value as + CONFIG_ENV_SIZE. + +- CONFIG_SYS_SPI_INIT_OFFSET + + Defines offset to the initial SPI buffer area in DPRAM. The + area is used at an early stage (ROM part) if the environment + is configured to reside in the SPI EEPROM: We need a 520 byte + scratch DPRAM area. It is used between the two initialization + calls (spi_init_f() and spi_init_r()). A value of 0xB00 seems + to be a good choice since it makes it far enough from the + start of the data area as well as from the stack pointer. + +Please note that the environment is read-only until the monitor +has been relocated to RAM and a RAM copy of the environment has been +created; also, when using EEPROM you will have to use getenv_f() +until then to read environment variables. + +The environment is protected by a CRC32 checksum. Before the monitor +is relocated into RAM, as a result of a bad CRC you will be working +with the compiled-in default environment - *silently*!!! [This is +necessary, because the first environment variable we need is the +"baudrate" setting for the console - if we have a bad CRC, we don't +have any device yet where we could complain.] + +Note: once the monitor has been relocated, then it will complain if +the default environment is used; a new CRC is computed as soon as you +use the "saveenv" command to store a valid environment. + +- CONFIG_SYS_FAULT_ECHO_LINK_DOWN: + Echo the inverted Ethernet link state to the fault LED. + + Note: If this option is active, then CONFIG_SYS_FAULT_MII_ADDR + also needs to be defined. + +- CONFIG_SYS_FAULT_MII_ADDR: + MII address of the PHY to check for the Ethernet link state. + +- CONFIG_NS16550_MIN_FUNCTIONS: + Define this if you desire to only have use of the NS16550_init + and NS16550_putc functions for the serial driver located at + drivers/serial/ns16550.c. This option is useful for saving + space for already greatly restricted images, including but not + limited to NAND_SPL configurations. + +- CONFIG_DISPLAY_BOARDINFO + Display information about the board that U-Boot is running on + when U-Boot starts up. The board function checkboard() is called + to do this. + +- CONFIG_DISPLAY_BOARDINFO_LATE + Similar to the previous option, but display this information + later, once stdio is running and output goes to the LCD, if + present. + +- CONFIG_BOARD_SIZE_LIMIT: + Maximum size of the U-Boot image. When defined, the + build system checks that the actual size does not + exceed it. + +Low Level (hardware related) configuration options: +--------------------------------------------------- + +- CONFIG_SYS_CACHELINE_SIZE: + Cache Line Size of the CPU. + +- CONFIG_SYS_DEFAULT_IMMR: + Default address of the IMMR after system reset. + + Needed on some 8260 systems (MPC8260ADS, PQ2FADS-ZU, + and RPXsuper) to be able to adjust the position of + the IMMR register after a reset. + +- CONFIG_SYS_CCSRBAR_DEFAULT: + Default (power-on reset) physical address of CCSR on Freescale + PowerPC SOCs. + +- CONFIG_SYS_CCSRBAR: + Virtual address of CCSR. On a 32-bit build, this is typically + the same value as CONFIG_SYS_CCSRBAR_DEFAULT. + + CONFIG_SYS_DEFAULT_IMMR must also be set to this value, + for cross-platform code that uses that macro instead. + +- CONFIG_SYS_CCSRBAR_PHYS: + Physical address of CCSR. CCSR can be relocated to a new + physical address, if desired. In this case, this macro should + be set to that address. Otherwise, it should be set to the + same value as CONFIG_SYS_CCSRBAR_DEFAULT. For example, CCSR + is typically relocated on 36-bit builds. It is recommended + that this macro be defined via the _HIGH and _LOW macros: + + #define CONFIG_SYS_CCSRBAR_PHYS ((CONFIG_SYS_CCSRBAR_PHYS_HIGH + * 1ull) << 32 | CONFIG_SYS_CCSRBAR_PHYS_LOW) + +- CONFIG_SYS_CCSRBAR_PHYS_HIGH: + Bits 33-36 of CONFIG_SYS_CCSRBAR_PHYS. This value is typically + either 0 (32-bit build) or 0xF (36-bit build). This macro is + used in assembly code, so it must not contain typecasts or + integer size suffixes (e.g. "ULL"). + +- CONFIG_SYS_CCSRBAR_PHYS_LOW: + Lower 32-bits of CONFIG_SYS_CCSRBAR_PHYS. This macro is + used in assembly code, so it must not contain typecasts or + integer size suffixes (e.g. "ULL"). + +- CONFIG_SYS_CCSR_DO_NOT_RELOCATE: + If this macro is defined, then CONFIG_SYS_CCSRBAR_PHYS will be + forced to a value that ensures that CCSR is not relocated. + +- Floppy Disk Support: + CONFIG_SYS_FDC_DRIVE_NUMBER + + the default drive number (default value 0) + + CONFIG_SYS_ISA_IO_STRIDE + + defines the spacing between FDC chipset registers + (default value 1) + + CONFIG_SYS_ISA_IO_OFFSET + + defines the offset of register from address. It + depends on which part of the data bus is connected to + the FDC chipset. (default value 0) + + If CONFIG_SYS_ISA_IO_STRIDE CONFIG_SYS_ISA_IO_OFFSET and + CONFIG_SYS_FDC_DRIVE_NUMBER are undefined, they take their + default value. + + if CONFIG_SYS_FDC_HW_INIT is defined, then the function + fdc_hw_init() is called at the beginning of the FDC + setup. fdc_hw_init() must be provided by the board + source code. It is used to make hardware-dependent + initializations. + +- CONFIG_IDE_AHB: + Most IDE controllers were designed to be connected with PCI + interface. Only few of them were designed for AHB interface. + When software is doing ATA command and data transfer to + IDE devices through IDE-AHB controller, some additional + registers accessing to these kind of IDE-AHB controller + is required. + +- CONFIG_SYS_IMMR: Physical address of the Internal Memory. + DO NOT CHANGE unless you know exactly what you're + doing! (11-4) [MPC8xx/82xx systems only] + +- CONFIG_SYS_INIT_RAM_ADDR: + + Start address of memory area that can be used for + initial data and stack; please note that this must be + writable memory that is working WITHOUT special + initialization, i. e. you CANNOT use normal RAM which + will become available only after programming the + memory controller and running certain initialization + sequences. + + U-Boot uses the following memory types: + - MPC8xx and MPC8260: IMMR (internal memory of the CPU) + - MPC824X: data cache + - PPC4xx: data cache + +- CONFIG_SYS_GBL_DATA_OFFSET: + + Offset of the initial data structure in the memory + area defined by CONFIG_SYS_INIT_RAM_ADDR. Usually + CONFIG_SYS_GBL_DATA_OFFSET is chosen such that the initial + data is located at the end of the available space + (sometimes written as (CONFIG_SYS_INIT_RAM_SIZE - + CONFIG_SYS_INIT_DATA_SIZE), and the initial stack is just + below that area (growing from (CONFIG_SYS_INIT_RAM_ADDR + + CONFIG_SYS_GBL_DATA_OFFSET) downward. + + Note: + On the MPC824X (or other systems that use the data + cache for initial memory) the address chosen for + CONFIG_SYS_INIT_RAM_ADDR is basically arbitrary - it must + point to an otherwise UNUSED address space between + the top of RAM and the start of the PCI space. + +- CONFIG_SYS_SIUMCR: SIU Module Configuration (11-6) + +- CONFIG_SYS_SYPCR: System Protection Control (11-9) + +- CONFIG_SYS_TBSCR: Time Base Status and Control (11-26) + +- CONFIG_SYS_PISCR: Periodic Interrupt Status and Control (11-31) + +- CONFIG_SYS_PLPRCR: PLL, Low-Power, and Reset Control Register (15-30) + +- CONFIG_SYS_SCCR: System Clock and reset Control Register (15-27) + +- CONFIG_SYS_OR_TIMING_SDRAM: + SDRAM timing + +- CONFIG_SYS_MAMR_PTA: + periodic timer for refresh + +- CONFIG_SYS_DER: Debug Event Register (37-47) + +- FLASH_BASE0_PRELIM, FLASH_BASE1_PRELIM, CONFIG_SYS_REMAP_OR_AM, + CONFIG_SYS_PRELIM_OR_AM, CONFIG_SYS_OR_TIMING_FLASH, CONFIG_SYS_OR0_REMAP, + CONFIG_SYS_OR0_PRELIM, CONFIG_SYS_BR0_PRELIM, CONFIG_SYS_OR1_REMAP, CONFIG_SYS_OR1_PRELIM, + CONFIG_SYS_BR1_PRELIM: + Memory Controller Definitions: BR0/1 and OR0/1 (FLASH) + +- SDRAM_BASE2_PRELIM, SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE, + CONFIG_SYS_OR_TIMING_SDRAM, CONFIG_SYS_OR2_PRELIM, CONFIG_SYS_BR2_PRELIM, + CONFIG_SYS_OR3_PRELIM, CONFIG_SYS_BR3_PRELIM: + Memory Controller Definitions: BR2/3 and OR2/3 (SDRAM) + +- CONFIG_SYS_MAMR_PTA, CONFIG_SYS_MPTPR_2BK_4K, CONFIG_SYS_MPTPR_1BK_4K, CONFIG_SYS_MPTPR_2BK_8K, + CONFIG_SYS_MPTPR_1BK_8K, CONFIG_SYS_MAMR_8COL, CONFIG_SYS_MAMR_9COL: + Machine Mode Register and Memory Periodic Timer + Prescaler definitions (SDRAM timing) + +- CONFIG_SYS_I2C_UCODE_PATCH, CONFIG_SYS_I2C_DPMEM_OFFSET [0x1FC0]: + enable I2C microcode relocation patch (MPC8xx); + define relocation offset in DPRAM [DSP2] + +- CONFIG_SYS_SMC_UCODE_PATCH, CONFIG_SYS_SMC_DPMEM_OFFSET [0x1FC0]: + enable SMC microcode relocation patch (MPC8xx); + define relocation offset in DPRAM [SMC1] + +- CONFIG_SYS_SPI_UCODE_PATCH, CONFIG_SYS_SPI_DPMEM_OFFSET [0x1FC0]: + enable SPI microcode relocation patch (MPC8xx); + define relocation offset in DPRAM [SCC4] + +- CONFIG_SYS_USE_OSCCLK: + Use OSCM clock mode on MBX8xx board. Be careful, + wrong setting might damage your board. Read + doc/README.MBX before setting this variable! + +- CONFIG_SYS_CPM_POST_WORD_ADDR: (MPC8xx, MPC8260 only) + Offset of the bootmode word in DPRAM used by post + (Power On Self Tests). This definition overrides + #define'd default value in commproc.h resp. + cpm_8260.h. + +- CONFIG_SYS_PCI_SLV_MEM_LOCAL, CONFIG_SYS_PCI_SLV_MEM_BUS, CONFIG_SYS_PICMR0_MASK_ATTRIB, + CONFIG_SYS_PCI_MSTR0_LOCAL, CONFIG_SYS_PCIMSK0_MASK, CONFIG_SYS_PCI_MSTR1_LOCAL, + CONFIG_SYS_PCIMSK1_MASK, CONFIG_SYS_PCI_MSTR_MEM_LOCAL, CONFIG_SYS_PCI_MSTR_MEM_BUS, + CONFIG_SYS_CPU_PCI_MEM_START, CONFIG_SYS_PCI_MSTR_MEM_SIZE, CONFIG_SYS_POCMR0_MASK_ATTRIB, + CONFIG_SYS_PCI_MSTR_MEMIO_LOCAL, CONFIG_SYS_PCI_MSTR_MEMIO_BUS, CPU_PCI_MEMIO_START, + CONFIG_SYS_PCI_MSTR_MEMIO_SIZE, CONFIG_SYS_POCMR1_MASK_ATTRIB, CONFIG_SYS_PCI_MSTR_IO_LOCAL, + CONFIG_SYS_PCI_MSTR_IO_BUS, CONFIG_SYS_CPU_PCI_IO_START, CONFIG_SYS_PCI_MSTR_IO_SIZE, + CONFIG_SYS_POCMR2_MASK_ATTRIB: (MPC826x only) + Overrides the default PCI memory map in arch/powerpc/cpu/mpc8260/pci.c if set. + +- CONFIG_PCI_DISABLE_PCIE: + Disable PCI-Express on systems where it is supported but not + required. + +- CONFIG_PCI_ENUM_ONLY + Only scan through and get the devices on the buses. + Don't do any setup work, presumably because someone or + something has already done it, and we don't need to do it + a second time. Useful for platforms that are pre-booted + by coreboot or similar. + +- CONFIG_PCI_INDIRECT_BRIDGE: + Enable support for indirect PCI bridges. + +- CONFIG_SYS_SRIO: + Chip has SRIO or not + +- CONFIG_SRIO1: + Board has SRIO 1 port available + +- CONFIG_SRIO2: + Board has SRIO 2 port available + +- CONFIG_SRIO_PCIE_BOOT_MASTER + Board can support master function for Boot from SRIO and PCIE + +- CONFIG_SYS_SRIOn_MEM_VIRT: + Virtual Address of SRIO port 'n' memory region + +- CONFIG_SYS_SRIOn_MEM_PHYS: + Physical Address of SRIO port 'n' memory region + +- CONFIG_SYS_SRIOn_MEM_SIZE: + Size of SRIO port 'n' memory region + +- CONFIG_SYS_NAND_BUSWIDTH_16BIT + Defined to tell the NAND controller that the NAND chip is using + a 16 bit bus. + Not all NAND drivers use this symbol. + Example of drivers that use it: + - drivers/mtd/nand/ndfc.c + - drivers/mtd/nand/mxc_nand.c + +- CONFIG_SYS_NDFC_EBC0_CFG + Sets the EBC0_CFG register for the NDFC. If not defined + a default value will be used. + +- CONFIG_SPD_EEPROM + Get DDR timing information from an I2C EEPROM. Common + with pluggable memory modules such as SODIMMs + + SPD_EEPROM_ADDRESS + I2C address of the SPD EEPROM + +- CONFIG_SYS_SPD_BUS_NUM + If SPD EEPROM is on an I2C bus other than the first + one, specify here. Note that the value must resolve + to something your driver can deal with. + +- CONFIG_SYS_DDR_RAW_TIMING + Get DDR timing information from other than SPD. Common with + soldered DDR chips onboard without SPD. DDR raw timing + parameters are extracted from datasheet and hard-coded into + header files or board specific files. + +- CONFIG_FSL_DDR_INTERACTIVE + Enable interactive DDR debugging. See doc/README.fsl-ddr. + +- CONFIG_FSL_DDR_SYNC_REFRESH + Enable sync of refresh for multiple controllers. + +- CONFIG_SYS_83XX_DDR_USES_CS0 + Only for 83xx systems. If specified, then DDR should + be configured using CS0 and CS1 instead of CS2 and CS3. + +- CONFIG_ETHER_ON_FEC[12] + Define to enable FEC[12] on a 8xx series processor. + +- CONFIG_FEC[12]_PHY + Define to the hardcoded PHY address which corresponds + to the given FEC; i. e. + #define CONFIG_FEC1_PHY 4 + means that the PHY with address 4 is connected to FEC1 + + When set to -1, means to probe for first available. + +- CONFIG_FEC[12]_PHY_NORXERR + The PHY does not have a RXERR line (RMII only). + (so program the FEC to ignore it). + +- CONFIG_RMII + Enable RMII mode for all FECs. + Note that this is a global option, we can't + have one FEC in standard MII mode and another in RMII mode. + +- CONFIG_CRC32_VERIFY + Add a verify option to the crc32 command. + The syntax is: + + => crc32 -v <address> <count> <crc32> + + Where address/count indicate a memory area + and crc32 is the correct crc32 which the + area should have. + +- CONFIG_LOOPW + Add the "loopw" memory command. This only takes effect if + the memory commands are activated globally (CONFIG_CMD_MEM). + +- CONFIG_MX_CYCLIC + Add the "mdc" and "mwc" memory commands. These are cyclic + "md/mw" commands. + Examples: + + => mdc.b 10 4 500 + This command will print 4 bytes (10,11,12,13) each 500 ms. + + => mwc.l 100 12345678 10 + This command will write 12345678 to address 100 all 10 ms. + + This only takes effect if the memory commands are activated + globally (CONFIG_CMD_MEM). + +- CONFIG_SKIP_LOWLEVEL_INIT + [ARM, NDS32, MIPS only] If this variable is defined, then certain + low level initializations (like setting up the memory + controller) are omitted and/or U-Boot does not + relocate itself into RAM. + + Normally this variable MUST NOT be defined. The only + exception is when U-Boot is loaded (to RAM) by some + other boot loader or by a debugger which performs + these initializations itself. + +- CONFIG_SPL_BUILD + Modifies the behaviour of start.S when compiling a loader + that is executed before the actual U-Boot. E.g. when + compiling a NAND SPL. + +- CONFIG_TPL_BUILD + Modifies the behaviour of start.S when compiling a loader + that is executed after the SPL and before the actual U-Boot. + It is loaded by the SPL. + +- CONFIG_SYS_MPC85XX_NO_RESETVEC + Only for 85xx systems. If this variable is specified, the section + .resetvec is not kept and the section .bootpg is placed in the + previous 4k of the .text section. + +- CONFIG_ARCH_MAP_SYSMEM + Generally U-Boot (and in particular the md command) uses + effective address. It is therefore not necessary to regard + U-Boot address as virtual addresses that need to be translated + to physical addresses. However, sandbox requires this, since + it maintains its own little RAM buffer which contains all + addressable memory. This option causes some memory accesses + to be mapped through map_sysmem() / unmap_sysmem(). + +- CONFIG_USE_ARCH_MEMCPY + CONFIG_USE_ARCH_MEMSET + If these options are used a optimized version of memcpy/memset will + be used if available. These functions may be faster under some + conditions but may increase the binary size. + +- CONFIG_X86_RESET_VECTOR + If defined, the x86 reset vector code is included. This is not + needed when U-Boot is running from Coreboot. + +- CONFIG_SYS_MPUCLK + Defines the MPU clock speed (in MHz). + + NOTE : currently only supported on AM335x platforms. + +- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC: + Enables the RTC32K OSC on AM33xx based plattforms + +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE + Option to disable subpage write in NAND driver + driver that uses this: + drivers/mtd/nand/davinci_nand.c + +Freescale QE/FMAN Firmware Support: +----------------------------------- + +The Freescale QUICCEngine (QE) and Frame Manager (FMAN) both support the +loading of "firmware", which is encoded in the QE firmware binary format. +This firmware often needs to be loaded during U-Boot booting, so macros +are used to identify the storage device (NOR flash, SPI, etc) and the address +within that device. + +- CONFIG_SYS_FMAN_FW_ADDR + The address in the storage device where the FMAN microcode is located. The + meaning of this address depends on which CONFIG_SYS_QE_FW_IN_xxx macro + is also specified. + +- CONFIG_SYS_QE_FW_ADDR + The address in the storage device where the QE microcode is located. The + meaning of this address depends on which CONFIG_SYS_QE_FW_IN_xxx macro + is also specified. + +- CONFIG_SYS_QE_FMAN_FW_LENGTH + The maximum possible size of the firmware. The firmware binary format + has a field that specifies the actual size of the firmware, but it + might not be possible to read any part of the firmware unless some + local storage is allocated to hold the entire firmware first. + +- CONFIG_SYS_QE_FMAN_FW_IN_NOR + Specifies that QE/FMAN firmware is located in NOR flash, mapped as + normal addressable memory via the LBC. CONFIG_SYS_FMAN_FW_ADDR is the + virtual address in NOR flash. + +- CONFIG_SYS_QE_FMAN_FW_IN_NAND + Specifies that QE/FMAN firmware is located in NAND flash. + CONFIG_SYS_FMAN_FW_ADDR is the offset within NAND flash. + +- CONFIG_SYS_QE_FMAN_FW_IN_MMC + Specifies that QE/FMAN firmware is located on the primary SD/MMC + device. CONFIG_SYS_FMAN_FW_ADDR is the byte offset on that device. + +- CONFIG_SYS_QE_FMAN_FW_IN_SPIFLASH + Specifies that QE/FMAN firmware is located on the primary SPI + device. CONFIG_SYS_FMAN_FW_ADDR is the byte offset on that device. + +- CONFIG_SYS_QE_FMAN_FW_IN_REMOTE + Specifies that QE/FMAN firmware is located in the remote (master) + memory space. CONFIG_SYS_FMAN_FW_ADDR is a virtual address which + can be mapped from slave TLB->slave LAW->slave SRIO or PCIE outbound + window->master inbound window->master LAW->the ucode address in + master's memory space. + +Freescale Layerscape Management Complex Firmware Support: +--------------------------------------------------------- +The Freescale Layerscape Management Complex (MC) supports the loading of +"firmware". +This firmware often needs to be loaded during U-Boot booting, so macros +are used to identify the storage device (NOR flash, SPI, etc) and the address +within that device. + +- CONFIG_FSL_MC_ENET + Enable the MC driver for Layerscape SoCs. + +- CONFIG_SYS_LS_MC_FW_ADDR + The address in the storage device where the firmware is located. The + meaning of this address depends on which CONFIG_SYS_LS_MC_FW_IN_xxx macro + is also specified. + +- CONFIG_SYS_LS_MC_FW_LENGTH + The maximum possible size of the firmware. The firmware binary format + has a field that specifies the actual size of the firmware, but it + might not be possible to read any part of the firmware unless some + local storage is allocated to hold the entire firmware first. + +- CONFIG_SYS_LS_MC_FW_IN_NOR + Specifies that MC firmware is located in NOR flash, mapped as + normal addressable memory via the LBC. CONFIG_SYS_LS_MC_FW_ADDR is the + virtual address in NOR flash. + +Building the Software: +====================== + +Building U-Boot has been tested in several native build environments +and in many different cross environments. Of course we cannot support +all possibly existing versions of cross development tools in all +(potentially obsolete) versions. In case of tool chain problems we +recommend to use the ELDK (see http://www.denx.de/wiki/DULG/ELDK) +which is extensively used to build and test U-Boot. + +If you are not using a native environment, it is assumed that you +have GNU cross compiling tools available in your path. In this case, +you must set the environment variable CROSS_COMPILE in your shell. +Note that no changes to the Makefile or any other source files are +necessary. For example using the ELDK on a 4xx CPU, please enter: + + $ CROSS_COMPILE=ppc_4xx- + $ export CROSS_COMPILE + +Note: If you wish to generate Windows versions of the utilities in + the tools directory you can use the MinGW toolchain + (http://www.mingw.org). Set your HOST tools to the MinGW + toolchain and execute 'make tools'. For example: + + $ make HOSTCC=i586-mingw32msvc-gcc HOSTSTRIP=i586-mingw32msvc-strip tools + + Binaries such as tools/mkimage.exe will be created which can + be executed on computers running Windows. + +U-Boot is intended to be simple to build. After installing the +sources you must configure U-Boot for one specific board type. This +is done by typing: + + make NAME_defconfig + +where "NAME_defconfig" is the name of one of the existing configu- +rations; see boards.cfg for supported names. + +Note: for some board special configuration names may exist; check if + additional information is available from the board vendor; for + instance, the TQM823L systems are available without (standard) + or with LCD support. You can select such additional "features" + when choosing the configuration, i. e. + + make TQM823L_defconfig + - will configure for a plain TQM823L, i. e. no LCD support + + make TQM823L_LCD_defconfig + - will configure for a TQM823L with U-Boot console on LCD + + etc. + + +Finally, type "make all", and you should get some working U-Boot +images ready for download to / installation on your system: + +- "u-boot.bin" is a raw binary image +- "u-boot" is an image in ELF binary format +- "u-boot.srec" is in Motorola S-Record format + +By default the build is performed locally and the objects are saved +in the source directory. One of the two methods can be used to change +this behavior and build U-Boot to some external directory: + +1. Add O= to the make command line invocations: + + make O=/tmp/build distclean + make O=/tmp/build NAME_defconfig + make O=/tmp/build all + +2. Set environment variable KBUILD_OUTPUT to point to the desired location: + + export KBUILD_OUTPUT=/tmp/build + make distclean + make NAME_defconfig + make all + +Note that the command line "O=" setting overrides the KBUILD_OUTPUT environment +variable. + + +Please be aware that the Makefiles assume you are using GNU make, so +for instance on NetBSD you might need to use "gmake" instead of +native "make". + + +If the system board that you have is not listed, then you will need +to port U-Boot to your hardware platform. To do this, follow these +steps: + +1. Add a new configuration option for your board to the toplevel + "boards.cfg" file, using the existing entries as examples. + Follow the instructions there to keep the boards in order. +2. Create a new directory to hold your board specific code. Add any + files you need. In your board directory, you will need at least + the "Makefile", a "<board>.c", "flash.c" and "u-boot.lds". +3. Create a new configuration file "include/configs/<board>.h" for + your board +3. If you're porting U-Boot to a new CPU, then also create a new + directory to hold your CPU specific code. Add any files you need. +4. Run "make <board>_defconfig" with your new name. +5. Type "make", and you should get a working "u-boot.srec" file + to be installed on your target system. +6. Debug and solve any problems that might arise. + [Of course, this last step is much harder than it sounds.] + + +Testing of U-Boot Modifications, Ports to New Hardware, etc.: +============================================================== + +If you have modified U-Boot sources (for instance added a new board +or support for new devices, a new CPU, etc.) you are expected to +provide feedback to the other developers. The feedback normally takes +the form of a "patch", i. e. a context diff against a certain (latest +official or latest in the git repository) version of U-Boot sources. + +But before you submit such a patch, please verify that your modifi- +cation did not break existing code. At least make sure that *ALL* of +the supported boards compile WITHOUT ANY compiler warnings. To do so, +just run the "MAKEALL" script, which will configure and build U-Boot +for ALL supported system. Be warned, this will take a while. You can +select which (cross) compiler to use by passing a `CROSS_COMPILE' +environment variable to the script, i. e. to use the ELDK cross tools +you can type + + CROSS_COMPILE=ppc_8xx- MAKEALL + +or to build on a native PowerPC system you can type + + CROSS_COMPILE=' ' MAKEALL + +When using the MAKEALL script, the default behaviour is to build +U-Boot in the source directory. This location can be changed by +setting the BUILD_DIR environment variable. Also, for each target +built, the MAKEALL script saves two log files (<target>.ERR and +<target>.MAKEALL) in the <source dir>/LOG directory. This default +location can be changed by setting the MAKEALL_LOGDIR environment +variable. For example: + + export BUILD_DIR=/tmp/build + export MAKEALL_LOGDIR=/tmp/log + CROSS_COMPILE=ppc_8xx- MAKEALL + +With the above settings build objects are saved in the /tmp/build, +log files are saved in the /tmp/log and the source tree remains clean +during the whole build process. + + +See also "U-Boot Porting Guide" below. + + +Monitor Commands - Overview: +============================ + +go - start application at address 'addr' +run - run commands in an environment variable +bootm - boot application image from memory +bootp - boot image via network using BootP/TFTP protocol +bootz - boot zImage from memory +tftpboot- boot image via network using TFTP protocol + and env variables "ipaddr" and "serverip" + (and eventually "gatewayip") +tftpput - upload a file via network using TFTP protocol +rarpboot- boot image via network using RARP/TFTP protocol +diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd' +loads - load S-Record file over serial line +loadb - load binary file over serial line (kermit mode) +md - memory display +mm - memory modify (auto-incrementing) +nm - memory modify (constant address) +mw - memory write (fill) +cp - memory copy +cmp - memory compare +crc32 - checksum calculation +i2c - I2C sub-system +sspi - SPI utility commands +base - print or set address offset +printenv- print environment variables +setenv - set environment variables +saveenv - save environment variables to persistent storage +protect - enable or disable FLASH write protection +erase - erase FLASH memory +flinfo - print FLASH memory information +nand - NAND memory operations (see doc/README.nand) +bdinfo - print Board Info structure +iminfo - print header information for application image +coninfo - print console devices and informations +ide - IDE sub-system +loop - infinite loop on address range +loopw - infinite write loop on address range +mtest - simple RAM test +icache - enable or disable instruction cache +dcache - enable or disable data cache +reset - Perform RESET of the CPU +echo - echo args to console +version - print monitor version +help - print online help +? - alias for 'help' + + +Monitor Commands - Detailed Description: +======================================== + +TODO. + +For now: just type "help <command>". + + +Environment Variables: +====================== + +U-Boot supports user configuration using Environment Variables which +can be made persistent by saving to Flash memory. + +Environment Variables are set using "setenv", printed using +"printenv", and saved to Flash using "saveenv". Using "setenv" +without a value can be used to delete a variable from the +environment. As long as you don't save the environment you are +working with an in-memory copy. In case the Flash area containing the +environment is erased by accident, a default environment is provided. + +Some configuration options can be set using Environment Variables. + +List of environment variables (most likely not complete): + + baudrate - see CONFIG_BAUDRATE + + bootdelay - see CONFIG_BOOTDELAY + + bootcmd - see CONFIG_BOOTCOMMAND + + bootargs - Boot arguments when booting an RTOS image + + bootfile - Name of the image to load with TFTP + + bootm_low - Memory range available for image processing in the bootm + command can be restricted. This variable is given as + a hexadecimal number and defines lowest address allowed + for use by the bootm command. See also "bootm_size" + environment variable. Address defined by "bootm_low" is + also the base of the initial memory mapping for the Linux + kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and + bootm_mapsize. + + bootm_mapsize - Size of the initial memory mapping for the Linux kernel. + This variable is given as a hexadecimal number and it + defines the size of the memory region starting at base + address bootm_low that is accessible by the Linux kernel + during early boot. If unset, CONFIG_SYS_BOOTMAPSZ is used + as the default value if it is defined, and bootm_size is + used otherwise. + + bootm_size - Memory range available for image processing in the bootm + command can be restricted. This variable is given as + a hexadecimal number and defines the size of the region + allowed for use by the bootm command. See also "bootm_low" + environment variable. + + updatefile - Location of the software update file on a TFTP server, used + by the automatic software update feature. Please refer to + documentation in doc/README.update for more details. + + autoload - if set to "no" (any string beginning with 'n'), + "bootp" will just load perform a lookup of the + configuration from the BOOTP server, but not try to + load any image using TFTP + + autostart - if set to "yes", an image loaded using the "bootp", + "rarpboot", "tftpboot" or "diskboot" commands will + be automatically started (by internally calling + "bootm") + + If set to "no", a standalone image passed to the + "bootm" command will be copied to the load address + (and eventually uncompressed), but NOT be started. + This can be used to load and uncompress arbitrary + data. + + fdt_high - if set this restricts the maximum address that the + flattened device tree will be copied into upon boot. + For example, if you have a system with 1 GB memory + at physical address 0x10000000, while Linux kernel + only recognizes the first 704 MB as low memory, you + may need to set fdt_high as 0x3C000000 to have the + device tree blob be copied to the maximum address + of the 704 MB low memory, so that Linux kernel can + access it during the boot procedure. + + If this is set to the special value 0xFFFFFFFF then + the fdt will not be copied at all on boot. For this + to work it must reside in writable memory, have + sufficient padding on the end of it for u-boot to + add the information it needs into it, and the memory + must be accessible by the kernel. + + fdtcontroladdr- if set this is the address of the control flattened + device tree used by U-Boot when CONFIG_OF_CONTROL is + defined. + + i2cfast - (PPC405GP|PPC405EP only) + if set to 'y' configures Linux I2C driver for fast + mode (400kHZ). This environment variable is used in + initialization code. So, for changes to be effective + it must be saved and board must be reset. + + initrd_high - restrict positioning of initrd images: + If this variable is not set, initrd images will be + copied to the highest possible address in RAM; this + is usually what you want since it allows for + maximum initrd size. If for some reason you want to + make sure that the initrd image is loaded below the + CONFIG_SYS_BOOTMAPSZ limit, you can set this environment + variable to a value of "no" or "off" or "0". + Alternatively, you can set it to a maximum upper + address to use (U-Boot will still check that it + does not overwrite the U-Boot stack and data). + + For instance, when you have a system with 16 MB + RAM, and want to reserve 4 MB from use by Linux, + you can do this by adding "mem=12M" to the value of + the "bootargs" variable. However, now you must make + sure that the initrd image is placed in the first + 12 MB as well - this can be done with + + setenv initrd_high 00c00000 + + If you set initrd_high to 0xFFFFFFFF, this is an + indication to U-Boot that all addresses are legal + for the Linux kernel, including addresses in flash + memory. In this case U-Boot will NOT COPY the + ramdisk at all. This may be useful to reduce the + boot time on your system, but requires that this + feature is supported by your Linux kernel. + + ipaddr - IP address; needed for tftpboot command + + loadaddr - Default load address for commands like "bootp", + "rarpboot", "tftpboot", "loadb" or "diskboot" + + loads_echo - see CONFIG_LOADS_ECHO + + serverip - TFTP server IP address; needed for tftpboot command + + bootretry - see CONFIG_BOOT_RETRY_TIME + + bootdelaykey - see CONFIG_AUTOBOOT_DELAY_STR + + bootstopkey - see CONFIG_AUTOBOOT_STOP_STR + + ethprime - controls which interface is used first. + + ethact - controls which interface is currently active. + For example you can do the following + + => setenv ethact FEC + => ping 192.168.0.1 # traffic sent on FEC + => setenv ethact SCC + => ping 10.0.0.1 # traffic sent on SCC + + ethrotate - When set to "no" U-Boot does not go through all + available network interfaces. + It just stays at the currently selected interface. + + netretry - When set to "no" each network operation will + either succeed or fail without retrying. + When set to "once" the network operation will + fail when all the available network interfaces + are tried once without success. + Useful on scripts which control the retry operation + themselves. + + npe_ucode - set load address for the NPE microcode + + silent_linux - If set then Linux will be told to boot silently, by + changing the console to be empty. If "yes" it will be + made silent. If "no" it will not be made silent. If + unset, then it will be made silent if the U-Boot console + is silent. + + tftpsrcport - If this is set, the value is used for TFTP's + UDP source port. + + tftpdstport - If this is set, the value is used for TFTP's UDP + destination port instead of the Well Know Port 69. + + tftpblocksize - Block size to use for TFTP transfers; if not set, + we use the TFTP server's default block size + + tftptimeout - Retransmission timeout for TFTP packets (in milli- + seconds, minimum value is 1000 = 1 second). Defines + when a packet is considered to be lost so it has to + be retransmitted. The default is 5000 = 5 seconds. + Lowering this value may make downloads succeed + faster in networks with high packet loss rates or + with unreliable TFTP servers. + + vlan - When set to a value < 4095 the traffic over + Ethernet is encapsulated/received over 802.1q + VLAN tagged frames. + +The following image location variables contain the location of images +used in booting. The "Image" column gives the role of the image and is +not an environment variable name. The other columns are environment +variable names. "File Name" gives the name of the file on a TFTP +server, "RAM Address" gives the location in RAM the image will be +loaded to, and "Flash Location" gives the image's address in NOR +flash or offset in NAND flash. + +*Note* - these variables don't have to be defined for all boards, some +boards currenlty use other variables for these purposes, and some +boards use these variables for other purposes. + +Image File Name RAM Address Flash Location +----- --------- ----------- -------------- +u-boot u-boot u-boot_addr_r u-boot_addr +Linux kernel bootfile kernel_addr_r kernel_addr +device tree blob fdtfile fdt_addr_r fdt_addr +ramdisk ramdiskfile ramdisk_addr_r ramdisk_addr + +The following environment variables may be used and automatically +updated by the network boot commands ("bootp" and "rarpboot"), +depending the information provided by your boot server: + + bootfile - see above + dnsip - IP address of your Domain Name Server + dnsip2 - IP address of your secondary Domain Name Server + gatewayip - IP address of the Gateway (Router) to use + hostname - Target hostname + ipaddr - see above + netmask - Subnet Mask + rootpath - Pathname of the root filesystem on the NFS server + serverip - see above + + +There are two special Environment Variables: + + serial# - contains hardware identification information such + as type string and/or serial number + ethaddr - Ethernet address + +These variables can be set only once (usually during manufacturing of +the board). U-Boot refuses to delete or overwrite these variables +once they have been set once. + + +Further special Environment Variables: + + ver - Contains the U-Boot version string as printed + with the "version" command. This variable is + readonly (see CONFIG_VERSION_VARIABLE). + + +Please note that changes to some configuration parameters may take +only effect after the next boot (yes, that's just like Windoze :-). + + +Callback functions for environment variables: +--------------------------------------------- + +For some environment variables, the behavior of u-boot needs to change +when their values are changed. This functionality allows functions to +be associated with arbitrary variables. On creation, overwrite, or +deletion, the callback will provide the opportunity for some side +effect to happen or for the change to be rejected. + +The callbacks are named and associated with a function using the +U_BOOT_ENV_CALLBACK macro in your board or driver code. + +These callbacks are associated with variables in one of two ways. The +static list can be added to by defining CONFIG_ENV_CALLBACK_LIST_STATIC +in the board configuration to a string that defines a list of +associations. The list must be in the following format: + + entry = variable_name[:callback_name] + list = entry[,list] + +If the callback name is not specified, then the callback is deleted. +Spaces are also allowed anywhere in the list. + +Callbacks can also be associated by defining the ".callbacks" variable +with the same list format above. Any association in ".callbacks" will +override any association in the static list. You can define +CONFIG_ENV_CALLBACK_LIST_DEFAULT to a list (string) to define the +".callbacks" environment variable in the default or embedded environment. + + +Command Line Parsing: +===================== + +There are two different command line parsers available with U-Boot: +the old "simple" one, and the much more powerful "hush" shell: + +Old, simple command line parser: +-------------------------------- + +- supports environment variables (through setenv / saveenv commands) +- several commands on one line, separated by ';' +- variable substitution using "... ${name} ..." syntax +- special characters ('$', ';') can be escaped by prefixing with '\', + for example: + setenv bootcmd bootm \${address} +- You can also escape text by enclosing in single apostrophes, for example: + setenv addip 'setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname::off' + +Hush shell: +----------- + +- similar to Bourne shell, with control structures like + if...then...else...fi, for...do...done; while...do...done, + until...do...done, ... +- supports environment ("global") variables (through setenv / saveenv + commands) and local shell variables (through standard shell syntax + "name=value"); only environment variables can be used with "run" + command + +General rules: +-------------- + +(1) If a command line (or an environment variable executed by a "run" + command) contains several commands separated by semicolon, and + one of these commands fails, then the remaining commands will be + executed anyway. + +(2) If you execute several variables with one call to run (i. e. + calling run with a list of variables as arguments), any failing + command will cause "run" to terminate, i. e. the remaining + variables are not executed. + +Note for Redundant Ethernet Interfaces: +======================================= + +Some boards come with redundant Ethernet interfaces; U-Boot supports +such configurations and is capable of automatic selection of a +"working" interface when needed. MAC assignment works as follows: + +Network interfaces are numbered eth0, eth1, eth2, ... Corresponding +MAC addresses can be stored in the environment as "ethaddr" (=>eth0), +"eth1addr" (=>eth1), "eth2addr", ... + +If the network interface stores some valid MAC address (for instance +in SROM), this is used as default address if there is NO correspon- +ding setting in the environment; if the corresponding environment +variable is set, this overrides the settings in the card; that means: + +o If the SROM has a valid MAC address, and there is no address in the + environment, the SROM's address is used. + +o If there is no valid address in the SROM, and a definition in the + environment exists, then the value from the environment variable is + used. + +o If both the SROM and the environment contain a MAC address, and + both addresses are the same, this MAC address is used. + +o If both the SROM and the environment contain a MAC address, and the + addresses differ, the value from the environment is used and a + warning is printed. + +o If neither SROM nor the environment contain a MAC address, an error + is raised. + +If Ethernet drivers implement the 'write_hwaddr' function, valid MAC addresses +will be programmed into hardware as part of the initialization process. This +may be skipped by setting the appropriate 'ethmacskip' environment variable. +The naming convention is as follows: +"ethmacskip" (=>eth0), "eth1macskip" (=>eth1) etc. + +Image Formats: +============== + +U-Boot is capable of booting (and performing other auxiliary operations on) +images in two formats: + +New uImage format (FIT) +----------------------- + +Flexible and powerful format based on Flattened Image Tree -- FIT (similar +to Flattened Device Tree). It allows the use of images with multiple +components (several kernels, ramdisks, etc.), with contents protected by +SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory. + + +Old uImage format +----------------- + +Old image format is based on binary files which can be basically anything, +preceded by a special header; see the definitions in include/image.h for +details; basically, the header defines the following image properties: + +* Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD, + 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, + LynxOS, pSOS, QNX, RTEMS, INTEGRITY; + Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, LynxOS, + INTEGRITY). +* Target CPU Architecture (Provisions for Alpha, ARM, AVR32, Intel x86, + IA64, MIPS, NDS32, Nios II, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit; + Currently supported: ARM, AVR32, Intel x86, MIPS, NDS32, Nios II, PowerPC). +* Compression Type (uncompressed, gzip, bzip2) +* Load Address +* Entry Point +* Image Name +* Image Timestamp + +The header is marked by a special Magic Number, and both the header +and the data portions of the image are secured against corruption by +CRC32 checksums. + + +Linux Support: +============== + +Although U-Boot should support any OS or standalone application +easily, the main focus has always been on Linux during the design of +U-Boot. + +U-Boot includes many features that so far have been part of some +special "boot loader" code within the Linux kernel. Also, any +"initrd" images to be used are no longer part of one big Linux image; +instead, kernel and "initrd" are separate images. This implementation +serves several purposes: + +- the same features can be used for other OS or standalone + applications (for instance: using compressed images to reduce the + Flash memory footprint) + +- it becomes much easier to port new Linux kernel versions because + lots of low-level, hardware dependent stuff are done by U-Boot + +- the same Linux kernel image can now be used with different "initrd" + images; of course this also means that different kernel images can + be run with the same "initrd". This makes testing easier (you don't + have to build a new "zImage.initrd" Linux image when you just + change a file in your "initrd"). Also, a field-upgrade of the + software is easier now. + + +Linux HOWTO: +============ + +Porting Linux to U-Boot based systems: +--------------------------------------- + +U-Boot cannot save you from doing all the necessary modifications to +configure the Linux device drivers for use with your target hardware +(no, we don't intend to provide a full virtual machine interface to +Linux :-). + +But now you can ignore ALL boot loader code (in arch/powerpc/mbxboot). + +Just make sure your machine specific header file (for instance +include/asm-ppc/tqm8xx.h) includes the same definition of the Board +Information structure as we define in include/asm-<arch>/u-boot.h, +and make sure that your definition of IMAP_ADDR uses the same value +as your U-Boot configuration in CONFIG_SYS_IMMR. + +Note that U-Boot now has a driver model, a unified model for drivers. +If you are adding a new driver, plumb it into driver model. If there +is no uclass available, you are encouraged to create one. See +doc/driver-model. + + +Configuring the Linux kernel: +----------------------------- + +No specific requirements for U-Boot. Make sure you have some root +device (initial ramdisk, NFS) for your target system. + + +Building a Linux Image: +----------------------- + +With U-Boot, "normal" build targets like "zImage" or "bzImage" are +not used. If you use recent kernel source, a new build target +"uImage" will exist which automatically builds an image usable by +U-Boot. Most older kernels also have support for a "pImage" target, +which was introduced for our predecessor project PPCBoot and uses a +100% compatible format. + +Example: + + make TQM850L_defconfig + make oldconfig + make dep + make uImage + +The "uImage" build target uses a special tool (in 'tools/mkimage') to +encapsulate a compressed Linux kernel image with header information, +CRC32 checksum etc. for use with U-Boot. This is what we are doing: + +* build a standard "vmlinux" kernel image (in ELF binary format): + +* convert the kernel into a raw binary image: + + ${CROSS_COMPILE}-objcopy -O binary \ + -R .note -R .comment \ + -S vmlinux linux.bin + +* compress the binary image: + + gzip -9 linux.bin + +* package compressed binary image for U-Boot: + + mkimage -A ppc -O linux -T kernel -C gzip \ + -a 0 -e 0 -n "Linux Kernel Image" \ + -d linux.bin.gz uImage + + +The "mkimage" tool can also be used to create ramdisk images for use +with U-Boot, either separated from the Linux kernel image, or +combined into one file. "mkimage" encapsulates the images with a 64 +byte header containing information about target architecture, +operating system, image type, compression method, entry points, time +stamp, CRC32 checksums, etc. + +"mkimage" can be called in two ways: to verify existing images and +print the header information, or to build new images. + +In the first form (with "-l" option) mkimage lists the information +contained in the header of an existing U-Boot image; this includes +checksum verification: + + tools/mkimage -l image + -l ==> list image header information + +The second form (with "-d" option) is used to build a U-Boot image +from a "data file" which is used as image payload: + + tools/mkimage -A arch -O os -T type -C comp -a addr -e ep \ + -n name -d data_file image + -A ==> set architecture to 'arch' + -O ==> set operating system to 'os' + -T ==> set image type to 'type' + -C ==> set compression type 'comp' + -a ==> set load address to 'addr' (hex) + -e ==> set entry point to 'ep' (hex) + -n ==> set image name to 'name' + -d ==> use image data from 'datafile' + +Right now, all Linux kernels for PowerPC systems use the same load +address (0x00000000), but the entry point address depends on the +kernel version: + +- 2.2.x kernels have the entry point at 0x0000000C, +- 2.3.x and later kernels have the entry point at 0x00000000. + +So a typical call to build a U-Boot image would read: + + -> tools/mkimage -n '2.4.4 kernel for TQM850L' \ + > -A ppc -O linux -T kernel -C gzip -a 0 -e 0 \ + > -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux.gz \ + > examples/uImage.TQM850L + Image Name: 2.4.4 kernel for TQM850L + Created: Wed Jul 19 02:34:59 2000 + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 335725 Bytes = 327.86 kB = 0.32 MB + Load Address: 0x00000000 + Entry Point: 0x00000000 + +To verify the contents of the image (or check for corruption): + + -> tools/mkimage -l examples/uImage.TQM850L + Image Name: 2.4.4 kernel for TQM850L + Created: Wed Jul 19 02:34:59 2000 + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 335725 Bytes = 327.86 kB = 0.32 MB + Load Address: 0x00000000 + Entry Point: 0x00000000 + +NOTE: for embedded systems where boot time is critical you can trade +speed for memory and install an UNCOMPRESSED image instead: this +needs more space in Flash, but boots much faster since it does not +need to be uncompressed: + + -> gunzip /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux.gz + -> tools/mkimage -n '2.4.4 kernel for TQM850L' \ + > -A ppc -O linux -T kernel -C none -a 0 -e 0 \ + > -d /opt/elsk/ppc_8xx/usr/src/linux-2.4.4/arch/powerpc/coffboot/vmlinux \ + > examples/uImage.TQM850L-uncompressed + Image Name: 2.4.4 kernel for TQM850L + Created: Wed Jul 19 02:34:59 2000 + Image Type: PowerPC Linux Kernel Image (uncompressed) + Data Size: 792160 Bytes = 773.59 kB = 0.76 MB + Load Address: 0x00000000 + Entry Point: 0x00000000 + + +Similar you can build U-Boot images from a 'ramdisk.image.gz' file +when your kernel is intended to use an initial ramdisk: + + -> tools/mkimage -n 'Simple Ramdisk Image' \ + > -A ppc -O linux -T ramdisk -C gzip \ + > -d /LinuxPPC/images/SIMPLE-ramdisk.image.gz examples/simple-initrd + Image Name: Simple Ramdisk Image + Created: Wed Jan 12 14:01:50 2000 + Image Type: PowerPC Linux RAMDisk Image (gzip compressed) + Data Size: 566530 Bytes = 553.25 kB = 0.54 MB + Load Address: 0x00000000 + Entry Point: 0x00000000 + +The "dumpimage" is a tool to disassemble images built by mkimage. Its "-i" +option performs the converse operation of the mkimage's second form (the "-d" +option). Given an image built by mkimage, the dumpimage extracts a "data file" +from the image: + + tools/dumpimage -i image -T type -p position data_file + -i ==> extract from the 'image' a specific 'data_file' + -T ==> set image type to 'type' + -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image' + + +Installing a Linux Image: +------------------------- + +To downloading a U-Boot image over the serial (console) interface, +you must convert the image to S-Record format: + + objcopy -I binary -O srec examples/image examples/image.srec + +The 'objcopy' does not understand the information in the U-Boot +image header, so the resulting S-Record file will be relative to +address 0x00000000. To load it to a given address, you need to +specify the target address as 'offset' parameter with the 'loads' +command. + +Example: install the image to address 0x40100000 (which on the +TQM8xxL is in the first Flash bank): + + => erase 40100000 401FFFFF + + .......... done + Erased 8 sectors + + => loads 40100000 + ## Ready for S-Record download ... + ~>examples/image.srec + 1 2 3 4 5 6 7 8 9 10 11 12 13 ... + ... + 15989 15990 15991 15992 + [file transfer complete] + [connected] + ## Start Addr = 0x00000000 + + +You can check the success of the download using the 'iminfo' command; +this includes a checksum verification so you can be sure no data +corruption happened: + + => imi 40100000 + + ## Checking Image at 40100000 ... + Image Name: 2.2.13 for initrd on TQM850L + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 335725 Bytes = 327 kB = 0 MB + Load Address: 00000000 + Entry Point: 0000000c + Verifying Checksum ... OK + + +Boot Linux: +----------- + +The "bootm" command is used to boot an application that is stored in +memory (RAM or Flash). In case of a Linux kernel image, the contents +of the "bootargs" environment variable is passed to the kernel as +parameters. You can check and modify this variable using the +"printenv" and "setenv" commands: + + + => printenv bootargs + bootargs=root=/dev/ram + + => setenv bootargs root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2 + + => printenv bootargs + bootargs=root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2 + + => bootm 40020000 + ## Booting Linux kernel at 40020000 ... + Image Name: 2.2.13 for NFS on TQM850L + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 381681 Bytes = 372 kB = 0 MB + Load Address: 00000000 + Entry Point: 0000000c + Verifying Checksum ... OK + Uncompressing Kernel Image ... OK + Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:35:17 MEST 2000 + Boot arguments: root=/dev/nfs rw nfsroot=10.0.0.2:/LinuxPPC nfsaddrs=10.0.0.99:10.0.0.2 + time_init: decrementer frequency = 187500000/60 + Calibrating delay loop... 49.77 BogoMIPS + Memory: 15208k available (700k kernel code, 444k data, 32k init) [c0000000,c1000000] + ... + +If you want to boot a Linux kernel with initial RAM disk, you pass +the memory addresses of both the kernel and the initrd image (PPBCOOT +format!) to the "bootm" command: + + => imi 40100000 40200000 + + ## Checking Image at 40100000 ... + Image Name: 2.2.13 for initrd on TQM850L + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 335725 Bytes = 327 kB = 0 MB + Load Address: 00000000 + Entry Point: 0000000c + Verifying Checksum ... OK + + ## Checking Image at 40200000 ... + Image Name: Simple Ramdisk Image + Image Type: PowerPC Linux RAMDisk Image (gzip compressed) + Data Size: 566530 Bytes = 553 kB = 0 MB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK + + => bootm 40100000 40200000 + ## Booting Linux kernel at 40100000 ... + Image Name: 2.2.13 for initrd on TQM850L + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 335725 Bytes = 327 kB = 0 MB + Load Address: 00000000 + Entry Point: 0000000c + Verifying Checksum ... OK + Uncompressing Kernel Image ... OK + ## Loading RAMDisk Image at 40200000 ... + Image Name: Simple Ramdisk Image + Image Type: PowerPC Linux RAMDisk Image (gzip compressed) + Data Size: 566530 Bytes = 553 kB = 0 MB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK + Loading Ramdisk ... OK + Linux version 2.2.13 (wd@denx.local.net) (gcc version 2.95.2 19991024 (release)) #1 Wed Jul 19 02:32:08 MEST 2000 + Boot arguments: root=/dev/ram + time_init: decrementer frequency = 187500000/60 + Calibrating delay loop... 49.77 BogoMIPS + ... + RAMDISK: Compressed image found at block 0 + VFS: Mounted root (ext2 filesystem). + + bash# + +Boot Linux and pass a flat device tree: +----------- + +First, U-Boot must be compiled with the appropriate defines. See the section +titled "Linux Kernel Interface" above for a more in depth explanation. The +following is an example of how to start a kernel and pass an updated +flat device tree: + +=> print oftaddr +oftaddr=0x300000 +=> print oft +oft=oftrees/mpc8540ads.dtb +=> tftp $oftaddr $oft +Speed: 1000, full duplex +Using TSEC0 device +TFTP from server 192.168.1.1; our IP address is 192.168.1.101 +Filename 'oftrees/mpc8540ads.dtb'. +Load address: 0x300000 +Loading: # +done +Bytes transferred = 4106 (100a hex) +=> tftp $loadaddr $bootfile +Speed: 1000, full duplex +Using TSEC0 device +TFTP from server 192.168.1.1; our IP address is 192.168.1.2 +Filename 'uImage'. +Load address: 0x200000 +Loading:############ +done +Bytes transferred = 1029407 (fb51f hex) +=> print loadaddr +loadaddr=200000 +=> print oftaddr +oftaddr=0x300000 +=> bootm $loadaddr - $oftaddr +## Booting image at 00200000 ... + Image Name: Linux-2.6.17-dirty + Image Type: PowerPC Linux Kernel Image (gzip compressed) + Data Size: 1029343 Bytes = 1005.2 kB + Load Address: 00000000 + Entry Point: 00000000 + Verifying Checksum ... OK + Uncompressing Kernel Image ... OK +Booting using flat device tree at 0x300000 +Using MPC85xx ADS machine description +Memory CAM mapping: CAM0=256Mb, CAM1=256Mb, CAM2=0Mb residual: 0Mb +[snip] + + +More About U-Boot Image Types: +------------------------------ + +U-Boot supports the following 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). + + "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. + +Booting the Linux zImage: +------------------------- + +On some platforms, it's possible to boot Linux zImage. This is done +using the "bootz" command. The syntax of "bootz" command is the same +as the syntax of "bootm" command. + +Note, defining the CONFIG_SUPPORT_RAW_INITRD allows user to supply +kernel with raw initrd images. The syntax is slightly different, the +address of the initrd must be augmented by it's size, in the following +format: "<initrd addres>:<initrd size>". + + +Standalone HOWTO: +================= + +One of the features of U-Boot is that you can dynamically load and +run "standalone" applications, which can use some resources of +U-Boot like console I/O functions or interrupt services. + +Two simple examples are included with the sources: + +"Hello World" Demo: +------------------- + +'examples/hello_world.c' contains a small "Hello World" Demo +application; it is automatically compiled when you build U-Boot. +It's configured to run at address 0x00040004, so you can play with it +like that: + + => loads + ## Ready for S-Record download ... + ~>examples/hello_world.srec + 1 2 3 4 5 6 7 8 9 10 11 ... + [file transfer complete] + [connected] + ## Start Addr = 0x00040004 + + => go 40004 Hello World! This is a test. + ## Starting application at 0x00040004 ... + Hello World + argc = 7 + argv[0] = "40004" + argv[1] = "Hello" + argv[2] = "World!" + argv[3] = "This" + argv[4] = "is" + argv[5] = "a" + argv[6] = "test." + argv[7] = "<NULL>" + Hit any key to exit ... + + ## Application terminated, rc = 0x0 + +Another example, which demonstrates how to register a CPM interrupt +handler with the U-Boot code, can be found in 'examples/timer.c'. +Here, a CPM timer is set up to generate an interrupt every second. +The interrupt service routine is trivial, just printing a '.' +character, but this is just a demo program. The application can be +controlled by the following keys: + + ? - print current values og the CPM Timer registers + b - enable interrupts and start timer + e - stop timer and disable interrupts + q - quit application + + => loads + ## Ready for S-Record download ... + ~>examples/timer.srec + 1 2 3 4 5 6 7 8 9 10 11 ... + [file transfer complete] + [connected] + ## Start Addr = 0x00040004 + + => go 40004 + ## Starting application at 0x00040004 ... + TIMERS=0xfff00980 + Using timer 1 + tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0 + +Hit 'b': + [q, b, e, ?] Set interval 1000000 us + Enabling timer +Hit '?': + [q, b, e, ?] ........ + tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0 +Hit '?': + [q, b, e, ?] . + tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0 +Hit '?': + [q, b, e, ?] . + tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0 +Hit '?': + [q, b, e, ?] . + tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0 +Hit 'e': + [q, b, e, ?] ...Stopping timer +Hit 'q': + [q, b, e, ?] ## Application terminated, rc = 0x0 + + +Minicom warning: +================ + +Over time, many people have reported problems when trying to use the +"minicom" terminal emulation program for serial download. I (wd) +consider minicom to be broken, and recommend not to use it. Under +Unix, I recommend to use C-Kermit for general purpose use (and +especially for kermit binary protocol download ("loadb" command), and +use "cu" for S-Record download ("loads" command). See +http://www.denx.de/wiki/view/DULG/SystemSetup#Section_4.3. +for help with kermit. + + +Nevertheless, if you absolutely want to use it try adding this +configuration to your "File transfer protocols" section: + + Name Program Name U/D FullScr IO-Red. Multi + X kermit /usr/bin/kermit -i -l %l -s Y U Y N N + Y kermit /usr/bin/kermit -i -l %l -r N D Y N N + + +NetBSD Notes: +============= + +Starting at version 0.9.2, U-Boot supports NetBSD both as host +(build U-Boot) and target system (boots NetBSD/mpc8xx). + +Building requires a cross environment; it is known to work on +NetBSD/i386 with the cross-powerpc-netbsd-1.3 package (you will also +need gmake since the Makefiles are not compatible with BSD make). +Note that the cross-powerpc package does not install include files; +attempting to build U-Boot will fail because <machine/ansi.h> is +missing. This file has to be installed and patched manually: + + # cd /usr/pkg/cross/powerpc-netbsd/include + # mkdir powerpc + # ln -s powerpc machine + # cp /usr/src/sys/arch/powerpc/include/ansi.h powerpc/ansi.h + # ${EDIT} powerpc/ansi.h ## must remove __va_list, _BSD_VA_LIST + +Native builds *don't* work due to incompatibilities between native +and U-Boot include files. + +Booting assumes that (the first part of) the image booted is a +stage-2 loader which in turn loads and then invokes the kernel +proper. Loader sources will eventually appear in the NetBSD source +tree (probably in sys/arc/mpc8xx/stand/u-boot_stage2/); in the +meantime, see ftp://ftp.denx.de/pub/u-boot/ppcboot_stage2.tar.gz + + +Implementation Internals: +========================= + +The following is not intended to be a complete description of every +implementation detail. However, it should help to understand the +inner workings of U-Boot and make it easier to port it to custom +hardware. + + +Initial Stack, Global Data: +--------------------------- + +The implementation of U-Boot is complicated by the fact that U-Boot +starts running out of ROM (flash memory), usually without access to +system RAM (because the memory controller is not initialized yet). +This means that we don't have writable Data or BSS segments, and BSS +is not initialized as zero. To be able to get a C environment working +at all, we have to allocate at least a minimal stack. Implementation +options for this are defined and restricted by the CPU used: Some CPU +models provide on-chip memory (like the IMMR area on MPC8xx and +MPC826x processors), on others (parts of) the data cache can be +locked as (mis-) used as memory, etc. + + Chris Hallinan posted a good summary of these issues to the + U-Boot mailing list: + + Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)? + From: "Chris Hallinan" <clh@net1plus.com> + Date: Mon, 10 Feb 2003 16:43:46 -0500 (22:43 MET) + ... + + Correct me if I'm wrong, folks, but the way I understand it + is this: Using DCACHE as initial RAM for Stack, etc, does not + require any physical RAM backing up the cache. The cleverness + is that the cache is being used as a temporary supply of + necessary storage before the SDRAM controller is setup. It's + beyond the scope of this list to explain the details, but you + can see how this works by studying the cache architecture and + operation in the architecture and processor-specific manuals. + + OCM is On Chip Memory, which I believe the 405GP has 4K. It + is another option for the system designer to use as an + initial stack/RAM area prior to SDRAM being available. Either + option should work for you. Using CS 4 should be fine if your + board designers haven't used it for something that would + cause you grief during the initial boot! It is frequently not + used. + + CONFIG_SYS_INIT_RAM_ADDR should be somewhere that won't interfere + with your processor/board/system design. The default value + you will find in any recent u-boot distribution in + walnut.h should work for you. I'd set it to a value larger + than your SDRAM module. If you have a 64MB SDRAM module, set + it above 400_0000. Just make sure your board has no resources + that are supposed to respond to that address! That code in + start.S has been around a while and should work as is when + you get the config right. + + -Chris Hallinan + DS4.COM, Inc. + +It is essential to remember this, since it has some impact on the C +code for the initialization procedures: + +* Initialized global data (data segment) is read-only. Do not attempt + to write it. + +* Do not use any uninitialized global data (or implicitly initialized + as zero data - BSS segment) at all - this is undefined, initiali- + zation is performed later (when relocating to RAM). + +* Stack space is very limited. Avoid big data buffers or things like + that. + +Having only the stack as writable memory limits means we cannot use +normal global data to share information between the code. But it +turned out that the implementation of U-Boot can be greatly +simplified by making a global data structure (gd_t) available to all +functions. We could pass a pointer to this data as argument to _all_ +functions, but this would bloat the code. Instead we use a feature of +the GCC compiler (Global Register Variables) to share the data: we +place a pointer (gd) to the global data into a register which we +reserve for this purpose. + +When choosing a register for such a purpose we are restricted by the +relevant (E)ABI specifications for the current architecture, and by +GCC's implementation. + +For PowerPC, the following registers have specific use: + R1: stack pointer + R2: reserved for system use + R3-R4: parameter passing and return values + R5-R10: parameter passing + R13: small data area pointer + R30: GOT pointer + R31: frame pointer + + (U-Boot also uses R12 as internal GOT pointer. r12 + is a volatile register so r12 needs to be reset when + going back and forth between asm and C) + + ==> U-Boot will use R2 to hold a pointer to the global data + + Note: on PPC, we could use a static initializer (since the + address of the global data structure is known at compile time), + but it turned out that reserving a register results in somewhat + smaller code - although the code savings are not that big (on + average for all boards 752 bytes for the whole U-Boot image, + 624 text + 127 data). + +On Blackfin, the normal C ABI (except for P3) is followed as documented here: + http://docs.blackfin.uclinux.org/doku.php?id=application_binary_interface + + ==> U-Boot will use P3 to hold a pointer to the global data + +On ARM, the following registers are used: + + R0: function argument word/integer result + R1-R3: function argument word + R9: platform specific + R10: stack limit (used only if stack checking is enabled) + R11: argument (frame) pointer + R12: temporary workspace + R13: stack pointer + R14: link register + R15: program counter + + ==> U-Boot will use R9 to hold a pointer to the global data + + Note: on ARM, only R_ARM_RELATIVE relocations are supported. + +On Nios II, the ABI is documented here: + http://www.altera.com/literature/hb/nios2/n2cpu_nii51016.pdf + + ==> U-Boot will use gp to hold a pointer to the global data + + Note: on Nios II, we give "-G0" option to gcc and don't use gp + to access small data sections, so gp is free. + +On NDS32, the following registers are used: + + R0-R1: argument/return + R2-R5: argument + R15: temporary register for assembler + R16: trampoline register + R28: frame pointer (FP) + R29: global pointer (GP) + R30: link register (LP) + R31: stack pointer (SP) + PC: program counter (PC) + + ==> U-Boot will use R10 to hold a pointer to the global data + +NOTE: DECLARE_GLOBAL_DATA_PTR must be used with file-global scope, +or current versions of GCC may "optimize" the code too much. + +Memory Management: +------------------ + +U-Boot runs in system state and uses physical addresses, i.e. the +MMU is not used either for address mapping nor for memory protection. + +The available memory is mapped to fixed addresses using the memory +controller. In this process, a contiguous block is formed for each +memory type (Flash, SDRAM, SRAM), even when it consists of several +physical memory banks. + +U-Boot is installed in the first 128 kB of the first Flash bank (on +TQM8xxL modules this is the range 0x40000000 ... 0x4001FFFF). After +booting and sizing and initializing DRAM, the code relocates itself +to the upper end of DRAM. Immediately below the U-Boot code some +memory is reserved for use by malloc() [see CONFIG_SYS_MALLOC_LEN +configuration setting]. Below that, a structure with global Board +Info data is placed, followed by the stack (growing downward). + +Additionally, some exception handler code is copied to the low 8 kB +of DRAM (0x00000000 ... 0x00001FFF). + +So a typical memory configuration with 16 MB of DRAM could look like +this: + + 0x0000 0000 Exception Vector code + : + 0x0000 1FFF + 0x0000 2000 Free for Application Use + : + : + + : + : + 0x00FB FF20 Monitor Stack (Growing downward) + 0x00FB FFAC Board Info Data and permanent copy of global data + 0x00FC 0000 Malloc Arena + : + 0x00FD FFFF + 0x00FE 0000 RAM Copy of Monitor Code + ... eventually: LCD or video framebuffer + ... eventually: pRAM (Protected RAM - unchanged by reset) + 0x00FF FFFF [End of RAM] + + +System Initialization: +---------------------- + +In the reset configuration, U-Boot starts at the reset entry point +(on most PowerPC systems at address 0x00000100). Because of the reset +configuration for CS0# this is a mirror of the on board Flash memory. +To be able to re-map memory U-Boot then jumps to its link address. +To be able to implement the initialization code in C, a (small!) +initial stack is set up in the internal Dual Ported RAM (in case CPUs +which provide such a feature like MPC8xx or MPC8260), or in a locked +part of the data cache. After that, U-Boot initializes the CPU core, +the caches and the SIU. + +Next, all (potentially) available memory banks are mapped using a +preliminary mapping. For example, we put them on 512 MB boundaries +(multiples of 0x20000000: SDRAM on 0x00000000 and 0x20000000, Flash +on 0x40000000 and 0x60000000, SRAM on 0x80000000). Then UPM A is +programmed for SDRAM access. Using the temporary configuration, a +simple memory test is run that determines the size of the SDRAM +banks. + +When there is more than one SDRAM bank, and the banks are of +different size, the largest is mapped first. For equal size, the first +bank (CS2#) is mapped first. The first mapping is always for address +0x00000000, with any additional banks following immediately to create +contiguous memory starting from 0. + +Then, the monitor installs itself at the upper end of the SDRAM area +and allocates memory for use by malloc() and for the global Board +Info data; also, the exception vector code is copied to the low RAM +pages, and the final stack is set up. + +Only after this relocation will you have a "normal" C environment; +until that you are restricted in several ways, mostly because you are +running from ROM, and because the code will have to be relocated to a +new address in RAM. + + +U-Boot Porting Guide: +---------------------- + +[Based on messages by Jerry Van Baren in the U-Boot-Users mailing +list, October 2002] + + +int main(int argc, char *argv[]) +{ + sighandler_t no_more_time; + + signal(SIGALRM, no_more_time); + alarm(PROJECT_DEADLINE - toSec (3 * WEEK)); + + if (available_money > available_manpower) { + Pay consultant to port U-Boot; + return 0; + } + + Download latest U-Boot source; + + Subscribe to u-boot mailing list; + + if (clueless) + email("Hi, I am new to U-Boot, how do I get started?"); + + while (learning) { + Read the README file in the top level directory; + Read http://www.denx.de/twiki/bin/view/DULG/Manual; + Read applicable doc/*.README; + Read the source, Luke; + /* find . -name "*.[chS]" | xargs grep -i <keyword> */ + } + + if (available_money > toLocalCurrency ($2500)) + Buy a BDI3000; + else + Add a lot of aggravation and time; + + if (a similar board exists) { /* hopefully... */ + cp -a board/<similar> board/<myboard> + cp include/configs/<similar>.h include/configs/<myboard>.h + } else { + Create your own board support subdirectory; + Create your own board include/configs/<myboard>.h file; + } + Edit new board/<myboard> files + Edit new include/configs/<myboard>.h + + while (!accepted) { + while (!running) { + do { + Add / modify source code; + } until (compiles); + Debug; + if (clueless) + email("Hi, I am having problems..."); + } + Send patch file to the U-Boot email list; + if (reasonable critiques) + Incorporate improvements from email list code review; + else + Defend code as written; + } + + return 0; +} + +void no_more_time (int sig) +{ + hire_a_guru(); +} + + +Coding Standards: +----------------- + +All contributions to U-Boot should conform to the Linux kernel +coding style; see the file "Documentation/CodingStyle" and the script +"scripts/Lindent" in your Linux kernel source directory. + +Source files originating from a different project (for example the +MTD subsystem) are generally exempt from these guidelines and are not +reformatted to ease subsequent migration to newer versions of those +sources. + +Please note that U-Boot is implemented in C (and to some small parts in +Assembler); no C++ is used, so please do not use C++ style comments (//) +in your code. + +Please also stick to the following formatting rules: +- remove any trailing white space +- use TAB characters for indentation and vertical alignment, not spaces +- make sure NOT to use DOS '\r\n' line feeds +- do not add more than 2 consecutive empty lines to source files +- do not add trailing empty lines to source files + +Submissions which do not conform to the standards may be returned +with a request to reformat the changes. + + +Submitting Patches: +------------------- + +Since the number of patches for U-Boot is growing, we need to +establish some rules. Submissions which do not conform to these rules +may be rejected, even when they contain important and valuable stuff. + +Please see http://www.denx.de/wiki/U-Boot/Patches for details. + +Patches shall be sent to the u-boot mailing list <u-boot@lists.denx.de>; +see http://lists.denx.de/mailman/listinfo/u-boot + +When you send a patch, please include the following information with +it: + +* For bug fixes: a description of the bug and how your patch fixes + this bug. Please try to include a way of demonstrating that the + patch actually fixes something. + +* For new features: a description of the feature and your + implementation. + +* A CHANGELOG entry as plaintext (separate from the patch) + +* For major contributions, your entry to the CREDITS file + +* When you add support for a new board, don't forget to add a + maintainer e-mail address to the boards.cfg file, too. + +* If your patch adds new configuration options, don't forget to + document these in the README file. + +* The patch itself. If you are using git (which is *strongly* + recommended) you can easily generate the patch using the + "git format-patch". If you then use "git send-email" to send it to + the U-Boot mailing list, you will avoid most of the common problems + with some other mail clients. + + If you cannot use git, use "diff -purN OLD NEW". If your version of + diff does not support these options, then get the latest version of + GNU diff. + + The current directory when running this command shall be the parent + directory of the U-Boot source tree (i. e. please make sure that + your patch includes sufficient directory information for the + affected files). + + We prefer patches as plain text. MIME attachments are discouraged, + and compressed attachments must not be used. + +* If one logical set of modifications affects or creates several + files, all these changes shall be submitted in a SINGLE patch file. + +* Changesets that contain different, unrelated modifications shall be + submitted as SEPARATE patches, one patch per changeset. + + +Notes: + +* Before sending the patch, run the MAKEALL script on your patched + source tree and make sure that no errors or warnings are reported + for any of the boards. + +* Keep your modifications to the necessary minimum: A patch + containing several unrelated changes or arbitrary reformats will be + returned with a request to re-formatting / split it. + +* If you modify existing code, make sure that your new code does not + add to the memory footprint of the code ;-) Small is beautiful! + When adding new features, these should compile conditionally only + (using #ifdef), and the resulting code with the new feature + disabled must not need more memory than the old code without your + modification. + +* Remember that there is a size limit of 100 kB per message on the + u-boot mailing list. Bigger patches will be moderated. If they are + reasonable and not too big, they will be acknowledged. But patches + bigger than the size limit should be avoided.
diff --git a/u-boot-imx/api/Makefile b/u-boot-imx/api/Makefile new file mode 100644 index 0000000..3c095ee --- /dev/null +++ b/u-boot-imx/api/Makefile
@@ -0,0 +1,9 @@ +# +# (C) Copyright 2007 Semihalf +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += api.o api_display.o api_net.o api_storage.o +obj-$(CONFIG_ARM) += api_platform-arm.o +obj-$(CONFIG_PPC) += api_platform-powerpc.o
diff --git a/u-boot-imx/api/README b/u-boot-imx/api/README new file mode 100644 index 0000000..6df225f --- /dev/null +++ b/u-boot-imx/api/README
@@ -0,0 +1,55 @@ +U-Boot machine/arch independent API for external apps +===================================================== + +1. Main assumptions + + - there is a single entry point (syscall) to the API + + - per current design the syscall is a C-callable function in the U-Boot + text, which might evolve into a real syscall using machine exception trap + once this initial version proves functional + + - the consumer app is responsible for producing appropriate context (call + number and arguments) + + - upon entry, the syscall dispatches the call to other (existing) U-Boot + functional areas like networking or storage operations + + - consumer application will recognize the API is available by searching + a specified (assumed by convention) range of address space for the + signature + + - the U-Boot integral part of the API is meant to be thin and non-intrusive, + leaving as much processing as possible on the consumer application side, + for example it doesn't keep states, but relies on hints from the app and + so on + + - optional (CONFIG_API) + + +2. Calls + + - console related (getc, putc, tstc etc.) + - system (reset, platform info) + - time (delay, current) + - env vars (enumerate all, get, set) + - devices (enumerate all, open, close, read, write); currently two classes + of devices are recognized and supported: network and storage (ide, scsi, + usb etc.) + + +3. Structure overview + + - core API, integral part of U-Boot, mandatory + - implements the single entry point (mimics UNIX syscall) + + - glue + - entry point at the consumer side, allows to make syscall, mandatory + part + + - helper conveniency wrappers so that consumer app does not have to use + the syscall directly, but in a more friendly manner (a la libc calls), + optional part + + - consumer application + - calls directly, or leverages the provided glue mid-layer
diff --git a/u-boot-imx/api/api.c b/u-boot-imx/api/api.c new file mode 100644 index 0000000..c5f6edb --- /dev/null +++ b/u-boot-imx/api/api.c
@@ -0,0 +1,691 @@ +/* + * (C) Copyright 2007 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <command.h> +#include <common.h> +#include <malloc.h> +#include <environment.h> +#include <linux/types.h> +#include <api_public.h> + +#include "api_private.h" + +#define DEBUG +#undef DEBUG + +/***************************************************************************** + * + * This is the API core. + * + * API_ functions are part of U-Boot code and constitute the lowest level + * calls: + * + * - they know what values they need as arguments + * - their direct return value pertains to the API_ "shell" itself (0 on + * success, some error code otherwise) + * - if the call returns a value it is buried within arguments + * + ****************************************************************************/ + +#ifdef DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +typedef int (*cfp_t)(va_list argp); + +static int calls_no; + +/* + * pseudo signature: + * + * int API_getc(int *c) + */ +static int API_getc(va_list ap) +{ + int *c; + + if ((c = (int *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + *c = getc(); + return 0; +} + +/* + * pseudo signature: + * + * int API_tstc(int *c) + */ +static int API_tstc(va_list ap) +{ + int *t; + + if ((t = (int *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + *t = tstc(); + return 0; +} + +/* + * pseudo signature: + * + * int API_putc(char *ch) + */ +static int API_putc(va_list ap) +{ + char *c; + + if ((c = (char *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + putc(*c); + return 0; +} + +/* + * pseudo signature: + * + * int API_puts(char **s) + */ +static int API_puts(va_list ap) +{ + char *s; + + if ((s = (char *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + puts(s); + return 0; +} + +/* + * pseudo signature: + * + * int API_reset(void) + */ +static int API_reset(va_list ap) +{ + do_reset(NULL, 0, 0, NULL); + + /* NOT REACHED */ + return 0; +} + +/* + * pseudo signature: + * + * int API_get_sys_info(struct sys_info *si) + * + * fill out the sys_info struct containing selected parameters about the + * machine + */ +static int API_get_sys_info(va_list ap) +{ + struct sys_info *si; + + si = (struct sys_info *)va_arg(ap, u_int32_t); + if (si == NULL) + return API_ENOMEM; + + return (platform_sys_info(si)) ? 0 : API_ENODEV; +} + +/* + * pseudo signature: + * + * int API_udelay(unsigned long *udelay) + */ +static int API_udelay(va_list ap) +{ + unsigned long *d; + + if ((d = (unsigned long *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + udelay(*d); + return 0; +} + +/* + * pseudo signature: + * + * int API_get_timer(unsigned long *current, unsigned long *base) + */ +static int API_get_timer(va_list ap) +{ + unsigned long *base, *cur; + + cur = (unsigned long *)va_arg(ap, u_int32_t); + if (cur == NULL) + return API_EINVAL; + + base = (unsigned long *)va_arg(ap, u_int32_t); + if (base == NULL) + return API_EINVAL; + + *cur = get_timer(*base); + return 0; +} + + +/***************************************************************************** + * + * pseudo signature: + * + * int API_dev_enum(struct device_info *) + * + * + * cookies uniqely identify the previously enumerated device instance and + * provide a hint for what to inspect in current enum iteration: + * + * - net: ð_device struct address from list pointed to by eth_devices + * + * - storage: block_dev_desc_t struct address from &ide_dev_desc[n], + * &scsi_dev_desc[n] and similar tables + * + ****************************************************************************/ + +static int API_dev_enum(va_list ap) +{ + struct device_info *di; + + /* arg is ptr to the device_info struct we are going to fill out */ + di = (struct device_info *)va_arg(ap, u_int32_t); + if (di == NULL) + return API_EINVAL; + + if (di->cookie == NULL) { + /* start over - clean up enumeration */ + dev_enum_reset(); /* XXX shouldn't the name contain 'stor'? */ + debugf("RESTART ENUM\n"); + + /* net device enumeration first */ + if (dev_enum_net(di)) + return 0; + } + + /* + * The hidden assumption is there can only be one active network + * device and it is identified upon enumeration (re)start, so there's + * no point in trying to find network devices in other cases than the + * (re)start and hence the 'next' device can only be storage + */ + if (!dev_enum_storage(di)) + /* make sure we mark there are no more devices */ + di->cookie = NULL; + + return 0; +} + + +static int API_dev_open(va_list ap) +{ + struct device_info *di; + int err = 0; + + /* arg is ptr to the device_info struct */ + di = (struct device_info *)va_arg(ap, u_int32_t); + if (di == NULL) + return API_EINVAL; + + /* Allow only one consumer of the device at a time */ + if (di->state == DEV_STA_OPEN) + return API_EBUSY; + + if (di->cookie == NULL) + return API_ENODEV; + + if (di->type & DEV_TYP_STOR) + err = dev_open_stor(di->cookie); + + else if (di->type & DEV_TYP_NET) + err = dev_open_net(di->cookie); + else + err = API_ENODEV; + + if (!err) + di->state = DEV_STA_OPEN; + + return err; +} + + +static int API_dev_close(va_list ap) +{ + struct device_info *di; + int err = 0; + + /* arg is ptr to the device_info struct */ + di = (struct device_info *)va_arg(ap, u_int32_t); + if (di == NULL) + return API_EINVAL; + + if (di->state == DEV_STA_CLOSED) + return 0; + + if (di->cookie == NULL) + return API_ENODEV; + + if (di->type & DEV_TYP_STOR) + err = dev_close_stor(di->cookie); + + else if (di->type & DEV_TYP_NET) + err = dev_close_net(di->cookie); + else + /* + * In case of unknown device we cannot change its state, so + * only return error code + */ + err = API_ENODEV; + + if (!err) + di->state = DEV_STA_CLOSED; + + return err; +} + + +/* + * Notice: this is for sending network packets only, as U-Boot does not + * support writing to storage at the moment (12.2007) + * + * pseudo signature: + * + * int API_dev_write( + * struct device_info *di, + * void *buf, + * int *len + * ) + * + * buf: ptr to buffer from where to get the data to send + * + * len: length of packet to be sent (in bytes) + * + */ +static int API_dev_write(va_list ap) +{ + struct device_info *di; + void *buf; + int *len; + int err = 0; + + /* 1. arg is ptr to the device_info struct */ + di = (struct device_info *)va_arg(ap, u_int32_t); + if (di == NULL) + return API_EINVAL; + + /* XXX should we check if device is open? i.e. the ->state ? */ + + if (di->cookie == NULL) + return API_ENODEV; + + /* 2. arg is ptr to buffer from where to get data to write */ + buf = (void *)va_arg(ap, u_int32_t); + if (buf == NULL) + return API_EINVAL; + + /* 3. arg is length of buffer */ + len = (int *)va_arg(ap, u_int32_t); + if (len == NULL) + return API_EINVAL; + if (*len <= 0) + return API_EINVAL; + + if (di->type & DEV_TYP_STOR) + /* + * write to storage is currently not supported by U-Boot: + * no storage device implements block_write() method + */ + return API_ENODEV; + + else if (di->type & DEV_TYP_NET) + err = dev_write_net(di->cookie, buf, *len); + else + err = API_ENODEV; + + return err; +} + + +/* + * pseudo signature: + * + * int API_dev_read( + * struct device_info *di, + * void *buf, + * size_t *len, + * unsigned long *start + * size_t *act_len + * ) + * + * buf: ptr to buffer where to put the read data + * + * len: ptr to length to be read + * - network: len of packet to read (in bytes) + * - storage: # of blocks to read (can vary in size depending on define) + * + * start: ptr to start block (only used for storage devices, ignored for + * network) + * + * act_len: ptr to where to put the len actually read + */ +static int API_dev_read(va_list ap) +{ + struct device_info *di; + void *buf; + lbasize_t *len_stor, *act_len_stor; + lbastart_t *start; + int *len_net, *act_len_net; + + /* 1. arg is ptr to the device_info struct */ + di = (struct device_info *)va_arg(ap, u_int32_t); + if (di == NULL) + return API_EINVAL; + + /* XXX should we check if device is open? i.e. the ->state ? */ + + if (di->cookie == NULL) + return API_ENODEV; + + /* 2. arg is ptr to buffer from where to put the read data */ + buf = (void *)va_arg(ap, u_int32_t); + if (buf == NULL) + return API_EINVAL; + + if (di->type & DEV_TYP_STOR) { + /* 3. arg - ptr to var with # of blocks to read */ + len_stor = (lbasize_t *)va_arg(ap, u_int32_t); + if (!len_stor) + return API_EINVAL; + if (*len_stor <= 0) + return API_EINVAL; + + /* 4. arg - ptr to var with start block */ + start = (lbastart_t *)va_arg(ap, u_int32_t); + + /* 5. arg - ptr to var where to put the len actually read */ + act_len_stor = (lbasize_t *)va_arg(ap, u_int32_t); + if (!act_len_stor) + return API_EINVAL; + + *act_len_stor = dev_read_stor(di->cookie, buf, *len_stor, *start); + + } else if (di->type & DEV_TYP_NET) { + + /* 3. arg points to the var with length of packet to read */ + len_net = (int *)va_arg(ap, u_int32_t); + if (!len_net) + return API_EINVAL; + if (*len_net <= 0) + return API_EINVAL; + + /* 4. - ptr to var where to put the len actually read */ + act_len_net = (int *)va_arg(ap, u_int32_t); + if (!act_len_net) + return API_EINVAL; + + *act_len_net = dev_read_net(di->cookie, buf, *len_net); + + } else + return API_ENODEV; + + return 0; +} + + +/* + * pseudo signature: + * + * int API_env_get(const char *name, char **value) + * + * name: ptr to name of env var + */ +static int API_env_get(va_list ap) +{ + char *name, **value; + + if ((name = (char *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + if ((value = (char **)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + *value = getenv(name); + + return 0; +} + +/* + * pseudo signature: + * + * int API_env_set(const char *name, const char *value) + * + * name: ptr to name of env var + * + * value: ptr to value to be set + */ +static int API_env_set(va_list ap) +{ + char *name, *value; + + if ((name = (char *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + if ((value = (char *)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + setenv(name, value); + + return 0; +} + +/* + * pseudo signature: + * + * int API_env_enum(const char *last, char **next) + * + * last: ptr to name of env var found in last iteration + */ +static int API_env_enum(va_list ap) +{ + int i, n; + char *last, **next; + + last = (char *)va_arg(ap, u_int32_t); + + if ((next = (char **)va_arg(ap, u_int32_t)) == NULL) + return API_EINVAL; + + if (last == NULL) + /* start over */ + *next = ((char *)env_get_addr(0)); + else { + *next = last; + + for (i = 0; env_get_char(i) != '\0'; i = n + 1) { + for (n = i; env_get_char(n) != '\0'; ++n) { + if (n >= CONFIG_ENV_SIZE) { + /* XXX shouldn't we set *next = NULL?? */ + return 0; + } + } + + if (envmatch((uchar *)last, i) < 0) + continue; + + /* try to get next name */ + i = n + 1; + if (env_get_char(i) == '\0') { + /* no more left */ + *next = NULL; + return 0; + } + + *next = ((char *)env_get_addr(i)); + return 0; + } + } + + return 0; +} + +/* + * pseudo signature: + * + * int API_display_get_info(int type, struct display_info *di) + */ +static int API_display_get_info(va_list ap) +{ + int type; + struct display_info *di; + + type = va_arg(ap, int); + di = va_arg(ap, struct display_info *); + + return display_get_info(type, di); +} + +/* + * pseudo signature: + * + * int API_display_draw_bitmap(ulong bitmap, int x, int y) + */ +static int API_display_draw_bitmap(va_list ap) +{ + ulong bitmap; + int x, y; + + bitmap = va_arg(ap, ulong); + x = va_arg(ap, int); + y = va_arg(ap, int); + + return display_draw_bitmap(bitmap, x, y); +} + +/* + * pseudo signature: + * + * void API_display_clear(void) + */ +static int API_display_clear(va_list ap) +{ + display_clear(); + return 0; +} + +static cfp_t calls_table[API_MAXCALL] = { NULL, }; + +/* + * The main syscall entry point - this is not reentrant, only one call is + * serviced until finished. + * + * e.g. syscall(1, int *, u_int32_t, u_int32_t, u_int32_t, u_int32_t); + * + * call: syscall number + * + * retval: points to the return value placeholder, this is the place the + * syscall puts its return value, if NULL the caller does not + * expect a return value + * + * ... syscall arguments (variable number) + * + * returns: 0 if the call not found, 1 if serviced + */ +int syscall(int call, int *retval, ...) +{ + va_list ap; + int rv; + + if (call < 0 || call >= calls_no) { + debugf("invalid call #%d\n", call); + return 0; + } + + if (calls_table[call] == NULL) { + debugf("syscall #%d does not have a handler\n", call); + return 0; + } + + va_start(ap, retval); + rv = calls_table[call](ap); + if (retval != NULL) + *retval = rv; + + return 1; +} + +void api_init(void) +{ + struct api_signature *sig = NULL; + + /* TODO put this into linker set one day... */ + calls_table[API_RSVD] = NULL; + calls_table[API_GETC] = &API_getc; + calls_table[API_PUTC] = &API_putc; + calls_table[API_TSTC] = &API_tstc; + calls_table[API_PUTS] = &API_puts; + calls_table[API_RESET] = &API_reset; + calls_table[API_GET_SYS_INFO] = &API_get_sys_info; + calls_table[API_UDELAY] = &API_udelay; + calls_table[API_GET_TIMER] = &API_get_timer; + calls_table[API_DEV_ENUM] = &API_dev_enum; + calls_table[API_DEV_OPEN] = &API_dev_open; + calls_table[API_DEV_CLOSE] = &API_dev_close; + calls_table[API_DEV_READ] = &API_dev_read; + calls_table[API_DEV_WRITE] = &API_dev_write; + calls_table[API_ENV_GET] = &API_env_get; + calls_table[API_ENV_SET] = &API_env_set; + calls_table[API_ENV_ENUM] = &API_env_enum; + calls_table[API_DISPLAY_GET_INFO] = &API_display_get_info; + calls_table[API_DISPLAY_DRAW_BITMAP] = &API_display_draw_bitmap; + calls_table[API_DISPLAY_CLEAR] = &API_display_clear; + calls_no = API_MAXCALL; + + debugf("API initialized with %d calls\n", calls_no); + + dev_stor_init(); + + /* + * Produce the signature so the API consumers can find it + */ + sig = malloc(sizeof(struct api_signature)); + if (sig == NULL) { + printf("API: could not allocate memory for the signature!\n"); + return; + } + + debugf("API sig @ 0x%08x\n", sig); + memcpy(sig->magic, API_SIG_MAGIC, 8); + sig->version = API_SIG_VERSION; + sig->syscall = &syscall; + sig->checksum = 0; + sig->checksum = crc32(0, (unsigned char *)sig, + sizeof(struct api_signature)); + debugf("syscall entry: 0x%08x\n", sig->syscall); +} + +void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size, + int flags) +{ + int i; + + if (!si->mr || !size || (flags == 0)) + return; + + /* find free slot */ + for (i = 0; i < si->mr_no; i++) + if (si->mr[i].flags == 0) { + /* insert new mem region */ + si->mr[i].start = start; + si->mr[i].size = size; + si->mr[i].flags = flags; + return; + } +}
diff --git a/u-boot-imx/api/api_display.c b/u-boot-imx/api/api_display.c new file mode 100644 index 0000000..fe04d39 --- /dev/null +++ b/u-boot-imx/api/api_display.c
@@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <api_public.h> +#include <lcd.h> +#include <video_font.h> /* Get font width and height */ + +/* lcd.h needs BMP_LOGO_HEIGHT to calculate CONSOLE_ROWS */ +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) +#include <bmp_logo.h> +#endif + +/* TODO(clchiou): add support of video device */ + +int display_get_info(int type, struct display_info *di) +{ + if (!di) + return API_EINVAL; + + switch (type) { + default: + debug("%s: unsupport display device type: %d\n", + __FILE__, type); + return API_ENODEV; +#ifdef CONFIG_LCD + case DISPLAY_TYPE_LCD: + di->pixel_width = panel_info.vl_col; + di->pixel_height = panel_info.vl_row; + di->screen_rows = lcd_get_screen_rows(); + di->screen_cols = lcd_get_screen_columns(); + break; +#endif + } + + di->type = type; + return 0; +} + +int display_draw_bitmap(ulong bitmap, int x, int y) +{ + if (!bitmap) + return API_EINVAL; +#ifdef CONFIG_LCD + return lcd_display_bitmap(bitmap, x, y); +#else + return API_ENODEV; +#endif +} + +void display_clear(void) +{ +#ifdef CONFIG_LCD + lcd_clear(); +#endif +}
diff --git a/u-boot-imx/api/api_net.c b/u-boot-imx/api/api_net.c new file mode 100644 index 0000000..7b3805e --- /dev/null +++ b/u-boot-imx/api/api_net.c
@@ -0,0 +1,117 @@ +/* + * (C) Copyright 2007 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <common.h> +#include <net.h> +#include <linux/types.h> +#include <api_public.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define DEBUG +#undef DEBUG + +#ifdef DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0) + +#ifdef CONFIG_CMD_NET + +static int dev_valid_net(void *cookie) +{ + return ((void *)eth_get_dev() == cookie) ? 1 : 0; +} + +int dev_open_net(void *cookie) +{ + if (!dev_valid_net(cookie)) + return API_ENODEV; + + if (eth_init(gd->bd) < 0) + return API_EIO; + + return 0; +} + +int dev_close_net(void *cookie) +{ + if (!dev_valid_net(cookie)) + return API_ENODEV; + + eth_halt(); + return 0; +} + +/* + * There can only be one active eth interface at a time - use what is + * currently set to eth_current + */ +int dev_enum_net(struct device_info *di) +{ + struct eth_device *eth_current = eth_get_dev(); + + di->type = DEV_TYP_NET; + di->cookie = (void *)eth_current; + if (di->cookie == NULL) + return 0; + + memcpy(di->di_net.hwaddr, eth_current->enetaddr, 6); + + debugf("device found, returning cookie 0x%08x\n", + (u_int32_t)di->cookie); + + return 1; +} + +int dev_write_net(void *cookie, void *buf, int len) +{ + /* XXX verify that cookie points to a valid net device??? */ + + return eth_send(buf, len); +} + +int dev_read_net(void *cookie, void *buf, int len) +{ + /* XXX verify that cookie points to a valid net device??? */ + + return eth_receive(buf, len); +} + +#else + +int dev_open_net(void *cookie) +{ + return API_ENODEV; +} + +int dev_close_net(void *cookie) +{ + return API_ENODEV; +} + +int dev_enum_net(struct device_info *di) +{ + return 0; +} + +int dev_write_net(void *cookie, void *buf, int len) +{ + return API_ENODEV; +} + +int dev_read_net(void *cookie, void *buf, int len) +{ + return API_ENODEV; +} + +#endif
diff --git a/u-boot-imx/api/api_platform-arm.c b/u-boot-imx/api/api_platform-arm.c new file mode 100644 index 0000000..eb5338f --- /dev/null +++ b/u-boot-imx/api/api_platform-arm.c
@@ -0,0 +1,37 @@ +/* + * (C) Copyright 2007 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file contains routines that fetch data from ARM-dependent sources + * (bd_info etc.) + */ + +#include <config.h> +#include <linux/types.h> +#include <api_public.h> + +#include <asm/u-boot.h> +#include <asm/global_data.h> + +#include "api_private.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Important notice: handling of individual fields MUST be kept in sync with + * include/asm-arm/u-boot.h and include/asm-arm/global_data.h, so any changes + * need to reflect their current state and layout of structures involved! + */ +int platform_sys_info(struct sys_info *si) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) + platform_set_mr(si, gd->bd->bi_dram[i].start, + gd->bd->bi_dram[i].size, MR_ATTR_DRAM); + + return 1; +}
diff --git a/u-boot-imx/api/api_platform-powerpc.c b/u-boot-imx/api/api_platform-powerpc.c new file mode 100644 index 0000000..f23f175 --- /dev/null +++ b/u-boot-imx/api/api_platform-powerpc.c
@@ -0,0 +1,54 @@ +/* + * (C) Copyright 2007 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file contains routines that fetch data from PowerPC-dependent sources + * (bd_info etc.) + */ + +#include <config.h> +#include <linux/types.h> +#include <api_public.h> + +#include <asm/u-boot.h> +#include <asm/global_data.h> + +#include "api_private.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Important notice: handling of individual fields MUST be kept in sync with + * include/asm-ppc/u-boot.h and include/asm-ppc/global_data.h, so any changes + * need to reflect their current state and layout of structures involved! + */ +int platform_sys_info(struct sys_info *si) +{ + si->clk_bus = gd->bus_clk; + si->clk_cpu = gd->cpu_clk; + +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_MPC8260) || \ + defined(CONFIG_E500) || defined(CONFIG_MPC86xx) +#define bi_bar bi_immr_base +#elif defined(CONFIG_MPC5xxx) +#define bi_bar bi_mbar_base +#elif defined(CONFIG_MPC83xx) +#define bi_bar bi_immrbar +#endif + +#if defined(bi_bar) + si->bar = gd->bd->bi_bar; +#undef bi_bar +#else + si->bar = 0; +#endif + + platform_set_mr(si, gd->bd->bi_memstart, gd->bd->bi_memsize, MR_ATTR_DRAM); + platform_set_mr(si, gd->bd->bi_flashstart, gd->bd->bi_flashsize, MR_ATTR_FLASH); + platform_set_mr(si, gd->bd->bi_sramstart, gd->bd->bi_sramsize, MR_ATTR_SRAM); + + return 1; +}
diff --git a/u-boot-imx/api/api_private.h b/u-boot-imx/api/api_private.h new file mode 100644 index 0000000..a8866ef --- /dev/null +++ b/u-boot-imx/api/api_private.h
@@ -0,0 +1,35 @@ +/* + * (C) Copyright 2007 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _API_PRIVATE_H_ +#define _API_PRIVATE_H_ + +void api_init(void); +void platform_set_mr(struct sys_info *, unsigned long, unsigned long, int); +int platform_sys_info(struct sys_info *); + +void dev_enum_reset(void); +int dev_enum_storage(struct device_info *); +int dev_enum_net(struct device_info *); + +int dev_open_stor(void *); +int dev_open_net(void *); +int dev_close_stor(void *); +int dev_close_net(void *); + +lbasize_t dev_read_stor(void *, void *, lbasize_t, lbastart_t); +int dev_read_net(void *, void *, int); +int dev_write_net(void *, void *, int); + +void dev_stor_init(void); + +int display_get_info(int type, struct display_info *di); +int display_draw_bitmap(ulong bitmap, int x, int y); +void display_clear(void); + +#endif /* _API_PRIVATE_H_ */
diff --git a/u-boot-imx/api/api_storage.c b/u-boot-imx/api/api_storage.c new file mode 100644 index 0000000..b76b07d --- /dev/null +++ b/u-boot-imx/api/api_storage.c
@@ -0,0 +1,373 @@ +/* + * (C) Copyright 2007-2008 Semihalf + * + * Written by: Rafal Jaworowski <raj@semihalf.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <common.h> +#include <api_public.h> + +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +#include <usb.h> +#endif + +#define DEBUG +#undef DEBUG + +#ifdef DEBUG +#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0) +#else +#define debugf(fmt, args...) +#endif + +#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0) + + +#define ENUM_IDE 0 +#define ENUM_USB 1 +#define ENUM_SCSI 2 +#define ENUM_MMC 3 +#define ENUM_SATA 4 +#define ENUM_MAX 5 + +struct stor_spec { + int max_dev; + int enum_started; + int enum_ended; + int type; /* "external" type: DT_STOR_{IDE,USB,etc} */ + char *name; +}; + +static struct stor_spec specs[ENUM_MAX] = { { 0, 0, 0, 0, "" }, }; + + +void dev_stor_init(void) +{ +#if defined(CONFIG_CMD_IDE) + specs[ENUM_IDE].max_dev = CONFIG_SYS_IDE_MAXDEVICE; + specs[ENUM_IDE].enum_started = 0; + specs[ENUM_IDE].enum_ended = 0; + specs[ENUM_IDE].type = DEV_TYP_STOR | DT_STOR_IDE; + specs[ENUM_IDE].name = "ide"; +#endif +#if defined(CONFIG_CMD_MMC) + specs[ENUM_MMC].max_dev = CONFIG_SYS_MMC_MAX_DEVICE; + specs[ENUM_MMC].enum_started = 0; + specs[ENUM_MMC].enum_ended = 0; + specs[ENUM_MMC].type = DEV_TYP_STOR | DT_STOR_MMC; + specs[ENUM_MMC].name = "mmc"; +#endif +#if defined(CONFIG_CMD_SATA) + specs[ENUM_SATA].max_dev = CONFIG_SYS_SATA_MAX_DEVICE; + specs[ENUM_SATA].enum_started = 0; + specs[ENUM_SATA].enum_ended = 0; + specs[ENUM_SATA].type = DEV_TYP_STOR | DT_STOR_SATA; + specs[ENUM_SATA].name = "sata"; +#endif +#if defined(CONFIG_CMD_SCSI) + specs[ENUM_SCSI].max_dev = CONFIG_SYS_SCSI_MAX_DEVICE; + specs[ENUM_SCSI].enum_started = 0; + specs[ENUM_SCSI].enum_ended = 0; + specs[ENUM_SCSI].type = DEV_TYP_STOR | DT_STOR_SCSI; + specs[ENUM_SCSI].name = "scsi"; +#endif +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) + specs[ENUM_USB].max_dev = USB_MAX_STOR_DEV; + specs[ENUM_USB].enum_started = 0; + specs[ENUM_USB].enum_ended = 0; + specs[ENUM_USB].type = DEV_TYP_STOR | DT_STOR_USB; + specs[ENUM_USB].name = "usb"; +#endif +} + +/* + * Finds next available device in the storage group + * + * type: storage group type - ENUM_IDE, ENUM_SCSI etc. + * + * first: if 1 the first device in the storage group is returned (if + * exists), if 0 the next available device is searched + * + * more: returns 0/1 depending if there are more devices in this group + * available (for future iterations) + * + * returns: 0/1 depending if device found in this iteration + */ +static int dev_stor_get(int type, int first, int *more, struct device_info *di) +{ + int found = 0; + *more = 0; + + int i; + + block_dev_desc_t *dd; + + if (first) { + di->cookie = (void *)get_dev(specs[type].name, 0); + if (di->cookie == NULL) + return 0; + else + found = 1; + + } else { + for (i = 0; i < specs[type].max_dev; i++) + if (di->cookie == (void *)get_dev(specs[type].name, i)) { + /* previous cookie found -- advance to the + * next device, if possible */ + + if (++i >= specs[type].max_dev) { + /* out of range, no more to enum */ + di->cookie = NULL; + break; + } + + di->cookie = (void *)get_dev(specs[type].name, i); + if (di->cookie == NULL) + return 0; + else + found = 1; + + /* provide hint if there are more devices in + * this group to enumerate */ + if ((i + 1) < specs[type].max_dev) + *more = 1; + + break; + } + } + + if (found) { + di->type = specs[type].type; + + if (di->cookie != NULL) { + dd = (block_dev_desc_t *)di->cookie; + if (dd->type == DEV_TYPE_UNKNOWN) { + debugf("device instance exists, but is not active.."); + found = 0; + } else { + di->di_stor.block_count = dd->lba; + di->di_stor.block_size = dd->blksz; + } + } + + } else + di->cookie = NULL; + + return found; +} + + +/* + * returns: ENUM_IDE, ENUM_USB etc. based on block_dev_desc_t + */ +static int dev_stor_type(block_dev_desc_t *dd) +{ + int i, j; + + for (i = ENUM_IDE; i < ENUM_MAX; i++) + for (j = 0; j < specs[i].max_dev; j++) + if (dd == get_dev(specs[i].name, j)) + return i; + + return ENUM_MAX; +} + + +/* + * returns: 0/1 whether cookie points to some device in this group + */ +static int dev_is_stor(int type, struct device_info *di) +{ + return (dev_stor_type(di->cookie) == type) ? 1 : 0; +} + + +static int dev_enum_stor(int type, struct device_info *di) +{ + int found = 0, more = 0; + + debugf("called, type %d\n", type); + + /* + * Formulae for enumerating storage devices: + * 1. if cookie (hint from previous enum call) is NULL we start again + * with enumeration, so return the first available device, done. + * + * 2. if cookie is not NULL, check if it identifies some device in + * this group: + * + * 2a. if cookie is a storage device from our group (IDE, USB etc.), + * return next available (if exists) in this group + * + * 2b. if it isn't device from our group, check if such devices were + * ever enumerated before: + * - if not, return the first available device from this group + * - else return 0 + */ + + if (di->cookie == NULL) { + + debugf("group%d - enum restart\n", type); + + /* + * 1. Enumeration (re-)started: take the first available + * device, if exists + */ + found = dev_stor_get(type, 1, &more, di); + specs[type].enum_started = 1; + + } else if (dev_is_stor(type, di)) { + + debugf("group%d - enum continued for the next device\n", type); + + if (specs[type].enum_ended) { + debugf("group%d - nothing more to enum!\n", type); + return 0; + } + + /* 2a. Attempt to take a next available device in the group */ + found = dev_stor_get(type, 0, &more, di); + + } else { + + if (specs[type].enum_ended) { + debugf("group %d - already enumerated, skipping\n", type); + return 0; + } + + debugf("group%d - first time enum\n", type); + + if (specs[type].enum_started == 0) { + /* + * 2b. If enumerating devices in this group did not + * happen before, it means the cookie pointed to a + * device frome some other group (another storage + * group, or network); in this case try to take the + * first available device from our group + */ + specs[type].enum_started = 1; + + /* + * Attempt to take the first device in this group: + *'first element' flag is set + */ + found = dev_stor_get(type, 1, &more, di); + + } else { + errf("group%d - out of order iteration\n", type); + found = 0; + more = 0; + } + } + + /* + * If there are no more devices in this group, consider its + * enumeration finished + */ + specs[type].enum_ended = (!more) ? 1 : 0; + + if (found) + debugf("device found, returning cookie 0x%08x\n", + (u_int32_t)di->cookie); + else + debugf("no device found\n"); + + return found; +} + +void dev_enum_reset(void) +{ + int i; + + for (i = 0; i < ENUM_MAX; i ++) { + specs[i].enum_started = 0; + specs[i].enum_ended = 0; + } +} + +int dev_enum_storage(struct device_info *di) +{ + int i; + + /* + * check: ide, usb, scsi, mmc + */ + for (i = ENUM_IDE; i < ENUM_MAX; i ++) { + if (dev_enum_stor(i, di)) + return 1; + } + + return 0; +} + +static int dev_stor_is_valid(int type, block_dev_desc_t *dd) +{ + int i; + + for (i = 0; i < specs[type].max_dev; i++) + if (dd == get_dev(specs[type].name, i)) + if (dd->type != DEV_TYPE_UNKNOWN) + return 1; + + return 0; +} + + +int dev_open_stor(void *cookie) +{ + int type = dev_stor_type(cookie); + + if (type == ENUM_MAX) + return API_ENODEV; + + if (dev_stor_is_valid(type, (block_dev_desc_t *)cookie)) + return 0; + + return API_ENODEV; +} + + +int dev_close_stor(void *cookie) +{ + /* + * Not much to do as we actually do not alter storage devices upon + * close + */ + return 0; +} + + +static int dev_stor_index(block_dev_desc_t *dd) +{ + int i, type; + + type = dev_stor_type(dd); + for (i = 0; i < specs[type].max_dev; i++) + if (dd == get_dev(specs[type].name, i)) + return i; + + return (specs[type].max_dev); +} + + +lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start) +{ + int type; + block_dev_desc_t *dd = (block_dev_desc_t *)cookie; + + if ((type = dev_stor_type(dd)) == ENUM_MAX) + return 0; + + if (!dev_stor_is_valid(type, dd)) + return 0; + + if ((dd->block_read) == NULL) { + debugf("no block_read() for device 0x%08x\n", cookie); + return 0; + } + + return (dd->block_read(dev_stor_index(dd), start, len, buf)); +}
diff --git a/u-boot-imx/arch/Kconfig b/u-boot-imx/arch/Kconfig new file mode 100644 index 0000000..2ca5305 --- /dev/null +++ b/u-boot-imx/arch/Kconfig
@@ -0,0 +1,160 @@ +config HAVE_GENERIC_BOARD + bool + +config SYS_GENERIC_BOARD + bool + depends on HAVE_GENERIC_BOARD + +choice + prompt "Architecture select" + default SANDBOX + +config ARC + bool "ARC architecture" + select HAVE_PRIVATE_LIBGCC + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +config ARM + bool "ARM architecture" + select HAVE_PRIVATE_LIBGCC + select HAVE_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +config AVR32 + bool "AVR32 architecture" + select HAVE_GENERIC_BOARD + +config BLACKFIN + bool "Blackfin architecture" + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + +config M68K + bool "M68000 architecture" + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + +config MICROBLAZE + bool "MicroBlaze architecture" + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +config MIPS + bool "MIPS architecture" + select HAVE_PRIVATE_LIBGCC + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + +config NDS32 + bool "NDS32 architecture" + +config NIOS2 + bool "Nios II architecture" + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + +config OPENRISC + bool "OpenRISC architecture" + +config PPC + bool "PowerPC architecture" + select HAVE_PRIVATE_LIBGCC + select HAVE_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +config SANDBOX + bool "Sandbox" + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +config SH + bool "SuperH architecture" + select HAVE_PRIVATE_LIBGCC + +config SPARC + bool "SPARC architecture" + +config X86 + bool "x86 architecture" + select HAVE_PRIVATE_LIBGCC + select HAVE_GENERIC_BOARD + select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL + +endchoice + +config SYS_ARCH + string + help + This option should contain the architecture name to build the + appropriate arch/<CONFIG_SYS_ARCH> directory. + All the architectures should specify this option correctly. + +config SYS_CPU + string + help + This option should contain the CPU name to build the correct + arch/<CONFIG_SYS_ARCH>/cpu/<CONFIG_SYS_CPU> directory. + + This is optional. For those targets without the CPU directory, + leave this option empty. + +config SYS_SOC + string + help + This option should contain the SoC name to build the directory + arch/<CONFIG_SYS_ARCH>/cpu/<CONFIG_SYS_CPU>/<CONFIG_SYS_SOC>. + + This is optional. For those targets without the SoC directory, + leave this option empty. + +config SYS_VENDOR + string + help + This option should contain the vendor name of the target board. + If it is set and + board/<CONFIG_SYS_VENDOR>/common/Makefile exists, the vendor common + directory is compiled. + If CONFIG_SYS_BOARD is also set, the sources under + board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> directory are compiled. + + This is optional. For those targets without the vendor directory, + leave this option empty. + +config SYS_BOARD + string + help + This option should contain the name of the target board. + If it is set, either board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> + or board/<CONFIG_SYS_BOARD> directory is compiled depending on + whether CONFIG_SYS_VENDOR is set or not. + + This is optional. For those targets without the board directory, + leave this option empty. + +config SYS_CONFIG_NAME + string + help + This option should contain the base name of board header file. + The header file include/configs/<CONFIG_SYS_CONFIG_NAME>.h + should be included from include/config.h. + +source "arch/arc/Kconfig" +source "arch/arm/Kconfig" +source "arch/avr32/Kconfig" +source "arch/blackfin/Kconfig" +source "arch/m68k/Kconfig" +source "arch/microblaze/Kconfig" +source "arch/mips/Kconfig" +source "arch/nds32/Kconfig" +source "arch/nios2/Kconfig" +source "arch/openrisc/Kconfig" +source "arch/powerpc/Kconfig" +source "arch/sandbox/Kconfig" +source "arch/sh/Kconfig" +source "arch/sparc/Kconfig" +source "arch/x86/Kconfig"
diff --git a/u-boot-imx/arch/arc/Kconfig b/u-boot-imx/arch/arc/Kconfig new file mode 100644 index 0000000..c044ad4 --- /dev/null +++ b/u-boot-imx/arch/arc/Kconfig
@@ -0,0 +1,159 @@ +menu "ARC architecture" + depends on ARC + +config SYS_ARCH + default "arc" + +config USE_PRIVATE_LIBGCC + default y + +config SYS_CPU + default "arcv1" if ISA_ARCOMPACT + default "arcv2" if ISA_ARCV2 + +choice + prompt "ARC Instruction Set" + default ISA_ARCOMPACT + +config ISA_ARCOMPACT + bool "ARCompact ISA" + help + The original ARC ISA of ARC600/700 cores + +config ISA_ARCV2 + bool "ARC ISA v2" + help + ISA for the Next Generation ARC-HS cores + +endchoice + +choice + prompt "CPU selection" + default CPU_ARC770D if ISA_ARCOMPACT + default CPU_ARCHS38 if ISA_ARCV2 + +config CPU_ARC750D + bool "ARC 750D" + select ARC_MMU_V2 + depends on ISA_ARCOMPACT + help + Choose this option to build an U-Boot for ARC750D CPU. + +config CPU_ARC770D + bool "ARC 770D" + select ARC_MMU_V3 + depends on ISA_ARCOMPACT + help + Choose this option to build an U-Boot for ARC770D CPU. + +config CPU_ARCEM6 + bool "ARC EM6" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS36 + bool "ARC HS36" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS38 + bool "ARC HS38" + select ARC_MMU_V4 + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA with MMU. + +endchoice + +choice + prompt "MMU Version" + default ARC_MMU_V3 if CPU_ARC770D + default ARC_MMU_V2 if CPU_ARC750D + default ARC_MMU_ABSENT if CPU_ARCEM6 + default ARC_MMU_ABSENT if CPU_ARCHS36 + default ARC_MMU_V4 if CPU_ARCHS38 + +config ARC_MMU_ABSENT + bool "No MMU" + help + No MMU + +config ARC_MMU_V2 + bool "MMU v2" + depends on CPU_ARC750D + help + Fixed the deficiency of v1 - possible thrashing in memcpy sceanrio + when 2 D-TLB and 1 I-TLB entries index into same 2way set. + +config ARC_MMU_V3 + bool "MMU v3" + depends on CPU_ARC770D + help + Introduced with ARC700 4.10: New Features + Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) + Shared Address Spaces (SASID) + +config ARC_MMU_V4 + bool "MMU v4" + depends on CPU_ARCHS38 + help + Introduced as a part of ARC HS38 release. + +endchoice + +config CPU_BIG_ENDIAN + bool "Enable Big Endian Mode" + default n + help + Build kernel for Big Endian Mode of ARC CPU + +config SYS_ICACHE_OFF + bool "Do not use Instruction Cache" + default n + +config SYS_DCACHE_OFF + bool "Do not use Data Cache" + default n + +config ARC_CACHE_LINE_SHIFT + int "Cache Line Length (as power of 2)" + range 5 7 + default "6" + depends on !SYS_DCACHE_OFF || !SYS_ICACHE_OFF + help + Starting with ARC700 4.9, Cache line length is configurable, + This option specifies "N", with Line-len = 2 power N + So line lengths of 32, 64, 128 are specified by 5,6,7, respectively + Linux only supports same line lengths for I and D caches. + +choice + prompt "Target select" + +config TARGET_DUMMY + bool "Dummy target" + help + Please select one of real target boards below! + This target is only meant to force "makedefconfig" to put + TARGET_xxx in defconfig even this is the first target from the list + below. + +config TARGET_TB100 + bool "Support tb100" + +config TARGET_ARCANGEL4 + bool "Support arcangel4" + +config TARGET_AXS101 + bool "Support axs101" + +endchoice + +source "board/abilis/tb100/Kconfig" +source "board/synopsys/Kconfig" +source "board/synopsys/axs101/Kconfig" + +endmenu
diff --git a/u-boot-imx/arch/arc/Makefile b/u-boot-imx/arch/arc/Makefile new file mode 100644 index 0000000..a59231e --- /dev/null +++ b/u-boot-imx/arch/arc/Makefile
@@ -0,0 +1,21 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +libs-y += arch/arc/cpu/$(CPU)/ +libs-y += arch/arc/lib/ + +# MetaWare debugger doesn't support PIE (position-independent executable) +# so the only way to load U-Boot in MDB is to fake it by: +# 1. Reset PIE flag in ELF header +# 2. Strip all debug information from elf +ifdef CONFIG_SYS_LITTLE_ENDIAN + EXEC_TYPE_OFFSET=16 +else + EXEC_TYPE_OFFSET=17 +endif + +mdbtrick: u-boot + $(Q)printf '\x02' | dd of=u-boot bs=1 seek=$(EXEC_TYPE_OFFSET) count=1 \ + conv=notrunc &> /dev/null + $(Q)$(CROSS_COMPILE)strip -g u-boot
diff --git a/u-boot-imx/arch/arc/config.mk b/u-boot-imx/arch/arc/config.mk new file mode 100644 index 0000000..04c034b --- /dev/null +++ b/u-boot-imx/arch/arc/config.mk
@@ -0,0 +1,59 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifndef CONFIG_CPU_BIG_ENDIAN +CONFIG_SYS_LITTLE_ENDIAN = 1 +else +CONFIG_SYS_BIG_ENDIAN = 1 +endif + +ifdef CONFIG_SYS_LITTLE_ENDIAN +ARC_CROSS_COMPILE := arc-buildroot-linux-uclibc- +PLATFORM_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -mlittle-endian +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +ARC_CROSS_COMPILE := arceb-buildroot-linux-uclibc- +PLATFORM_LDFLAGS += -EB +PLATFORM_CPPFLAGS += -mbig-endian +endif + +ifeq ($(CROSS_COMPILE),) +CROSS_COMPILE := $(ARC_CROSS_COMPILE) +endif + +ifdef CONFIG_ARC_MMU_VER +CONFIG_MMU = 1 +endif + +ifdef CONFIG_CPU_ARC750D +PLATFORM_CPPFLAGS += -marc700 +endif + +ifdef CONFIG_CPU_ARC770D +PLATFORM_CPPFLAGS += -marc700 -mlock -mswape +endif + +ifdef CONFIG_CPU_ARCEM6 +PLATFORM_CPPFLAGS += -marcem +endif + +ifdef CONFIG_CPU_ARCHS34 +PLATFORM_CPPFLAGS += -marchs +endif + +ifdef CONFIG_CPU_ARCHS38 +PLATFORM_CPPFLAGS += -marchs +endif + +PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 + +# Needed for relocation +LDFLAGS_FINAL += -pie + +# Load address for standalone apps +CONFIG_STANDALONE_LOAD_ADDR ?= 0x82000000
diff --git a/u-boot-imx/arch/arc/cpu/arcv1/Makefile b/u-boot-imx/arch/arc/cpu/arcv1/Makefile new file mode 100644 index 0000000..6d17ab2 --- /dev/null +++ b/u-boot-imx/arch/arc/cpu/arcv1/Makefile
@@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ivt.o
diff --git a/u-boot-imx/arch/arc/cpu/arcv1/ivt.S b/u-boot-imx/arch/arc/cpu/arcv1/ivt.S new file mode 100644 index 0000000..7df47a2 --- /dev/null +++ b/u-boot-imx/arch/arc/cpu/arcv1/ivt.S
@@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.section .ivt, "ax",@progbits +.align 4 +_ivt: + /* Critical system events */ + j _start /* 0 - 0x000 */ + j memory_error /* 1 - 0x008 */ + j instruction_error /* 2 - 0x010 */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr + /* Exceptions */ + j EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ + j EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ + j EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ + j EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ + j EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ + j EV_Trap /* 0x128, Trap exception (0x25) */ + j EV_Extension /* 0x130, Extn Intruction Excp (0x26) */
diff --git a/u-boot-imx/arch/arc/cpu/arcv2/Makefile b/u-boot-imx/arch/arc/cpu/arcv2/Makefile new file mode 100644 index 0000000..e338a0a --- /dev/null +++ b/u-boot-imx/arch/arc/cpu/arcv2/Makefile
@@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ivt.o
diff --git a/u-boot-imx/arch/arc/cpu/arcv2/ivt.S b/u-boot-imx/arch/arc/cpu/arcv2/ivt.S new file mode 100644 index 0000000..d110b5b --- /dev/null +++ b/u-boot-imx/arch/arc/cpu/arcv2/ivt.S
@@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.section .ivt, "a",@progbits +.align 4 + /* Critical system events */ +.word _start /* 0 - 0x000 */ +.word memory_error /* 1 - 0x008 */ +.word instruction_error /* 2 - 0x010 */ + + /* Exceptions */ +.word EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ +.word EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ +.word EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ +.word EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ +.word EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ +.word EV_Trap /* 0x128, Trap exception (0x25) */ +.word EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr
diff --git a/u-boot-imx/arch/arc/cpu/u-boot.lds b/u-boot-imx/arch/arc/cpu/u-boot.lds new file mode 100644 index 0000000..693df74 --- /dev/null +++ b/u-boot-imx/arch/arc/cpu/u-boot.lds
@@ -0,0 +1,86 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc") +OUTPUT_ARCH(arc) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(4); + .text : { + *(.__text_start) + *(.__image_copy_start) + arch/arc/lib/start.o (.text*) + *(.text*) + } + + . = ALIGN(4); + .text_end : + { + *(.__text_end) + } + + . = ALIGN(1024); + .ivt_start : { + *(.__ivt_start) + } + + .ivt : + { + *(.ivt) + } + + .ivt_end : { + *(.__ivt_end) + } + + . = ALIGN(4); + .rodata : { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(4); + .rel_dyn_start : { + *(.__rel_dyn_start) + } + + .rela.dyn : { + *(.rela.dyn) + } + + .rel_dyn_end : { + *(.__rel_dyn_end) + } + + . = ALIGN(4); + .bss_start : { + *(.__bss_start); + } + + .bss : { + *(.bss*) + } + + .bss_end : { + *(.__bss_end); + } + + . = ALIGN(4); + .image_copy_end : { + *(.__image_copy_end) + *(.__init_end) + } +}
diff --git a/u-boot-imx/arch/arc/dts/Makefile b/u-boot-imx/arch/arc/dts/Makefile new file mode 100644 index 0000000..5bc6f44 --- /dev/null +++ b/u-boot-imx/arch/arc/dts/Makefile
@@ -0,0 +1,12 @@ +dtb-$(CONFIG_TARGET_ARCANGEL4) += arcangel4.dtb +dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb
diff --git a/u-boot-imx/arch/arc/dts/abilis_tb100.dts b/u-boot-imx/arch/arc/dts/abilis_tb100.dts new file mode 100644 index 0000000..cf395c4 --- /dev/null +++ b/u-boot-imx/arch/arc/dts/abilis_tb100.dts
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &uart0; + }; + + uart0: serial@ff100000 { + compatible = "snps,dw-apb-uart"; + reg = <0xff100000 0x1000>; + reg-shift = <2>; + reg-io-width = <4>; + }; +};
diff --git a/u-boot-imx/arch/arc/dts/arcangel4.dts b/u-boot-imx/arch/arc/dts/arcangel4.dts new file mode 100644 index 0000000..bfcb9d8 --- /dev/null +++ b/u-boot-imx/arch/arc/dts/arcangel4.dts
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &arcuart0; + }; + + arcuart0: serial@0xc0fc1000 { + compatible = "snps,arc-uart"; + reg = <0xc0fc1000 0x100>; + clock-frequency = <80000000>; + }; + +};
diff --git a/u-boot-imx/arch/arc/dts/skeleton.dtsi b/u-boot-imx/arch/arc/dts/skeleton.dtsi new file mode 100644 index 0000000..b41d241 --- /dev/null +++ b/u-boot-imx/arch/arc/dts/skeleton.dtsi
@@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +};
diff --git a/u-boot-imx/arch/arc/include/asm/arcregs.h b/u-boot-imx/arch/arc/include/asm/arcregs.h new file mode 100644 index 0000000..0e11dcc --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/arcregs.h
@@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARC_ARCREGS_H +#define _ASM_ARC_ARCREGS_H + +#include <asm/cache.h> + +/* + * ARC architecture has additional address space - auxiliary registers. + * These registers are mostly used for configuration purposes. + * These registers are not memory mapped and special commands are used for + * access: "lr"/"sr". + */ + +#define ARC_AUX_IDENTITY 0x04 +#define ARC_AUX_STATUS32 0x0a + +/* Instruction cache related auxiliary registers */ +#define ARC_AUX_IC_IVIC 0x10 +#define ARC_AUX_IC_CTRL 0x11 +#define ARC_AUX_IC_IVIL 0x19 +#if (CONFIG_ARC_MMU_VER == 3) +#define ARC_AUX_IC_PTAG 0x1E +#endif +#define ARC_BCR_IC_BUILD 0x77 + +/* Timer related auxiliary registers */ +#define ARC_AUX_TIMER0_CNT 0x21 /* Timer 0 count */ +#define ARC_AUX_TIMER0_CTRL 0x22 /* Timer 0 control */ +#define ARC_AUX_TIMER0_LIMIT 0x23 /* Timer 0 limit */ + +#define ARC_AUX_INTR_VEC_BASE 0x25 + +/* Data cache related auxiliary registers */ +#define ARC_AUX_DC_IVDC 0x47 +#define ARC_AUX_DC_CTRL 0x48 + +#define ARC_AUX_DC_IVDL 0x4A +#define ARC_AUX_DC_FLSH 0x4B +#define ARC_AUX_DC_FLDL 0x4C +#if (CONFIG_ARC_MMU_VER == 3) +#define ARC_AUX_DC_PTAG 0x5C +#endif +#define ARC_BCR_DC_BUILD 0x72 +#define ARC_BCR_SLC 0xce +#define ARC_AUX_SLC_CONTROL 0x903 +#define ARC_AUX_SLC_FLUSH 0x904 +#define ARC_AUX_SLC_INVALIDATE 0x905 + +#ifndef __ASSEMBLY__ +/* Accessors for auxiliary registers */ +#define read_aux_reg(reg) __builtin_arc_lr(reg) + +/* gcc builtin sr needs reg param to be long immediate */ +#define write_aux_reg(reg_immed, val) \ + __builtin_arc_sr((unsigned int)val, reg_immed) +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARC_ARCREGS_H */
diff --git a/u-boot-imx/arch/arc/include/asm/bitops.h b/u-boot-imx/arch/arc/include/asm/bitops.h new file mode 100644 index 0000000..85721aa --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/bitops.h
@@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_BITOPS_H +#define __ASM_ARC_BITOPS_H + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __ASM_ARC_BITOPS_H */
diff --git a/u-boot-imx/arch/arc/include/asm/byteorder.h b/u-boot-imx/arch/arc/include/asm/byteorder.h new file mode 100644 index 0000000..2fa9776 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/byteorder.h
@@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_BYTEORDER_H +#define __ASM_ARC_BYTEORDER_H + +#include <asm/types.h> + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) + #define __BYTEORDER_HAS_U64__ + #define __SWAB_64_THRU_32__ +#endif + +#ifdef __LITTLE_ENDIAN__ + #include <linux/byteorder/little_endian.h> +#else + #include <linux/byteorder/big_endian.h> +#endif /* CONFIG_SYS_BIG_ENDIAN */ + +#endif /* ASM_ARC_BYTEORDER_H */
diff --git a/u-boot-imx/arch/arc/include/asm/cache.h b/u-boot-imx/arch/arc/include/asm/cache.h new file mode 100644 index 0000000..0b3ebd9 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/cache.h
@@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_CACHE_H +#define __ASM_ARC_CACHE_H + +#include <config.h> + +#ifdef CONFIG_ARC_CACHE_LINE_SHIFT +#define CONFIG_SYS_CACHELINE_SIZE (1 << CONFIG_ARC_CACHE_LINE_SHIFT) +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#else +/* Satisfy users of ARCH_DMA_MINALIGN */ +#define ARCH_DMA_MINALIGN 128 +#endif + +#if defined(ARC_MMU_ABSENT) +#define CONFIG_ARC_MMU_VER 0 +#elif defined(CONFIG_ARC_MMU_V2) +#define CONFIG_ARC_MMU_VER 2 +#elif defined(CONFIG_ARC_MMU_V3) +#define CONFIG_ARC_MMU_VER 3 +#elif defined(CONFIG_ARC_MMU_V4) +#define CONFIG_ARC_MMU_VER 4 +#endif + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_ISA_ARCV2 +void slc_enable(void); +void slc_disable(void); +void slc_flush(void); +void slc_invalidate(void); +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARC_CACHE_H */
diff --git a/u-boot-imx/arch/arc/include/asm/config.h b/u-boot-imx/arch/arc/include/asm/config.h new file mode 100644 index 0000000..d2d7919 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/config.h
@@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_CONFIG_H_ +#define __ASM_ARC_CONFIG_H_ + +#define CONFIG_SYS_BOOT_RAMDISK_HIGH +#define CONFIG_ARCH_EARLY_INIT_R + +#define CONFIG_LMB + +#endif /*__ASM_ARC_CONFIG_H_ */
diff --git a/u-boot-imx/arch/arc/include/asm/errno.h b/u-boot-imx/arch/arc/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/errno.h
@@ -0,0 +1 @@ +#include <asm-generic/errno.h>
diff --git a/u-boot-imx/arch/arc/include/asm/global_data.h b/u-boot-imx/arch/arc/include/asm/global_data.h new file mode 100644 index 0000000..d644e80 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/global_data.h
@@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_GLOBAL_DATA_H +#define __ASM_ARC_GLOBAL_DATA_H + +/* Architecture-specific global data */ +struct arch_global_data { + int running_on_hw; +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r25") + +#endif /* __ASM_ARC_GLOBAL_DATA_H */
diff --git a/u-boot-imx/arch/arc/include/asm/init_helpers.h b/u-boot-imx/arch/arc/include/asm/init_helpers.h new file mode 100644 index 0000000..7607e19 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/init_helpers.h
@@ -0,0 +1,12 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARC_INIT_HELPERS_H +#define _ASM_ARC_INIT_HELPERS_H + +int init_cache_f_r(void); + +#endif /* _ASM_ARC_INIT_HELPERS_H */
diff --git a/u-boot-imx/arch/arc/include/asm/io.h b/u-boot-imx/arch/arc/include/asm/io.h new file mode 100644 index 0000000..24b7337 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/io.h
@@ -0,0 +1,218 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_IO_H +#define __ASM_ARC_IO_H + +#include <linux/types.h> +#include <asm/byteorder.h> + +static inline void sync(void) +{ + /* Not yet implemented */ +} + +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ + u8 b; + + __asm__ __volatile__("ldb%U1 %0, %1\n" + : "=r" (b) + : "m" (*(volatile u8 __force *)addr) + : "memory"); + return b; +} + +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ + u16 s; + + __asm__ __volatile__("ldw%U1 %0, %1\n" + : "=r" (s) + : "m" (*(volatile u16 __force *)addr) + : "memory"); + return s; +} + +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ + u32 w; + + __asm__ __volatile__("ld%U1 %0, %1\n" + : "=r" (w) + : "m" (*(volatile u32 __force *)addr) + : "memory"); + return w; +} + +#define readb __raw_readb + +static inline u16 readw(const volatile void __iomem *addr) +{ + return __le16_to_cpu(__raw_readw(addr)); +} + +static inline u32 readl(const volatile void __iomem *addr) +{ + return __le32_to_cpu(__raw_readl(addr)); +} + +static inline void __raw_writeb(u8 b, volatile void __iomem *addr) +{ + __asm__ __volatile__("stb%U1 %0, %1\n" + : + : "r" (b), "m" (*(volatile u8 __force *)addr) + : "memory"); +} + +static inline void __raw_writew(u16 s, volatile void __iomem *addr) +{ + __asm__ __volatile__("stw%U1 %0, %1\n" + : + : "r" (s), "m" (*(volatile u16 __force *)addr) + : "memory"); +} + +static inline void __raw_writel(u32 w, volatile void __iomem *addr) +{ + __asm__ __volatile__("st%U1 %0, %1\n" + : + : "r" (w), "m" (*(volatile u32 __force *)addr) + : "memory"); +} + +#define writeb __raw_writeb +#define writew(b, addr) __raw_writew(__cpu_to_le16(b), addr) +#define writel(b, addr) __raw_writel(__cpu_to_le32(b), addr) + +static inline int __raw_readsb(unsigned int addr, void *data, int bytelen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "stb.ab r8, [r1, 1]\n" + : + : "r" (addr), "r" (data), "r" (bytelen) + : "r8"); + return bytelen; +} + +static inline int __raw_readsw(unsigned int addr, void *data, int wordlen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "stw.ab r8, [r1, 2]\n" + : + : "r" (addr), "r" (data), "r" (wordlen) + : "r8"); + return wordlen; +} + +static inline int __raw_readsl(unsigned int addr, void *data, int longlen) +{ + __asm__ __volatile__ ("1:ld.di r8, [r0]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab r8, [r1, 4]\n" + : + : "r" (addr), "r" (data), "r" (longlen) + : "r8"); + return longlen; +} + +static inline int __raw_writesb(unsigned int addr, void *data, int bytelen) +{ + __asm__ __volatile__ ("1:ldb.ab r8, [r1, 1]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (bytelen) + : "r8"); + return bytelen; +} + +static inline int __raw_writesw(unsigned int addr, void *data, int wordlen) +{ + __asm__ __volatile__ ("1:ldw.ab r8, [r1, 2]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (wordlen) + : "r8"); + return wordlen; +} + +static inline int __raw_writesl(unsigned int addr, void *data, int longlen) +{ + __asm__ __volatile__ ("1:ld.ab r8, [r1, 4]\n" + "sub.f r2, r2, 1\n" + "bnz.d 1b\n" + "st.ab.di r8, [r0, 0]\n" + : + : "r" (addr), "r" (data), "r" (longlen) + : "r8"); + return longlen; +} + +#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) + +/* + * 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 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) + +#endif /* __ASM_ARC_IO_H */
diff --git a/u-boot-imx/arch/arc/include/asm/linkage.h b/u-boot-imx/arch/arc/include/asm/linkage.h new file mode 100644 index 0000000..2d1a603 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/linkage.h
@@ -0,0 +1,12 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_LINKAGE_H +#define __ASM_ARC_LINKAGE_H + +#define ASM_NL ` /* use '`' to mark new line in macro */ + +#endif /* __ASM_ARC_LINKAGE_H */
diff --git a/u-boot-imx/arch/arc/include/asm/posix_types.h b/u-boot-imx/arch/arc/include/asm/posix_types.h new file mode 100644 index 0000000..51347a4 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/posix_types.h
@@ -0,0 +1,43 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_POSIX_TYPES_H +#define __ASM_ARC_POSIX_TYPES_H + +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; +#ifdef __GNUC__ +typedef __SIZE_TYPE__ __kernel_size_t; +#else +typedef unsigned int __kernel_size_t; +#endif +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 + +#endif /* __ASM_ARC_POSIX_TYPES_H */
diff --git a/u-boot-imx/arch/arc/include/asm/ptrace.h b/u-boot-imx/arch/arc/include/asm/ptrace.h new file mode 100644 index 0000000..8f73b31 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/ptrace.h
@@ -0,0 +1,50 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_PTRACE_H +#define __ASM_ARC_PTRACE_H + +struct pt_regs { + long bta; + long lp_start; + long lp_end; + long lp_count; + long status32; + long ret; + long blink; + long fp; + long r26; /* gp */ + long r25; + long r24; + long r23; + long r22; + long r21; + long r20; + long r19; + long r18; + long r17; + long r16; + long r15; + long r14; + long r13; + long r12; + long r11; + long r10; + long r9; + long r8; + long r7; + long r6; + long r5; + long r4; + long r3; + long r2; + long r1; + long r0; + long sp; + long ecr; +}; + +#endif /* __ASM_ARC_PTRACE_H */
diff --git a/u-boot-imx/arch/arc/include/asm/relocate.h b/u-boot-imx/arch/arc/include/asm/relocate.h new file mode 100644 index 0000000..4c5f923 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/relocate.h
@@ -0,0 +1,16 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARC_RELOCATE_H +#define _ASM_ARC_RELOCATE_H + +#include <common.h> + +int copy_uboot_to_ram(void); +int clear_bss(void); +int do_elf_reloc_fixups(void); + +#endif /* _ASM_ARC_RELOCATE_H */
diff --git a/u-boot-imx/arch/arc/include/asm/sections.h b/u-boot-imx/arch/arc/include/asm/sections.h new file mode 100644 index 0000000..b8f2a85 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/sections.h
@@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_SECTIONS_H +#define __ASM_ARC_SECTIONS_H + +#include <asm-generic/sections.h> + +extern ulong __text_end; +extern ulong __ivt_start; +extern ulong __ivt_end; +extern ulong __image_copy_start; + +#endif /* __ASM_ARC_SECTIONS_H */
diff --git a/u-boot-imx/arch/arc/include/asm/string.h b/u-boot-imx/arch/arc/include/asm/string.h new file mode 100644 index 0000000..909129c --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/string.h
@@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_STRING_H +#define __ASM_ARC_STRING_H + +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_STRCHR +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRLEN + +extern void *memset(void *ptr, int, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t); +extern void memzero(void *ptr, __kernel_size_t n); +extern int memcmp(const void *, const void *, __kernel_size_t); +extern char *strchr(const char *s, int c); +extern char *strcpy(char *dest, const char *src); +extern int strcmp(const char *cs, const char *ct); +extern __kernel_size_t strlen(const char *); + +#endif /* __ASM_ARC_STRING_H */
diff --git a/u-boot-imx/arch/arc/include/asm/types.h b/u-boot-imx/arch/arc/include/asm/types.h new file mode 100644 index 0000000..24eeb76 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/types.h
@@ -0,0 +1,55 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_TYPES_H +#define __ASM_ARC_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 + */ +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 /* __ASM_ARC_TYPES_H */
diff --git a/u-boot-imx/arch/arc/include/asm/u-boot-arc.h b/u-boot-imx/arch/arc/include/asm/u-boot-arc.h new file mode 100644 index 0000000..a56ccf1 --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/u-boot-arc.h
@@ -0,0 +1,15 @@ +/* + * Copyright (C) 2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_U_BOOT_ARC_H__ +#define __ASM_ARC_U_BOOT_ARC_H__ + +int arch_early_init_r(void); + +void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn)); +void board_init_f_r(void) __attribute__ ((noreturn)); + +#endif /* __ASM_ARC_U_BOOT_ARC_H__ */
diff --git a/u-boot-imx/arch/arc/include/asm/u-boot.h b/u-boot-imx/arch/arc/include/asm/u-boot.h new file mode 100644 index 0000000..e354edf --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/u-boot.h
@@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARC_U_BOOT_H__ +#define __ASM_ARC_U_BOOT_H__ + +#include <asm-generic/u-boot.h> + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_ARC + +#endif /* __ASM_ARC_U_BOOT_H__ */
diff --git a/u-boot-imx/arch/arc/include/asm/unaligned.h b/u-boot-imx/arch/arc/include/asm/unaligned.h new file mode 100644 index 0000000..6cecbbb --- /dev/null +++ b/u-boot-imx/arch/arc/include/asm/unaligned.h
@@ -0,0 +1 @@ +#include <asm-generic/unaligned.h>
diff --git a/u-boot-imx/arch/arc/lib/Makefile b/u-boot-imx/arch/arc/lib/Makefile new file mode 100644 index 0000000..e592802 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/Makefile
@@ -0,0 +1,28 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +head-y := start.o +obj-y += cache.o +obj-y += cpu.o +obj-y += interrupts.o +obj-y += sections.o +obj-y += relocate.o +obj-y += strchr-700.o +obj-y += strcmp.o +obj-y += strcpy-700.o +obj-y += strlen.o +obj-y += memcmp.o +obj-y += memcpy-700.o +obj-y += memset.o +obj-y += reset.o +obj-y += timer.o +obj-y += ints_low.o +obj-y += init_helpers.o + +obj-$(CONFIG_CMD_BOOTM) += bootm.o + +lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _millicodethunk.o libgcc2.o
diff --git a/u-boot-imx/arch/arc/lib/_millicodethunk.S b/u-boot-imx/arch/arc/lib/_millicodethunk.S new file mode 100644 index 0000000..b332416 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/_millicodethunk.S
@@ -0,0 +1,226 @@ +/* + * Copyright (C) 1995, 1997, 2007-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /* ANSI concatenation macros. */ + + #define CONCAT1(a, b) CONCAT2(a, b) + #define CONCAT2(a, b) a ## b + + /* Use the right prefix for global labels. */ + + #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +#ifndef WORKING_ASSEMBLER +#define abs_l abs +#define asl_l asl +#define mov_l mov +#endif + +#define FUNC(X) .type SYM(X),@function +#define HIDDEN_FUNC(X) FUNC(X)` .hidden X +#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X +#define ENDFUNC(X) ENDFUNC0(X) + + .section .text + .align 4 + .global SYM(__st_r13_to_r15) + .global SYM(__st_r13_to_r16) + .global SYM(__st_r13_to_r17) + .global SYM(__st_r13_to_r18) + .global SYM(__st_r13_to_r19) + .global SYM(__st_r13_to_r20) + .global SYM(__st_r13_to_r21) + .global SYM(__st_r13_to_r22) + .global SYM(__st_r13_to_r23) + .global SYM(__st_r13_to_r24) + .global SYM(__st_r13_to_r25) + HIDDEN_FUNC(__st_r13_to_r15) + HIDDEN_FUNC(__st_r13_to_r16) + HIDDEN_FUNC(__st_r13_to_r17) + HIDDEN_FUNC(__st_r13_to_r18) + HIDDEN_FUNC(__st_r13_to_r19) + HIDDEN_FUNC(__st_r13_to_r20) + HIDDEN_FUNC(__st_r13_to_r21) + HIDDEN_FUNC(__st_r13_to_r22) + HIDDEN_FUNC(__st_r13_to_r23) + HIDDEN_FUNC(__st_r13_to_r24) + HIDDEN_FUNC(__st_r13_to_r25) + .align 4 +SYM(__st_r13_to_r25): + st r25, [sp,48] +SYM(__st_r13_to_r24): + st r24, [sp,44] +SYM(__st_r13_to_r23): + st r23, [sp,40] +SYM(__st_r13_to_r22): + st r22, [sp,36] +SYM(__st_r13_to_r21): + st r21, [sp,32] +SYM(__st_r13_to_r20): + st r20, [sp,28] +SYM(__st_r13_to_r19): + st r19, [sp,24] +SYM(__st_r13_to_r18): + st r18, [sp,20] +SYM(__st_r13_to_r17): + st r17, [sp,16] +SYM(__st_r13_to_r16): + st r16, [sp,12] +SYM(__st_r13_to_r15): +#ifdef __ARC700__ + st r15, [sp,8] ; minimum function size to avoid stall: 6 bytes. +#else + st_s r15, [sp,8] +#endif + st_s r14, [sp,4] + j_s.d [%blink] + st_s r13, [sp,0] + ENDFUNC(__st_r13_to_r15) + ENDFUNC(__st_r13_to_r16) + ENDFUNC(__st_r13_to_r17) + ENDFUNC(__st_r13_to_r18) + ENDFUNC(__st_r13_to_r19) + ENDFUNC(__st_r13_to_r20) + ENDFUNC(__st_r13_to_r21) + ENDFUNC(__st_r13_to_r22) + ENDFUNC(__st_r13_to_r23) + ENDFUNC(__st_r13_to_r24) + ENDFUNC(__st_r13_to_r25) + + .section .text + .align 4 +; ================================== +; the loads + + .global SYM(__ld_r13_to_r15) + .global SYM(__ld_r13_to_r16) + .global SYM(__ld_r13_to_r17) + .global SYM(__ld_r13_to_r18) + .global SYM(__ld_r13_to_r19) + .global SYM(__ld_r13_to_r20) + .global SYM(__ld_r13_to_r21) + .global SYM(__ld_r13_to_r22) + .global SYM(__ld_r13_to_r23) + .global SYM(__ld_r13_to_r24) + .global SYM(__ld_r13_to_r25) + HIDDEN_FUNC(__ld_r13_to_r15) + HIDDEN_FUNC(__ld_r13_to_r16) + HIDDEN_FUNC(__ld_r13_to_r17) + HIDDEN_FUNC(__ld_r13_to_r18) + HIDDEN_FUNC(__ld_r13_to_r19) + HIDDEN_FUNC(__ld_r13_to_r20) + HIDDEN_FUNC(__ld_r13_to_r21) + HIDDEN_FUNC(__ld_r13_to_r22) + HIDDEN_FUNC(__ld_r13_to_r23) + HIDDEN_FUNC(__ld_r13_to_r24) + HIDDEN_FUNC(__ld_r13_to_r25) +SYM(__ld_r13_to_r25): + ld r25, [sp,48] +SYM(__ld_r13_to_r24): + ld r24, [sp,44] +SYM(__ld_r13_to_r23): + ld r23, [sp,40] +SYM(__ld_r13_to_r22): + ld r22, [sp,36] +SYM(__ld_r13_to_r21): + ld r21, [sp,32] +SYM(__ld_r13_to_r20): + ld r20, [sp,28] +SYM(__ld_r13_to_r19): + ld r19, [sp,24] +SYM(__ld_r13_to_r18): + ld r18, [sp,20] +SYM(__ld_r13_to_r17): + ld r17, [sp,16] +SYM(__ld_r13_to_r16): + ld r16, [sp,12] +SYM(__ld_r13_to_r15): +#ifdef __ARC700__ + ld r15, [sp,8] ; minimum function size to avoid stall: 6 bytes. +#else + ld_s r15, [sp,8] +#endif + ld_s r14, [sp,4] + j_s.d [%blink] + ld_s r13, [sp,0] + ENDFUNC(__ld_r13_to_r15) + ENDFUNC(__ld_r13_to_r16) + ENDFUNC(__ld_r13_to_r17) + ENDFUNC(__ld_r13_to_r18) + ENDFUNC(__ld_r13_to_r19) + ENDFUNC(__ld_r13_to_r20) + ENDFUNC(__ld_r13_to_r21) + ENDFUNC(__ld_r13_to_r22) + ENDFUNC(__ld_r13_to_r23) + ENDFUNC(__ld_r13_to_r24) + ENDFUNC(__ld_r13_to_r25) + + .global SYM(__ld_r13_to_r14_ret) + .global SYM(__ld_r13_to_r15_ret) + .global SYM(__ld_r13_to_r16_ret) + .global SYM(__ld_r13_to_r17_ret) + .global SYM(__ld_r13_to_r18_ret) + .global SYM(__ld_r13_to_r19_ret) + .global SYM(__ld_r13_to_r20_ret) + .global SYM(__ld_r13_to_r21_ret) + .global SYM(__ld_r13_to_r22_ret) + .global SYM(__ld_r13_to_r23_ret) + .global SYM(__ld_r13_to_r24_ret) + .global SYM(__ld_r13_to_r25_ret) + HIDDEN_FUNC(__ld_r13_to_r14_ret) + HIDDEN_FUNC(__ld_r13_to_r15_ret) + HIDDEN_FUNC(__ld_r13_to_r16_ret) + HIDDEN_FUNC(__ld_r13_to_r17_ret) + HIDDEN_FUNC(__ld_r13_to_r18_ret) + HIDDEN_FUNC(__ld_r13_to_r19_ret) + HIDDEN_FUNC(__ld_r13_to_r20_ret) + HIDDEN_FUNC(__ld_r13_to_r21_ret) + HIDDEN_FUNC(__ld_r13_to_r22_ret) + HIDDEN_FUNC(__ld_r13_to_r23_ret) + HIDDEN_FUNC(__ld_r13_to_r24_ret) + HIDDEN_FUNC(__ld_r13_to_r25_ret) + .section .text + .align 4 +SYM(__ld_r13_to_r25_ret): + ld r25, [sp,48] +SYM(__ld_r13_to_r24_ret): + ld r24, [sp,44] +SYM(__ld_r13_to_r23_ret): + ld r23, [sp,40] +SYM(__ld_r13_to_r22_ret): + ld r22, [sp,36] +SYM(__ld_r13_to_r21_ret): + ld r21, [sp,32] +SYM(__ld_r13_to_r20_ret): + ld r20, [sp,28] +SYM(__ld_r13_to_r19_ret): + ld r19, [sp,24] +SYM(__ld_r13_to_r18_ret): + ld r18, [sp,20] +SYM(__ld_r13_to_r17_ret): + ld r17, [sp,16] +SYM(__ld_r13_to_r16_ret): + ld r16, [sp,12] +SYM(__ld_r13_to_r15_ret): + ld r15, [sp,8] +SYM(__ld_r13_to_r14_ret): + ld blink,[sp,r12] + ld_s r14, [sp,4] + ld.ab r13, [sp,r12] + j_s.d [%blink] + add_s sp,sp,4 + ENDFUNC(__ld_r13_to_r14_ret) + ENDFUNC(__ld_r13_to_r15_ret) + ENDFUNC(__ld_r13_to_r16_ret) + ENDFUNC(__ld_r13_to_r17_ret) + ENDFUNC(__ld_r13_to_r18_ret) + ENDFUNC(__ld_r13_to_r19_ret) + ENDFUNC(__ld_r13_to_r20_ret) + ENDFUNC(__ld_r13_to_r21_ret) + ENDFUNC(__ld_r13_to_r22_ret) + ENDFUNC(__ld_r13_to_r23_ret) + ENDFUNC(__ld_r13_to_r24_ret) + ENDFUNC(__ld_r13_to_r25_ret)
diff --git a/u-boot-imx/arch/arc/lib/bootm.c b/u-boot-imx/arch/arc/lib/bootm.c new file mode 100644 index 0000000..d185a50 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/bootm.c
@@ -0,0 +1,106 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +static ulong get_sp(void) +{ + ulong ret; + + asm("mov %0, sp" : "=r"(ret) : ); + return ret; +} + +void arch_lmb_reserve(struct lmb *lmb) +{ + ulong sp; + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 4K to be safe */ + sp -= 4096; + lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp)); +} + +static int cleanup_before_linux(void) +{ + disable_interrupts(); + flush_dcache_all(); + invalidate_icache_all(); + + return 0; +} + +/* Subcommand: PREP */ +static void boot_prep_linux(bootm_headers_t *images) +{ + if (image_setup_linux(images)) + hang(); +} + +/* Subcommand: GO */ +static void boot_jump_linux(bootm_headers_t *images, int flag) +{ + void (*kernel_entry)(int zero, int arch, uint params); + unsigned int r0, r2; + int fake = (flag & BOOTM_STATE_OS_FAKE_GO); + + kernel_entry = (void (*)(int, int, uint))images->ep; + + debug("## Transferring control to Linux (at address %08lx)...\n", + (ulong) kernel_entry); + bootstage_mark(BOOTSTAGE_ID_RUN_OS); + + printf("\nStarting kernel ...%s\n\n", fake ? + "(fake run for tracing)" : ""); + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); + + cleanup_before_linux(); + + if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { + r0 = 2; + r2 = (unsigned int)images->ft_addr; + } else { + r0 = 1; + r2 = (unsigned int)getenv("bootargs"); + } + + if (!fake) + kernel_entry(r0, 0, r2); +} + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + /* No need for those on ARC */ + if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) + return -1; + + if (flag & BOOTM_STATE_OS_PREP) { + boot_prep_linux(images); + return 0; + } + + if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { + boot_jump_linux(images, flag); + return 0; + } + + boot_prep_linux(images); + boot_jump_linux(images, flag); + return 0; +}
diff --git a/u-boot-imx/arch/arc/lib/cache.c b/u-boot-imx/arch/arc/lib/cache.c new file mode 100644 index 0000000..e369e5a --- /dev/null +++ b/u-boot-imx/arch/arc/lib/cache.c
@@ -0,0 +1,218 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arcregs.h> +#include <asm/cache.h> + +/* Bit values in IC_CTRL */ +#define IC_CTRL_CACHE_DISABLE (1 << 0) + +/* Bit values in DC_CTRL */ +#define DC_CTRL_CACHE_DISABLE (1 << 0) +#define DC_CTRL_INV_MODE_FLUSH (1 << 6) +#define DC_CTRL_FLUSH_STATUS (1 << 8) +#define CACHE_VER_NUM_MASK 0xF +#define SLC_CTRL_SB (1 << 2) + +int icache_status(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return 0; + + return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) != + IC_CTRL_CACHE_DISABLE; +} + +void icache_enable(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & + ~IC_CTRL_CACHE_DISABLE); +} + +void icache_disable(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | + IC_CTRL_CACHE_DISABLE); +} + +void invalidate_icache_all(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + /* Any write to IC_IVIC register triggers invalidation of entire I$ */ + write_aux_reg(ARC_AUX_IC_IVIC, 1); +} + +int dcache_status(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return 0; + + return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) != + DC_CTRL_CACHE_DISABLE; +} + +void dcache_enable(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & + ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE)); +} + +void dcache_disable(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) | + DC_CTRL_CACHE_DISABLE); +} + +void flush_dcache_all(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + /* Do flush of entire cache */ + write_aux_reg(ARC_AUX_DC_FLSH, 1); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) + ; +} + +#ifndef CONFIG_SYS_DCACHE_OFF +static void dcache_flush_line(unsigned addr) +{ +#if (CONFIG_ARC_MMU_VER == 3) + write_aux_reg(ARC_AUX_DC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_DC_FLDL, addr); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) + ; + +#ifndef CONFIG_SYS_ICACHE_OFF + /* + * Invalidate I$ for addresses range just flushed from D$. + * If we try to execute data flushed above it will be valid/correct + */ +#if (CONFIG_ARC_MMU_VER == 3) + write_aux_reg(ARC_AUX_IC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_IC_IVIL, addr); +#endif /* CONFIG_SYS_ICACHE_OFF */ +} +#endif /* CONFIG_SYS_DCACHE_OFF */ + +void flush_dcache_range(unsigned long start, unsigned long end) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned int addr; + + start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) + dcache_flush_line(addr); +#endif /* CONFIG_SYS_DCACHE_OFF */ +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned int addr; + + start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { +#if (CONFIG_ARC_MMU_VER == 3) + write_aux_reg(ARC_AUX_DC_PTAG, addr); +#endif + write_aux_reg(ARC_AUX_DC_IVDL, addr); + } +#endif /* CONFIG_SYS_DCACHE_OFF */ +} + +void invalidate_dcache_all(void) +{ + /* If no cache in CPU exit immediately */ + if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + return; + + /* Write 1 to DC_IVDC register triggers invalidation of entire D$ */ + write_aux_reg(ARC_AUX_DC_IVDC, 1); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} + +#ifdef CONFIG_ISA_ARCV2 +void slc_enable(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_CONTROL, + read_aux_reg(ARC_AUX_SLC_CONTROL) & ~1); +} + +void slc_disable(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_CONTROL, + read_aux_reg(ARC_AUX_SLC_CONTROL) | 1); +} + +void slc_flush(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_FLUSH, 1); + + /* Wait flush end */ + while (read_aux_reg(ARC_AUX_SLC_CONTROL) & SLC_CTRL_SB) + ; +} + +void slc_invalidate(void) +{ + /* If SLC ver = 0, no SLC present in CPU */ + if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) + return; + + write_aux_reg(ARC_AUX_SLC_INVALIDATE, 1); +} + +#endif /* CONFIG_ISA_ARCV2 */
diff --git a/u-boot-imx/arch/arc/lib/cpu.c b/u-boot-imx/arch/arc/lib/cpu.c new file mode 100644 index 0000000..3c930bc --- /dev/null +++ b/u-boot-imx/arch/arc/lib/cpu.c
@@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arcregs.h> +#include <asm/cache.h> + +DECLARE_GLOBAL_DATA_PTR; + +int arch_cpu_init(void) +{ + timer_init(); + +/* In simulation (ISS) "CHIPID" and "ARCNUM" are all "ff" */ + if ((read_aux_reg(ARC_AUX_IDENTITY) & 0xffffff00) == 0xffffff00) + gd->arch.running_on_hw = 0; + else + gd->arch.running_on_hw = 1; + + gd->cpu_clk = CONFIG_SYS_CLK_FREQ; + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + + return 0; +} + +int arch_early_init_r(void) +{ + gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + return 0; +}
diff --git a/u-boot-imx/arch/arc/lib/init_helpers.c b/u-boot-imx/arch/arc/lib/init_helpers.c new file mode 100644 index 0000000..25690ee --- /dev/null +++ b/u-boot-imx/arch/arc/lib/init_helpers.c
@@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +int init_cache_f_r(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); + /* Make sure no stale entries persist from before we disabled cache */ + invalidate_icache_all(); +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); + /* Make sure no stale entries persist from before we disabled cache */ + invalidate_dcache_all(); +#endif + return 0; +}
diff --git a/u-boot-imx/arch/arc/lib/interrupts.c b/u-boot-imx/arch/arc/lib/interrupts.c new file mode 100644 index 0000000..d7cab3b --- /dev/null +++ b/u-boot-imx/arch/arc/lib/interrupts.c
@@ -0,0 +1,143 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arcregs.h> +#include <asm/ptrace.h> + +/* Bit values in STATUS32 */ +#define E1_MASK (1 << 1) /* Level 1 interrupts enable */ +#define E2_MASK (1 << 2) /* Level 2 interrupts enable */ + +int interrupt_init(void) +{ + return 0; +} + +/* + * returns true if interrupts had been enabled before we disabled them + */ +int disable_interrupts(void) +{ + int status = read_aux_reg(ARC_AUX_STATUS32); + int state = (status & (E1_MASK | E2_MASK)) ? 1 : 0; + + status &= ~(E1_MASK | E2_MASK); + /* STATUS32 register is updated indirectly with "FLAG" instruction */ + __asm__("flag %0" : : "r" (status)); + return state; +} + +void enable_interrupts(void) +{ + unsigned int status = read_aux_reg(ARC_AUX_STATUS32); + + status |= E1_MASK | E2_MASK; + /* STATUS32 register is updated indirectly with "FLAG" instruction */ + __asm__("flag %0" : : "r" (status)); +} + +static void print_reg_file(long *reg_rev, int start_num) +{ + unsigned int i; + + /* Print 3 registers per line */ + for (i = start_num; i < start_num + 25; i++) { + printf("r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev); + if (((i + 1) % 3) == 0) + printf("\n"); + + /* Because pt_regs has registers reversed */ + reg_rev--; + } + + /* Add new-line if none was inserted in the end of loop above */ + if (((i + 1) % 3) != 0) + printf("\n"); +} + +void show_regs(struct pt_regs *regs) +{ + printf("ECR:\t0x%08lx\n", regs->ecr); + printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n", + regs->ret, regs->blink, regs->status32); + printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25); + printf("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", regs->bta, + regs->sp, regs->fp); + printf("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start, + regs->lp_end, regs->lp_count); + + print_reg_file(&(regs->r0), 0); +} + +void bad_mode(struct pt_regs *regs) +{ + if (regs) + show_regs(regs); + + panic("Resetting CPU ...\n"); +} + +void do_memory_error(unsigned long address, struct pt_regs *regs) +{ + printf("Memory error exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_instruction_error(unsigned long address, struct pt_regs *regs) +{ + printf("Instruction error exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_machine_check_fault(unsigned long address, struct pt_regs *regs) +{ + printf("Machine check exception @ 0x%lx\n", address); + bad_mode(regs); +} + +void do_interrupt_handler(void) +{ + printf("Interrupt fired\n"); + bad_mode(0); +} + +void do_itlb_miss(struct pt_regs *regs) +{ + printf("I TLB miss exception\n"); + bad_mode(regs); +} + +void do_dtlb_miss(struct pt_regs *regs) +{ + printf("D TLB miss exception\n"); + bad_mode(regs); +} + +void do_tlb_prot_violation(unsigned long address, struct pt_regs *regs) +{ + printf("TLB protection violation or misaligned access @ 0x%lx\n", + address); + bad_mode(regs); +} + +void do_privilege_violation(struct pt_regs *regs) +{ + printf("Privilege violation exception\n"); + bad_mode(regs); +} + +void do_trap(struct pt_regs *regs) +{ + printf("Trap exception\n"); + bad_mode(regs); +} + +void do_extension(struct pt_regs *regs) +{ + printf("Extension instruction exception\n"); + bad_mode(regs); +}
diff --git a/u-boot-imx/arch/arc/lib/ints_low.S b/u-boot-imx/arch/arc/lib/ints_low.S new file mode 100644 index 0000000..161cf37 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/ints_low.S
@@ -0,0 +1,151 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +/* + * Note on the LD/ST addressing modes with address register write-back + * + * LD.a same as LD.aw + * + * LD.a reg1, [reg2, x] => Pre Incr + * Eff Addr for load = [reg2 + x] + * + * LD.ab reg1, [reg2, x] => Post Incr + * Eff Addr for load = [reg2] + */ + +.macro PUSH reg + st.a \reg, [%sp, -4] +.endm + +.macro PUSHAX aux + lr %r9, [\aux] + PUSH %r9 +.endm + +.macro SAVE_R1_TO_R24 + PUSH %r1 + PUSH %r2 + PUSH %r3 + PUSH %r4 + PUSH %r5 + PUSH %r6 + PUSH %r7 + PUSH %r8 + PUSH %r9 + PUSH %r10 + PUSH %r11 + PUSH %r12 + PUSH %r13 + PUSH %r14 + PUSH %r15 + PUSH %r16 + PUSH %r17 + PUSH %r18 + PUSH %r19 + PUSH %r20 + PUSH %r21 + PUSH %r22 + PUSH %r23 + PUSH %r24 +.endm + +.macro SAVE_ALL_SYS + /* saving %r0 to reg->r0 in advance since we read %ecr into it */ + st %r0, [%sp, -8] + lr %r0, [%ecr] /* all stack addressing is manual so far */ + st %r0, [%sp] + st %sp, [%sp, -4] + /* now move %sp to reg->r0 position so we can do "push" automatically */ + sub %sp, %sp, 8 + + SAVE_R1_TO_R24 + PUSH %r25 + PUSH %gp + PUSH %fp + PUSH %blink + PUSHAX %eret + PUSHAX %erstatus + PUSH %lp_count + PUSHAX %lp_end + PUSHAX %lp_start + PUSHAX %erbta +.endm + +.macro SAVE_EXCEPTION_SOURCE +#ifdef CONFIG_MMU + /* If MMU exists exception faulting address is loaded in EFA reg */ + lr %r0, [%efa] +#else + /* Otherwise in ERET (exception return) reg */ + lr %r0, [%eret] +#endif +.endm + +ENTRY(memory_error) + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_memory_error +ENDPROC(memory_error) + +ENTRY(instruction_error) + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_instruction_error +ENDPROC(instruction_error) + +ENTRY(interrupt_handler) + /* Todo - save and restore CPU context when interrupts will be in use */ + bl do_interrupt_handler + rtie +ENDPROC(interrupt_handler) + +ENTRY(EV_MachineCheck) + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_machine_check_fault +ENDPROC(EV_MachineCheck) + +ENTRY(EV_TLBMissI) + SAVE_ALL_SYS + mov %r0, %sp + j do_itlb_miss +ENDPROC(EV_TLBMissI) + +ENTRY(EV_TLBMissD) + SAVE_ALL_SYS + mov %r0, %sp + j do_dtlb_miss +ENDPROC(EV_TLBMissD) + +ENTRY(EV_TLBProtV) + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_tlb_prot_violation +ENDPROC(EV_TLBProtV) + +ENTRY(EV_PrivilegeV) + SAVE_ALL_SYS + mov %r0, %sp + j do_privilege_violation +ENDPROC(EV_PrivilegeV) + +ENTRY(EV_Trap) + SAVE_ALL_SYS + mov %r0, %sp + j do_trap +ENDPROC(EV_Trap) + +ENTRY(EV_Extension) + SAVE_ALL_SYS + mov %r0, %sp + j do_extension +ENDPROC(EV_Extension)
diff --git a/u-boot-imx/arch/arc/lib/libgcc2.c b/u-boot-imx/arch/arc/lib/libgcc2.c new file mode 100644 index 0000000..d5ad327 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/libgcc2.c
@@ -0,0 +1,161 @@ +/* + * Copyright (C) 1989-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "libgcc2.h" + +DWtype +__ashldi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + w.s.low = 0; + w.s.high = (UWtype)uu.s.low << -bm; + } else { + const UWtype carries = (UWtype) uu.s.low >> bm; + + w.s.low = (UWtype)uu.s.low << b; + w.s.high = ((UWtype)uu.s.high << b) | carries; + } + + return w.ll; +} + +DWtype +__ashrdi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (W_TYPE_SIZE - 1); + w.s.low = uu.s.high >> -bm; + } else { + const UWtype carries = (UWtype) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((UWtype)uu.s.low >> b) | carries; + } + + return w.ll; +} + +DWtype +__lshrdi3(DWtype u, shift_count_type b) +{ + if (b == 0) + return u; + + const DWunion uu = {.ll = u}; + const shift_count_type bm = W_TYPE_SIZE - b; + DWunion w; + + if (bm <= 0) { + w.s.high = 0; + w.s.low = (UWtype)uu.s.high >> -bm; + } else { + const UWtype carries = (UWtype)uu.s.high << bm; + + w.s.high = (UWtype)uu.s.high >> b; + w.s.low = ((UWtype)uu.s.low >> b) | carries; + } + + return w.ll; +} + +unsigned long +udivmodsi4(unsigned long num, unsigned long den, int modwanted) +{ + unsigned long bit = 1; + unsigned long res = 0; + + while (den < num && bit && !(den & (1L<<31))) { + den <<= 1; + bit <<= 1; + } + + while (bit) { + if (num >= den) { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + + if (modwanted) + return num; + + return res; +} + +long +__divsi3(long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) { + a = -a; + neg = !neg; + } + + if (b < 0) { + b = -b; + neg = !neg; + } + + res = udivmodsi4(a, b, 0); + + if (neg) + res = -res; + + return res; +} + +long +__modsi3(long a, long b) +{ + int neg = 0; + long res; + + if (a < 0) { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4(a, b, 1); + + if (neg) + res = -res; + + return res; +} + +long +__udivsi3(long a, long b) +{ + return udivmodsi4(a, b, 0); +} + +long +__umodsi3(long a, long b) +{ + return udivmodsi4(a, b, 1); +}
diff --git a/u-boot-imx/arch/arc/lib/libgcc2.h b/u-boot-imx/arch/arc/lib/libgcc2.h new file mode 100644 index 0000000..8813c3b --- /dev/null +++ b/u-boot-imx/arch/arc/lib/libgcc2.h
@@ -0,0 +1,132 @@ +/* + * Copyright (C) 1989-2013 Free Software Foundation, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#define UNITS_PER_WORD 4 /* for ARC */ +#define BITS_PER_UNIT 8 /* for ARC */ + +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) + +#define MIN_UNITS_PER_WORD UNITS_PER_WORD + +/* Work out the largest "word" size that we can deal with on this target. */ +#if MIN_UNITS_PER_WORD > 4 +# define LIBGCC2_MAX_UNITS_PER_WORD 8 +#elif (MIN_UNITS_PER_WORD > 2 \ + || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4)) +# define LIBGCC2_MAX_UNITS_PER_WORD 4 +#else +# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD +#endif + +/* Work out what word size we are using for this compilation. + The value can be set on the command line. */ +#ifndef LIBGCC2_UNITS_PER_WORD +#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD +#endif + +typedef int QItype __attribute__ ((mode (QI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int HItype __attribute__ ((mode (HI))); +typedef unsigned int UHItype __attribute__ ((mode (HI))); +#if MIN_UNITS_PER_WORD > 1 +/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1. */ +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +#if __SIZEOF_LONG_LONG__ > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2. */ +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#if MIN_UNITS_PER_WORD > 4 +/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4. */ +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#endif +#endif +#endif + +#if LIBGCC2_UNITS_PER_WORD == 8 +#define W_TYPE_SIZE (8 * BITS_PER_UNIT) +#define Wtype DItype +#define UWtype UDItype +#define HWtype DItype +#define UHWtype UDItype +#define DWtype TItype +#define UDWtype UTItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## di ## b +#define __NDW(a,b) __gnu_ ## a ## ti ## b +#else +#define __NW(a,b) __ ## a ## di ## b +#define __NDW(a,b) __ ## a ## ti ## b +#endif +#elif LIBGCC2_UNITS_PER_WORD == 4 +#define W_TYPE_SIZE (4 * BITS_PER_UNIT) +#define Wtype SItype +#define UWtype USItype +#define HWtype SItype +#define UHWtype USItype +#define DWtype DItype +#define UDWtype UDItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## si ## b +#define __NDW(a,b) __gnu_ ## a ## di ## b +#else +#define __NW(a,b) __ ## a ## si ## b +#define __NDW(a,b) __ ## a ## di ## b +#endif +#elif LIBGCC2_UNITS_PER_WORD == 2 +#define W_TYPE_SIZE (2 * BITS_PER_UNIT) +#define Wtype HItype +#define UWtype UHItype +#define HWtype HItype +#define UHWtype UHItype +#define DWtype SItype +#define UDWtype USItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## hi ## b +#define __NDW(a,b) __gnu_ ## a ## si ## b +#else +#define __NW(a,b) __ ## a ## hi ## b +#define __NDW(a,b) __ ## a ## si ## b +#endif +#else +#define W_TYPE_SIZE BITS_PER_UNIT +#define Wtype QItype +#define UWtype UQItype +#define HWtype QItype +#define UHWtype UQItype +#define DWtype HItype +#define UDWtype UHItype +#ifdef LIBGCC2_GNU_PREFIX +#define __NW(a,b) __gnu_ ## a ## qi ## b +#define __NDW(a,b) __gnu_ ## a ## hi ## b +#else +#define __NW(a,b) __ ## a ## qi ## b +#define __NDW(a,b) __ ## a ## hi ## b +#endif +#endif + +typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__))); + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + struct DWstruct {Wtype high, low;}; +#else + struct DWstruct {Wtype low, high;}; +#endif + +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ + +typedef union { + struct DWstruct s; + DWtype ll; +} DWunion; + +#endif /* __ASM_LIBGCC_H */
diff --git a/u-boot-imx/arch/arc/lib/memcmp.S b/u-boot-imx/arch/arc/lib/memcmp.S new file mode 100644 index 0000000..87bccab --- /dev/null +++ b/u-boot-imx/arch/arc/lib/memcmp.S
@@ -0,0 +1,123 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifdef __LITTLE_ENDIAN__ +#define WORD2 r2 +#define SHIFT r3 +#else /* __BIG_ENDIAN__ */ +#define WORD2 r3 +#define SHIFT r2 +#endif /* _ENDIAN__ */ + +.global memcmp +.align 4 +memcmp: + or %r12, %r0, %r1 + asl_s %r12, %r12, 30 + sub %r3, %r2, 1 + brls %r2, %r12, .Lbytewise + ld %r4, [%r0, 0] + ld %r5, [%r1, 0] + lsr.f %lp_count, %r3, 3 + lpne .Loop_end + ld_s WORD2, [%r0, 4] + ld_s %r12, [%r1, 4] + brne %r4, %r5, .Leven + ld.a %r4, [%r0, 8] + ld.a %r5, [%r1, 8] + brne WORD2, %r12, .Lodd + nop +.Loop_end: + asl_s SHIFT, SHIFT, 3 + bhs_s .Last_cmp + brne %r4, %r5, .Leven + ld %r4, [%r0, 4] + ld %r5, [%r1, 4] +#ifdef __LITTLE_ENDIAN__ + nop_s + /* one more load latency cycle */ +.Last_cmp: + xor %r0, %r4, %r5 + bset %r0, %r0, SHIFT + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + b.d .Leven_cmp + and %r1, %r1, 24 +.Leven: + xor %r0, %r4, %r5 + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + /* slow track insn */ + and %r1, %r1, 24 +.Leven_cmp: + asl %r2, %r4, %r1 + asl %r12, %r5, %r1 + lsr_s %r2, %r2, 1 + lsr_s %r12, %r12, 1 + j_s.d [%blink] + sub %r0, %r2, %r12 + .balign 4 +.Lodd: + xor %r0, WORD2, %r12 + sub_s %r1, %r0, 1 + bic_s %r1, %r1, %r0 + norm %r1, %r1 + /* slow track insn */ + and %r1, %r1, 24 + asl_s %r2, %r2, %r1 + asl_s %r12, %r12, %r1 + lsr_s %r2, %r2, 1 + lsr_s %r12, %r12, 1 + j_s.d [%blink] + sub %r0, %r2, %r12 +#else /* __BIG_ENDIAN__ */ +.Last_cmp: + neg_s SHIFT, SHIFT + lsr %r4, %r4, SHIFT + lsr %r5, %r5, SHIFT + /* slow track insn */ +.Leven: + sub.f %r0, %r4, %r5 + mov.ne %r0, 1 + j_s.d [%blink] + bset.cs %r0, %r0, 31 +.Lodd: + cmp_s WORD2, %r12 + + mov_s %r0, 1 + j_s.d [%blink] + bset.cs %r0, %r0, 31 +#endif /* _ENDIAN__ */ + .balign 4 +.Lbytewise: + breq %r2, 0, .Lnil + ldb %r4, [%r0, 0] + ldb %r5, [%r1, 0] + lsr.f %lp_count, %r3 + lpne .Lbyte_end + ldb_s %r3, [%r0, 1] + ldb %r12, [%r1, 1] + brne %r4, %r5, .Lbyte_even + ldb.a %r4, [%r0, 2] + ldb.a %r5, [%r1, 2] + brne %r3, %r12, .Lbyte_odd + nop +.Lbyte_end: + bcc .Lbyte_even + brne %r4, %r5, .Lbyte_even + ldb_s %r3, [%r0, 1] + ldb_s %r12, [%r1, 1] +.Lbyte_odd: + j_s.d [%blink] + sub %r0, %r3, %r12 +.Lbyte_even: + j_s.d [%blink] + sub %r0, %r4, %r5 +.Lnil: + j_s.d [%blink] + mov %r0, 0
diff --git a/u-boot-imx/arch/arc/lib/memcpy-700.S b/u-boot-imx/arch/arc/lib/memcpy-700.S new file mode 100644 index 0000000..51dd73a --- /dev/null +++ b/u-boot-imx/arch/arc/lib/memcpy-700.S
@@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.global memcpy +.align 4 +memcpy: + or %r3, %r0, %r1 + asl_s %r3, %r3, 30 + mov_s %r5, %r0 + brls.d %r2, %r3, .Lcopy_bytewise + sub.f %r3, %r2, 1 + ld_s %r12, [%r1, 0] + asr.f %lp_count, %r3, 3 + bbit0.d %r3, 2, .Lnox4 + bmsk_s %r2, %r2, 1 + st.ab %r12, [%r5, 4] + ld.a %r12, [%r1, 4] +.Lnox4: + lppnz .Lendloop + ld_s %r3, [%r1, 4] + st.ab %r12, [%r5, 4] + ld.a %r12, [%r1, 8] + st.ab %r3, [%r5, 4] +.Lendloop: + breq %r2, 0, .Last_store + ld %r3, [%r5, 0] +#ifdef __LITTLE_ENDIAN__ + add3 %r2, -1, %r2 + /* uses long immediate */ + xor_s %r12, %r12, %r3 + bmsk %r12, %r12, %r2 + xor_s %r12, %r12, %r3 +#else /* __BIG_ENDIAN__ */ + sub3 %r2, 31, %r2 + /* uses long immediate */ + xor_s %r3, %r3, %r12 + bmsk %r3, %r3, %r2 + xor_s %r12, %r12, %r3 +#endif /* _ENDIAN__ */ +.Last_store: + j_s.d [%blink] + st %r12, [%r5, 0] + + .balign 4 +.Lcopy_bytewise: + jcs [%blink] + ldb_s %r12, [%r1, 0] + lsr.f %lp_count, %r3 + bhs_s .Lnox1 + stb.ab %r12, [%r5, 1] + ldb.a %r12, [%r1, 1] +.Lnox1: + lppnz .Lendbloop + ldb_s %r3, [%r1, 1] + stb.ab %r12, [%r5, 1] + ldb.a %r12, [%r1, 2] + stb.ab %r3, [%r5, 1] +.Lendbloop: + j_s.d [%blink] + stb %r12, [%r5, 0]
diff --git a/u-boot-imx/arch/arc/lib/memset.S b/u-boot-imx/arch/arc/lib/memset.S new file mode 100644 index 0000000..017e8af --- /dev/null +++ b/u-boot-imx/arch/arc/lib/memset.S
@@ -0,0 +1,62 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define SMALL 7 /* Must be at least 6 to deal with alignment/loop issues. */ + +.global memset +.align 4 +memset: + mov_s %r4, %r0 + or %r12, %r0, %r2 + bmsk.f %r12, %r12, 1 + extb_s %r1, %r1 + asl %r3, %r1, 8 + beq.d .Laligned + or_s %r1, %r1, %r3 + brls %r2, SMALL, .Ltiny + add %r3, %r2, %r0 + stb %r1, [%r3, -1] + bclr_s %r3, %r3, 0 + stw %r1, [%r3, -2] + bmsk.f %r12, %r0, 1 + add_s %r2, %r2, %r12 + sub.ne %r2, %r2, 4 + stb.ab %r1, [%r4, 1] + and %r4, %r4, -2 + stw.ab %r1, [%r4, 2] + and %r4, %r4, -4 + + .balign 4 +.Laligned: + asl %r3, %r1, 16 + lsr.f %lp_count, %r2, 2 + or_s %r1, %r1, %r3 + lpne .Loop_end + st.ab %r1, [%r4, 4] +.Loop_end: + j_s [%blink] + + .balign 4 +.Ltiny: + mov.f %lp_count, %r2 + lpne .Ltiny_end + stb.ab %r1, [%r4, 1] +.Ltiny_end: + j_s [%blink] + +/* + * memzero: @r0 = mem, @r1 = size_t + * memset: @r0 = mem, @r1 = char, @r2 = size_t + */ + +.global memzero +.align 4 +memzero: + /* adjust bzero args to memset args */ + mov %r2, %r1 + mov %r1, 0 + /* tail call so need to tinker with blink */ + b memset
diff --git a/u-boot-imx/arch/arc/lib/relocate.c b/u-boot-imx/arch/arc/lib/relocate.c new file mode 100644 index 0000000..5c2c2d1 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/relocate.c
@@ -0,0 +1,88 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <elf.h> +#include <asm/sections.h> + +DECLARE_GLOBAL_DATA_PTR; + +int copy_uboot_to_ram(void) +{ + size_t len = (size_t)&__image_copy_end - (size_t)&__image_copy_start; + + memcpy((void *)gd->relocaddr, (void *)&__image_copy_start, len); + + return 0; +} + +int clear_bss(void) +{ + ulong dst_addr = (ulong)&__bss_start + gd->reloc_off; + size_t len = (size_t)&__bss_end - (size_t)&__bss_start; + + memset((void *)dst_addr, 0x00, len); + + return 0; +} + +/* + * Base functionality is taken from x86 version with added ARC-specifics + */ +int do_elf_reloc_fixups(void) +{ + Elf32_Rela *re_src = (Elf32_Rela *)(&__rel_dyn_start); + Elf32_Rela *re_end = (Elf32_Rela *)(&__rel_dyn_end); + + Elf32_Addr *offset_ptr_rom, *last_offset = NULL; + Elf32_Addr *offset_ptr_ram; + + do { + /* Get the location from the relocation entry */ + offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; + + /* Check that the location of the relocation is in .text */ + if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start && + offset_ptr_rom > last_offset) { + unsigned int val; + /* Switch to the in-RAM version */ + offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + + gd->reloc_off); + + /* + * Use "memcpy" because target location might be + * 16-bit aligned on ARC so we may need to read + * byte-by-byte. On attempt to read entire word by + * CPU throws an exception + */ + memcpy(&val, offset_ptr_ram, sizeof(int)); + +#ifdef __LITTLE_ENDIAN__ + /* If location in ".text" section swap value */ + if ((unsigned int)offset_ptr_rom < + (unsigned int)&__ivt_end) + val = (val << 16) | (val >> 16); +#endif + + /* Check that the target points into executable */ + if (val >= (unsigned int)&__image_copy_start && val <= + (unsigned int)&__image_copy_end) { + val += gd->reloc_off; +#ifdef __LITTLE_ENDIAN__ + /* If location in ".text" section swap value */ + if ((unsigned int)offset_ptr_rom < + (unsigned int)&__ivt_end) + val = (val << 16) | (val >> 16); +#endif + memcpy(offset_ptr_ram, &val, sizeof(int)); + } + } + last_offset = offset_ptr_rom; + + } while (++re_src < re_end); + + return 0; +}
diff --git a/u-boot-imx/arch/arc/lib/reset.c b/u-boot-imx/arch/arc/lib/reset.c new file mode 100644 index 0000000..98ebf1d --- /dev/null +++ b/u-boot-imx/arch/arc/lib/reset.c
@@ -0,0 +1,19 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <command.h> +#include <common.h> + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + printf("Put your restart handler here\n"); + +#ifdef DEBUG + /* Stop debug session here */ + __asm__("brk"); +#endif + return 0; +}
diff --git a/u-boot-imx/arch/arc/lib/sections.c b/u-boot-imx/arch/arc/lib/sections.c new file mode 100644 index 0000000..a72c694 --- /dev/null +++ b/u-boot-imx/arch/arc/lib/sections.c
@@ -0,0 +1,23 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * For some reason linker sets linker-generated symbols to zero in PIE mode. + * A work-around is substitution of linker-generated symbols with + * compiler-generated symbols which are properly handled by linker in PAE mode. + */ + +char __bss_start[0] __attribute__((section(".__bss_start"))); +char __bss_end[0] __attribute__((section(".__bss_end"))); +char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); +char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); +char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); +char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); +char __text_start[0] __attribute__((section(".__text_start"))); +char __text_end[0] __attribute__((section(".__text_end"))); +char __init_end[0] __attribute__((section(".__init_end"))); +char __ivt_start[0] __attribute__((section(".__ivt_start"))); +char __ivt_end[0] __attribute__((section(".__ivt_end")));
diff --git a/u-boot-imx/arch/arc/lib/start.S b/u-boot-imx/arch/arc/lib/start.S new file mode 100644 index 0000000..e1ef19c --- /dev/null +++ b/u-boot-imx/arch/arc/lib/start.S
@@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> +#include <asm/arcregs.h> + +ENTRY(_start) + /* Setup interrupt vector base that matches "__text_start" */ + sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] + + /* Setup stack- and frame-pointers */ + mov %sp, CONFIG_SYS_INIT_SP_ADDR + mov %fp, %sp + + /* Unconditionally disable caches */ +#ifdef CONFIG_ISA_ARCV2 + bl slc_flush + bl slc_disable +#endif + bl flush_dcache_all + bl dcache_disable + bl icache_disable + + /* Allocate and zero GD, update SP */ + mov %r0, %sp + bl board_init_f_mem + + /* Update stack- and frame-pointers */ + mov %sp, %r0 + mov %fp, %sp + + /* Zero the one and only argument of "board_init_f" */ + mov_s %r0, 0 + j board_init_f +ENDPROC(_start) + +/* + * void board_init_f_r_trampoline(stack-pointer address) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r0 = new stack-pointer + */ +ENTRY(board_init_f_r_trampoline) + /* Set up the stack- and frame-pointers */ + mov %sp, %r0 + mov %fp, %sp + + /* Update position of intterupt vector table */ + lr %r0, [ARC_AUX_INTR_VEC_BASE] + ld %r1, [%r25, GD_RELOC_OFF] + add %r0, %r0, %r1 + sr %r0, [ARC_AUX_INTR_VEC_BASE] + + /* Re-enter U-Boot by calling board_init_f_r */ + j board_init_f_r +ENDPROC(board_init_f_r_trampoline)
diff --git a/u-boot-imx/arch/arc/lib/strchr-700.S b/u-boot-imx/arch/arc/lib/strchr-700.S new file mode 100644 index 0000000..55fcc9f --- /dev/null +++ b/u-boot-imx/arch/arc/lib/strchr-700.S
@@ -0,0 +1,141 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * ARC700 has a relatively long pipeline and branch prediction, so we want + * to avoid branches that are hard to predict. On the other hand, the + * presence of the norm instruction makes it easier to operate on whole + * words branch-free. + */ + +.global strchr +.align 4 +strchr: + extb_s %r1, %r1 + asl %r5, %r1, 8 + bmsk %r2, %r0, 1 + or %r5, %r5, %r1 + mov_s %r3, 0x01010101 + breq.d %r2, %r0, .Laligned + asl %r4, %r5, 16 + sub_s %r0, %r0, %r2 + asl %r7, %r2, 3 + ld_s %r2, [%r0] +#ifdef __LITTLE_ENDIAN__ + asl %r7, %r3, %r7 +#else /* __BIG_ENDIAN__ */ + lsr %r7, %r3, %r7 +#endif /* _ENDIAN__ */ + or %r5, %r5, %r4 + ror %r4, %r3 + sub %r12, %r2, %r7 + bic_s %r12, %r12, %r2 + and %r12, %r12, %r4 + brne.d %r12, 0, .Lfound0_ua + xor %r6, %r2, %r5 + ld.a %r2, [%r0, 4] + sub %r12, %r6, %r7 + bic %r12, %r12, %r6 +#ifdef __LITTLE_ENDIAN__ + and %r7, %r12, %r4 + /* For speed, we want this branch to be unaligned. */ + breq %r7, 0, .Loop + /* Likewise this one */ + b .Lfound_char +#else /* __BIG_ENDIAN__ */ + and %r12, %r12, %r4 + /* For speed, we want this branch to be unaligned. */ + breq %r12, 0, .Loop + lsr_s %r12, %r12, 7 + bic %r2, %r7, %r6 + b.d .Lfound_char_b + and_s %r2, %r2, %r12 +#endif /* _ENDIAN__ */ + /* We require this code address to be unaligned for speed... */ +.Laligned: + ld_s %r2, [%r0] + or %r5, %r5, %r4 + ror %r4, %r3 + /* ... so that this code address is aligned, for itself and ... */ +.Loop: + sub %r12, %r2, %r3 + bic_s %r12, %r12, %r2 + and %r12, %r12, %r4 + brne.d %r12, 0, .Lfound0 + xor %r6, %r2, %r5 + ld.a %r2, [%r0, 4] + sub %r12, %r6, %r3 + bic %r12, %r12, %r6 + and %r7, %r12, %r4 + breq %r7, 0, .Loop + /* + *... so that this branch is unaligned. + * Found searched-for character. + * r0 has already advanced to next word. + */ +#ifdef __LITTLE_ENDIAN__ + /* + * We only need the information about the first matching byte + * (i.e. the least significant matching byte) to be exact, + * hence there is no problem with carry effects. + */ +.Lfound_char: + sub %r3, %r7, 1 + bic %r3, %r3, %r7 + norm %r2, %r3 + sub_s %r0, %r0, 1 + asr_s %r2, %r2, 3 + j.d [%blink] + sub_s %r0, %r0, %r2 + + .balign 4 +.Lfound0_ua: + mov %r3, %r7 +.Lfound0: + sub %r3, %r6, %r3 + bic %r3, %r3, %r6 + and %r2, %r3, %r4 + or_s %r12, %r12, %r2 + sub_s %r3, %r12, 1 + bic_s %r3, %r3, %r12 + norm %r3, %r3 + add_s %r0, %r0, 3 + asr_s %r12, %r3, 3 + asl.f 0, %r2, %r3 + sub_s %r0, %r0, %r12 + j_s.d [%blink] + mov.pl %r0, 0 +#else /* __BIG_ENDIAN__ */ +.Lfound_char: + lsr %r7, %r7, 7 + + bic %r2, %r7, %r6 +.Lfound_char_b: + norm %r2, %r2 + sub_s %r0, %r0, 4 + asr_s %r2, %r2, 3 + j.d [%blink] + add_s %r0, %r0, %r2 + +.Lfound0_ua: + mov_s %r3, %r7 +.Lfound0: + asl_s %r2, %r2, 7 + or %r7, %r6, %r4 + bic_s %r12, %r12, %r2 + sub %r2, %r7, %r3 + or %r2, %r2, %r6 + bic %r12, %r2, %r12 + bic.f %r3, %r4, %r12 + norm %r3, %r3 + + add.pl %r3, %r3, 1 + asr_s %r12, %r3, 3 + asl.f 0, %r2, %r3 + add_s %r0, %r0, %r12 + j_s.d [%blink] + mov.mi %r0, 0 +#endif /* _ENDIAN__ */
diff --git a/u-boot-imx/arch/arc/lib/strcmp.S b/u-boot-imx/arch/arc/lib/strcmp.S new file mode 100644 index 0000000..8cb7d2f --- /dev/null +++ b/u-boot-imx/arch/arc/lib/strcmp.S
@@ -0,0 +1,97 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This is optimized primarily for the ARC700. + * It would be possible to speed up the loops by one cycle / word + * respective one cycle / byte by forcing double source 1 alignment, unrolling + * by a factor of two, and speculatively loading the second word / byte of + * source 1; however, that would increase the overhead for loop setup / finish, + * and strcmp might often terminate early. + */ + +.global strcmp +.align 4 +strcmp: + or %r2, %r0, %r1 + bmsk_s %r2, %r2, 1 + brne %r2, 0, .Lcharloop + mov_s %r12, 0x01010101 + ror %r5, %r12 +.Lwordloop: + ld.ab %r2, [%r0, 4] + ld.ab %r3, [%r1, 4] + nop_s + sub %r4, %r2, %r12 + bic %r4, %r4, %r2 + and %r4, %r4, %r5 + brne %r4, 0, .Lfound0 + breq %r2 ,%r3, .Lwordloop +#ifdef __LITTLE_ENDIAN__ + xor %r0, %r2, %r3 /* mask for difference */ + sub_s %r1, %r0, 1 + bic_s %r0, %r0, %r1 /* mask for least significant difference bit */ + sub %r1, %r5, %r0 + xor %r0, %r5, %r1 /* mask for least significant difference byte */ + and_s %r2, %r2, %r0 + and_s %r3, %r3, %r0 +#endif /* _ENDIAN__ */ + cmp_s %r2, %r3 + mov_s %r0, 1 + j_s.d [%blink] + bset.lo %r0, %r0, 31 + + .balign 4 +#ifdef __LITTLE_ENDIAN__ +.Lfound0: + xor %r0, %r2, %r3 /* mask for difference */ + or %r0, %r0, %r4 /* or in zero indicator */ + sub_s %r1, %r0, 1 + bic_s %r0, %r0, %r1 /* mask for least significant difference bit */ + sub %r1, %r5, %r0 + xor %r0, %r5, %r1 /* mask for least significant difference byte */ + and_s %r2, %r2, %r0 + and_s %r3, %r3, %r0 + sub.f %r0, %r2, %r3 + mov.hi %r0, 1 + j_s.d [%blink] + bset.lo %r0, %r0, 31 +#else /* __BIG_ENDIAN__ */ + /* + * The zero-detection above can mis-detect 0x01 bytes as zeroes + * because of carry-propagateion from a lower significant zero byte. + * We can compensate for this by checking that bit0 is zero. + * This compensation is not necessary in the step where we + * get a low estimate for r2, because in any affected bytes + * we already have 0x00 or 0x01, which will remain unchanged + * when bit 7 is cleared. + */ + .balign 4 +.Lfound0: + lsr %r0, %r4, 8 + lsr_s %r1, %r2 + bic_s %r2, %r2, %r0 /* get low estimate for r2 and get ... */ + bic_s %r0, %r0, %r1 /* <this is the adjusted mask for zeros> */ + or_s %r3, %r3, %r0 /* ... high estimate r3 so that r2 > r3 will */ + cmp_s %r3, %r2 /* ... be independent of trailing garbage */ + or_s %r2, %r2, %r0 /* likewise for r3 > r2 */ + bic_s %r3, %r3, %r0 + rlc %r0, 0 /* r0 := r2 > r3 ? 1 : 0 */ + cmp_s %r2, %r3 + j_s.d [%blink] + bset.lo %r0, %r0, 31 +#endif /* _ENDIAN__ */ + + .balign 4 +.Lcharloop: + ldb.ab %r2,[%r0,1] + ldb.ab %r3,[%r1,1] + nop_s + breq %r2, 0, .Lcmpend + breq %r2, %r3, .Lcharloop +.Lcmpend: + j_s.d [%blink] + sub %r0, %r2, %r3
diff --git a/u-boot-imx/arch/arc/lib/strcpy-700.S b/u-boot-imx/arch/arc/lib/strcpy-700.S new file mode 100644 index 0000000..41bb53e --- /dev/null +++ b/u-boot-imx/arch/arc/lib/strcpy-700.S
@@ -0,0 +1,67 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * If dst and src are 4 byte aligned, copy 8 bytes at a time. + * If the src is 4, but not 8 byte aligned, we first read 4 bytes to get + * it 8 byte aligned. Thus, we can do a little read-ahead, without + * dereferencing a cache line that we should not touch. + * Note that short and long instructions have been scheduled to avoid + * branch stalls. + * The beq_s to r3z could be made unaligned & long to avoid a stall + * there, but it is not likely to be taken often, and it would also be likely + * to cost an unaligned mispredict at the next call. + */ + +.global strcpy +.align 4 +strcpy: + or %r2, %r0, %r1 + bmsk_s %r2, %r2, 1 + brne.d %r2, 0, charloop + mov_s %r10, %r0 + ld_s %r3, [%r1, 0] + mov %r8, 0x01010101 + bbit0.d %r1, 2, loop_start + ror %r12, %r8 + sub %r2, %r3, %r8 + bic_s %r2, %r2, %r3 + tst_s %r2,%r12 + bne r3z + mov_s %r4,%r3 + .balign 4 +loop: + ld.a %r3, [%r1, 4] + st.ab %r4, [%r10, 4] +loop_start: + ld.a %r4, [%r1, 4] + sub %r2, %r3, %r8 + bic_s %r2, %r2, %r3 + tst_s %r2, %r12 + bne_s r3z + st.ab %r3, [%r10, 4] + sub %r2, %r4, %r8 + bic %r2, %r2, %r4 + tst %r2, %r12 + beq loop + mov_s %r3, %r4 +#ifdef __LITTLE_ENDIAN__ +r3z: bmsk.f %r1, %r3, 7 + lsr_s %r3, %r3, 8 +#else /* __BIG_ENDIAN__ */ +r3z: lsr.f %r1, %r3, 24 + asl_s %r3, %r3, 8 +#endif /* _ENDIAN__ */ + bne.d r3z + stb.ab %r1, [%r10, 1] + j_s [%blink] + + .balign 4 +charloop: + ldb.ab %r3, [%r1, 1] + brne.d %r3, 0, charloop + stb.ab %r3, [%r10, 1] + j [%blink]
diff --git a/u-boot-imx/arch/arc/lib/strlen.S b/u-boot-imx/arch/arc/lib/strlen.S new file mode 100644 index 0000000..666e22c --- /dev/null +++ b/u-boot-imx/arch/arc/lib/strlen.S
@@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.global strlen +.align 4 +strlen: + or %r3, %r0, 7 + ld %r2, [%r3, -7] + ld.a %r6, [%r3, -3] + mov %r4, 0x01010101 + /* uses long immediate */ +#ifdef __LITTLE_ENDIAN__ + asl_s %r1, %r0, 3 + btst_s %r0, 2 + asl %r7, %r4, %r1 + ror %r5, %r4 + sub %r1, %r2, %r7 + bic_s %r1, %r1, %r2 + mov.eq %r7, %r4 + sub %r12, %r6, %r7 + bic %r12, %r12, %r6 + or.eq %r12, %r12, %r1 + and %r12, %r12, %r5 + brne %r12, 0, .Learly_end +#else /* __BIG_ENDIAN__ */ + ror %r5, %r4 + btst_s %r0, 2 + mov_s %r1, 31 + sub3 %r7, %r1, %r0 + sub %r1, %r2, %r4 + bic_s %r1, %r1, %r2 + bmsk %r1, %r1, %r7 + sub %r12, %r6, %r4 + bic %r12, %r12, %r6 + bmsk.ne %r12, %r12, %r7 + or.eq %r12, %r12, %r1 + and %r12, %r12, %r5 + brne %r12, 0, .Learly_end +#endif /* _ENDIAN__ */ + +.Loop: + ld_s %r2, [%r3, 4] + ld.a %r6, [%r3, 8] + /* stall for load result */ + sub %r1, %r2, %r4 + bic_s %r1, %r1, %r2 + sub %r12, %r6, %r4 + bic %r12, %r12, %r6 + or %r12, %r12, %r1 + and %r12, %r12, %r5 + breq %r12, 0, .Loop +.Lend: + and.f %r1, %r1, %r5 + sub.ne %r3, %r3, 4 + mov.eq %r1, %r12 +#ifdef __LITTLE_ENDIAN__ + sub_s %r2, %r1, 1 + bic_s %r2, %r2, %r1 + norm %r1, %r2 + sub_s %r0, %r0, 3 + lsr_s %r1, %r1, 3 + sub %r0, %r3, %r0 + j_s.d [%blink] + sub %r0, %r0, %r1 +#else /* __BIG_ENDIAN__ */ + lsr_s %r1, %r1, 7 + mov.eq %r2, %r6 + bic_s %r1, %r1, %r2 + norm %r1, %r1 + sub %r0, %r3, %r0 + lsr_s %r1, %r1, 3 + j_s.d [%blink] + add %r0, %r0, %r1 +#endif /* _ENDIAN */ +.Learly_end: + b.d .Lend + sub_s.ne %r1, %r1, %r1
diff --git a/u-boot-imx/arch/arc/lib/timer.c b/u-boot-imx/arch/arc/lib/timer.c new file mode 100644 index 0000000..a0acbbc --- /dev/null +++ b/u-boot-imx/arch/arc/lib/timer.c
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arcregs.h> + +#define NH_MODE (1 << 1) /* Disable timer if CPU is halted */ + +int timer_init(void) +{ + write_aux_reg(ARC_AUX_TIMER0_CTRL, NH_MODE); + /* Set max value for counter/timer */ + write_aux_reg(ARC_AUX_TIMER0_LIMIT, 0xffffffff); + /* Set initial count value and restart counter/timer */ + write_aux_reg(ARC_AUX_TIMER0_CNT, 0); + return 0; +} + +unsigned long timer_read_counter(void) +{ + return read_aux_reg(ARC_AUX_TIMER0_CNT); +}
diff --git a/u-boot-imx/arch/arm/Kconfig b/u-boot-imx/arch/arm/Kconfig new file mode 100644 index 0000000..8df7ff2 --- /dev/null +++ b/u-boot-imx/arch/arm/Kconfig
@@ -0,0 +1,958 @@ +menu "ARM architecture" + depends on ARM + +config SYS_ARCH + default "arm" + +config ARM64 + bool + +config HAS_VBAR + bool + +config CPU_ARM720T + bool + +config CPU_ARM920T + bool + +config CPU_ARM926EJS + bool + +config CPU_ARM946ES + bool + +config CPU_ARM1136 + bool + +config CPU_ARM1176 + bool + select HAS_VBAR + +config CPU_V7 + bool + select HAS_VBAR + +config CPU_PXA + bool + +config CPU_SA1100 + bool + +config SYS_CPU + default "arm720t" if CPU_ARM720T + default "arm920t" if CPU_ARM920T + default "arm926ejs" if CPU_ARM926EJS + default "arm946es" if CPU_ARM946ES + default "arm1136" if CPU_ARM1136 + default "arm1176" if CPU_ARM1176 + default "armv7" if CPU_V7 + default "pxa" if CPU_PXA + default "sa1100" if CPU_SA1100 + default "armv8" if ARM64 + +config SEMIHOSTING + bool "support boot from semihosting" + help + In emulated environments, semihosting is a way for + the hosted environment to call out to the emulator to + retrieve files from the host machine. + +choice + prompt "Target select" + +config TARGET_INTEGRATORAP_CM720T + bool "Support integratorap_cm720t" + select CPU_ARM720T + +config TARGET_INTEGRATORAP_CM920T + bool "Support integratorap_cm920t" + select CPU_ARM920T + +config TARGET_INTEGRATORCP_CM920T + bool "Support integratorcp_cm920t" + select CPU_ARM920T + +config ARCH_AT91 + bool "Atmel AT91" + +config TARGET_EDB93XX + bool "Support edb93xx" + select CPU_ARM920T + +config TARGET_SCB9328 + bool "Support scb9328" + select CPU_ARM920T + +config TARGET_VCMA9 + bool "Support VCMA9" + select CPU_ARM920T + +config TARGET_SMDK2410 + bool "Support smdk2410" + select CPU_ARM920T + +config TARGET_INTEGRATORAP_CM926EJS + bool "Support integratorap_cm926ejs" + select CPU_ARM926EJS + +config TARGET_INTEGRATORCP_CM926EJS + bool "Support integratorcp_cm926ejs" + select CPU_ARM926EJS + +config TARGET_ASPENITE + bool "Support aspenite" + select CPU_ARM926EJS + +config TARGET_GPLUGD + bool "Support gplugd" + select CPU_ARM926EJS + +config ARCH_DAVINCI + bool "TI DaVinci" + select CPU_ARM926EJS + help + Support for TI's DaVinci platform. + +config KIRKWOOD + bool "Marvell Kirkwood" + select CPU_ARM926EJS + +config TARGET_DB_MV784MP_GP + bool "Support db-mv784mp-gp" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_MAXBCM + bool "Support maxbcm" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_DEVKIT3250 + bool "Support devkit3250" + select CPU_ARM926EJS + +config TARGET_WORK_92105 + bool "Support work_92105" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_MX25PDK + bool "Support mx25pdk" + select CPU_ARM926EJS + +config TARGET_TX25 + bool "Support tx25" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_ZMX25 + bool "Support zmx25" + select CPU_ARM926EJS + +config TARGET_APF27 + bool "Support apf27" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_IMX27LITE + bool "Support imx27lite" + select CPU_ARM926EJS + +config TARGET_MAGNESIUM + bool "Support magnesium" + select CPU_ARM926EJS + +config TARGET_APX4DEVKIT + bool "Support apx4devkit" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_XFI3 + bool "Support xfi3" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_M28EVK + bool "Support m28evk" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_MX23EVK + bool "Support mx23evk" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_MX28EVK + bool "Support mx28evk" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_MX23_OLINUXINO + bool "Support mx23_olinuxino" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_BG0900 + bool "Support bg0900" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_SANSA_FUZE_PLUS + bool "Support sansa_fuze_plus" + select CPU_ARM926EJS + select SUPPORT_SPL + +config TARGET_SC_SPS_1 + bool "Support sc_sps_1" + select CPU_ARM926EJS + select SUPPORT_SPL + +config ARCH_NOMADIK + bool "ST-Ericsson Nomadik" + select CPU_ARM926EJS + +config ORION5X + bool "Marvell Orion" + select CPU_ARM926EJS + +config TARGET_SPEAR300 + bool "Support spear300" + select CPU_ARM926EJS + +config TARGET_SPEAR310 + bool "Support spear310" + select CPU_ARM926EJS + +config TARGET_SPEAR320 + bool "Support spear320" + select CPU_ARM926EJS + +config TARGET_SPEAR600 + bool "Support spear600" + select CPU_ARM926EJS + +config TARGET_STV0991 + bool "Support stv0991" + select CPU_V7 + +config TARGET_X600 + bool "Support x600" + select CPU_ARM926EJS + select SUPPORT_SPL + +config ARCH_VERSATILE + bool "ARM Ltd. Versatile family" + select CPU_ARM926EJS + +config TARGET_INTEGRATORCP_CM1136 + bool "Support integratorcp_cm1136" + select CPU_ARM1136 + +config TARGET_IMX31_PHYCORE + bool "Support imx31_phycore" + select CPU_ARM1136 + +config TARGET_QONG + bool "Support qong" + select CPU_ARM1136 + +config TARGET_MX31ADS + bool "Support mx31ads" + select CPU_ARM1136 + +config TARGET_MX31PDK + bool "Support mx31pdk" + select CPU_ARM1136 + select SUPPORT_SPL + +config TARGET_TT01 + bool "Support tt01" + select CPU_ARM1136 + +config TARGET_IMX31_LITEKIT + bool "Support imx31_litekit" + select CPU_ARM1136 + +config TARGET_WOODBURN + bool "Support woodburn" + select CPU_ARM1136 + +config TARGET_WOODBURN_SD + bool "Support woodburn_sd" + select CPU_ARM1136 + select SUPPORT_SPL + +config TARGET_FLEA3 + bool "Support flea3" + select CPU_ARM1136 + +config TARGET_MX35PDK + bool "Support mx35pdk" + select CPU_ARM1136 + +config ARCH_BCM283X + bool "Broadcom BCM283X family" + +config TARGET_INTEGRATORAP_CM946ES + bool "Support integratorap_cm946es" + select CPU_ARM946ES + +config TARGET_INTEGRATORCP_CM946ES + bool "Support integratorcp_cm946es" + select CPU_ARM946ES + +config TARGET_VEXPRESS_CA15_TC2 + bool "Support vexpress_ca15_tc2" + select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + +config TARGET_VEXPRESS_CA5X2 + bool "Support vexpress_ca5x2" + select CPU_V7 + +config TARGET_VEXPRESS_CA9X4 + bool "Support vexpress_ca9x4" + select CPU_V7 + +config TARGET_KWB + bool "Support kwb" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_TSERIES + bool "Support tseries" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_CM_T335 + bool "Support cm_t335" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PEPPER + bool "Support pepper" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_AM335X_IGEP0033 + bool "Support am335x_igep0033" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PCM051 + bool "Support pcm051" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_DRACO + bool "Support draco" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_DXR2 + bool "Support dxr2" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PXM2 + bool "Support pxm2" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_RUT + bool "Support rut" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PENGWYN + bool "Support pengwyn" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_AM335X_EVM + bool "Support am335x_evm" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_AM43XX_EVM + bool "Support am43xx_evm" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_BAV335X + bool "Support bav335x" + select CPU_V7 + select SUPPORT_SPL + help + The BAV335x OEM Network Processor integrates all the functions of an + embedded network computer in a small, easy to use SODIMM module which + incorporates the popular Texas Instruments Sitara 32bit ARM Coretex-A8 + processor, with fast DDR3 512MB SDRAM, 4GB of embedded MMC and a Gigabit + ethernet with simple connection to external connectors. + + For more information, visit: http://birdland.com/oem + +config TARGET_TI814X_EVM + bool "Support ti814x_evm" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_TI816X_EVM + bool "Support ti816x_evm" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_BCM28155_AP + bool "Support bcm28155_ap" + select CPU_V7 + +config TARGET_BCMCYGNUS + bool "Support bcmcygnus" + select CPU_V7 + +config TARGET_BCMNSP + bool "Support bcmnsp" + select CPU_V7 + +config ARCH_EXYNOS + bool "Samsung EXYNOS" + select CPU_V7 + +config ARCH_S5PC1XX + bool "Samsung S5PC1XX" + select CPU_V7 + +config ARCH_HIGHBANK + bool "Calxeda Highbank" + select CPU_V7 + +config ARCH_KEYSTONE + bool "TI Keystone" + select CPU_V7 + select SUPPORT_SPL + +config ARCH_MX6 + bool "Freescale MX6" + select CPU_V7 + +config ARCH_MX5 + bool "Freescale MX5" + select CPU_V7 + +config TARGET_M53EVK + bool "Support m53evk" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_IMA3_MX53 + bool "Support ima3-mx53" + select CPU_V7 + +config TARGET_MX51EVK + bool "Support mx51evk" + select CPU_V7 + +config TARGET_MX53ARD + bool "Support mx53ard" + select CPU_V7 + +config TARGET_MX53EVK + bool "Support mx53evk" + select CPU_V7 + +config TARGET_MX53LOCO + bool "Support mx53loco" + select CPU_V7 + +config TARGET_MX53SMD + bool "Support mx53smd" + select CPU_V7 + +config TARGET_MX51_EFIKAMX + bool "Support mx51_efikamx" + select CPU_V7 + +config TARGET_VISION2 + bool "Support vision2" + select CPU_V7 + +config TARGET_UDOO + bool "Support udoo" + select CPU_V7 + +config TARGET_WANDBOARD + bool "Support wandboard" + select CPU_V7 + +config TARGET_WARP + bool "Support WaRP" + select CPU_V7 + +config TARGET_TITANIUM + bool "Support titanium" + select CPU_V7 + +config TARGET_NITROGEN6X + bool "Support nitrogen6x" + select CPU_V7 + +config TARGET_CGTQMX6EVAL + bool "Support cgtqmx6eval" + select CPU_V7 + +config TARGET_EMBESTMX6BOARDS + bool "Support embestmx6boards" + select CPU_V7 + +config TARGET_ARISTAINETOS + bool "Support aristainetos" + select CPU_V7 + +config TARGET_NEST_DIAMOND3 + bool "Support Diamond3 board" + select CPU_V7 + +config TARGET_NEST_FLINTSTONE + bool "Support Flintstone board" + select CPU_V7 + +config TARGET_MX6QARM2 + bool "Support mx6qarm2" + select CPU_V7 + +config TARGET_MX6QSABREAUTO + bool "Support mx6qsabreauto" + select CPU_V7 + +config TARGET_MX6SABRESD + bool "Support mx6sabresd" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_MX6SLEVK + bool "Support mx6slevk" + select CPU_V7 + +config TARGET_MX6SXSABRESD + bool "Support mx6sxsabresd" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_MX6SXSABREAUTO + bool "Support mx6sxsabreauto" + select CPU_V7 + +config TARGET_MX6SX_17X17_ARM2 + bool "Support mx6sx_17x17_arm2" + select CPU_V7 + +config TARGET_MX6SX_19X19_ARM2 + bool "Support mx6sx_19x19_arm2" + select CPU_V7 + +config TARGET_MX7D_12X12_LPDDR3_ARM2 + bool "Support mx7d_12x12_lpddr3_arm2" + select CPU_V7 + +config TARGET_MX7D_12X12_DDR3_ARM2 + bool "Support mx7d_12x12_ddr3_arm2" + select CPU_V7 + +config TARGET_MX7D_19X19_LPDDR3_ARM2 + bool "Support mx7d_19x19_lpddr3_arm2" + select CPU_V7 + +config TARGET_MX7D_19X19_DDR3_ARM2 + bool "Support mx7d_19x19_ddr3_arm2" + select CPU_V7 + +config TARGET_MX7DSABRESD + bool "Support mx7dsabresd" + select CPU_V7 + +config TARGET_MX6UL_14X14_EVK + bool "Support mx6ul_14x14_evk" + select CPU_V7 + +config TARGET_MX6UL_14X14_DDR3_ARM2 + bool "Support mx6ul_14x14_ddr3_arm2" + select CPU_V7 + +config TARGET_MX6UL_14X14_LPDDR2_ARM2 + bool "Support mx6ul_14x14_lpddr2_arm2" + select CPU_V7 + +config TARGET_GW_VENTANA + bool "Support gw_ventana" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_HUMMINGBOARD + bool "Support hummingboard" + select CPU_V7 + +config TARGET_KOSAGI_NOVENA + bool "Support Kosagi Novena" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_TBS2910 + bool "Support tbs2910" + select CPU_V7 + +config TARGET_TQMA6 + bool "TQ Systems TQMa6 board" + select CPU_V7 + +config TARGET_OT1200 + bool "Bachmann OT1200" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PLATINUM_PICON + bool "Support platinum-picon" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_PLATINUM_TITANIUM + bool "Support platinum-titanium" + select CPU_V7 + select SUPPORT_SPL + +config OMAP34XX + bool "OMAP34XX SoC" + select CPU_V7 + +config OMAP44XX + bool "OMAP44XX SoC" + select CPU_V7 + select SUPPORT_SPL + +config OMAP54XX + bool "OMAP54XX SoC" + select CPU_V7 + select SUPPORT_SPL + +config RMOBILE + bool "Renesas ARM SoCs" + select CPU_V7 + +config TARGET_CM_FX6 + bool "Support cm_fx6" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_SOCFPGA_ARRIA5 + bool "Support socfpga_arria5" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_SOCFPGA_CYCLONE5 + bool "Support socfpga_cyclone5" + select CPU_V7 + select SUPPORT_SPL + +config ARCH_SUNXI + bool "Support sunxi (Allwinner) SoCs" + +config TARGET_SNOWBALL + bool "Support snowball" + select CPU_V7 + +config TARGET_U8500_HREF + bool "Support u8500_href" + select CPU_V7 + +config TARGET_VF610TWR + bool "Support vf610twr" + select CPU_V7 + +config ZYNQ + bool "Xilinx Zynq Platform" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_XILINX_ZYNQMP + bool "Support Xilinx ZynqMP Platform" + select ARM64 + +config TEGRA + bool "NVIDIA Tegra" + select SUPPORT_SPL + select SPL + select OF_CONTROL + select CPU_V7 + +config TARGET_VEXPRESS64_AEMV8A + bool "Support vexpress_aemv8a" + select ARM64 + +config TARGET_VEXPRESS64_BASE_FVP + bool "Support Versatile Express ARMv8a FVP BASE model" + select ARM64 + select SEMIHOSTING + +config TARGET_VEXPRESS64_JUNO + bool "Support Versatile Express Juno Development Platform" + select ARM64 + +config TARGET_LS2085A_EMU + bool "Support ls2085a_emu" + select ARM64 + select ARMV8_MULTIENTRY + +config TARGET_LS2085A_SIMU + bool "Support ls2085a_simu" + select ARM64 + select ARMV8_MULTIENTRY + +config TARGET_LS1021AQDS + bool "Support ls1021aqds" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_LS1021ATWR + bool "Support ls1021atwr" + select CPU_V7 + select SUPPORT_SPL + +config TARGET_BALLOON3 + bool "Support balloon3" + select CPU_PXA + +config TARGET_H2200 + bool "Support h2200" + select CPU_PXA + +config TARGET_PALMLD + bool "Support palmld" + select CPU_PXA + +config TARGET_PALMTC + bool "Support palmtc" + select CPU_PXA + +config TARGET_PALMTREO680 + bool "Support palmtreo680" + select CPU_PXA + select SUPPORT_SPL + +config TARGET_PXA255_IDP + bool "Support pxa255_idp" + select CPU_PXA + +config TARGET_TRIZEPSIV + bool "Support trizepsiv" + select CPU_PXA + +config TARGET_VPAC270 + bool "Support vpac270" + select CPU_PXA + select SUPPORT_SPL + +config TARGET_XAENIAX + bool "Support xaeniax" + select CPU_PXA + +config TARGET_ZIPITZ2 + bool "Support zipitz2" + select CPU_PXA + +config TARGET_LP8X4X + bool "Support lp8x4x" + select CPU_PXA + +config TARGET_COLIBRI_PXA270 + bool "Support colibri_pxa270" + select CPU_PXA + +config TARGET_JORNADA + bool "Support jornada" + select CPU_SA1100 + +config ARCH_UNIPHIER + bool "Panasonic UniPhier platform" + select CPU_V7 + select SUPPORT_SPL + select SPL + select OF_CONTROL + +endchoice + +source "arch/arm/mach-at91/Kconfig" + +source "arch/arm/mach-bcm283x/Kconfig" + +source "arch/arm/mach-davinci/Kconfig" + +source "arch/arm/cpu/armv7/exynos/Kconfig" + +source "arch/arm/mach-highbank/Kconfig" + +source "arch/arm/mach-keystone/Kconfig" + +source "arch/arm/mach-kirkwood/Kconfig" + +source "arch/arm/cpu/armv7/mx6/Kconfig" + +source "arch/arm/cpu/armv7/mx5/Kconfig" + +source "arch/arm/mach-nomadik/Kconfig" + +source "arch/arm/cpu/armv7/omap3/Kconfig" + +source "arch/arm/cpu/armv7/omap4/Kconfig" + +source "arch/arm/cpu/armv7/omap5/Kconfig" + +source "arch/arm/mach-orion5x/Kconfig" + +source "arch/arm/cpu/armv7/rmobile/Kconfig" + +source "arch/arm/cpu/armv7/s5pc1xx/Kconfig" + +source "arch/arm/mach-tegra/Kconfig" + +source "arch/arm/mach-uniphier/Kconfig" + +source "arch/arm/mach-versatile/Kconfig" + +source "arch/arm/cpu/armv7/zynq/Kconfig" + +source "arch/arm/cpu/armv7/Kconfig" + +source "arch/arm/cpu/armv8/Kconfig" + +source "arch/arm/imx-common/Kconfig" + +source "board/aristainetos/Kconfig" +source "board/BuR/kwb/Kconfig" +source "board/BuR/tseries/Kconfig" +source "board/CarMediaLab/flea3/Kconfig" +source "board/Marvell/aspenite/Kconfig" +source "board/Marvell/db-mv784mp-gp/Kconfig" +source "board/Marvell/gplugd/Kconfig" +source "board/altera/socfpga/Kconfig" +source "board/armadeus/apf27/Kconfig" +source "board/armltd/integrator/Kconfig" +source "board/armltd/vexpress/Kconfig" +source "board/armltd/vexpress64/Kconfig" +source "board/bachmann/ot1200/Kconfig" +source "board/balloon3/Kconfig" +source "board/barco/platinum/Kconfig" +source "board/barco/titanium/Kconfig" +source "board/bluegiga/apx4devkit/Kconfig" +source "board/boundary/nitrogen6x/Kconfig" +source "board/broadcom/bcm28155_ap/Kconfig" +source "board/broadcom/bcmcygnus/Kconfig" +source "board/broadcom/bcmnsp/Kconfig" +source "board/cirrus/edb93xx/Kconfig" +source "board/compulab/cm_t335/Kconfig" +source "board/compulab/cm_fx6/Kconfig" +source "board/congatec/cgtqmx6eval/Kconfig" +source "board/creative/xfi3/Kconfig" +source "board/davedenx/qong/Kconfig" +source "board/denx/m28evk/Kconfig" +source "board/denx/m53evk/Kconfig" +source "board/embest/mx6boards/Kconfig" +source "board/esg/ima3-mx53/Kconfig" +source "board/freescale/ls2085a/Kconfig" +source "board/freescale/ls1021aqds/Kconfig" +source "board/freescale/ls1021atwr/Kconfig" +source "board/freescale/mx23evk/Kconfig" +source "board/freescale/mx25pdk/Kconfig" +source "board/freescale/mx28evk/Kconfig" +source "board/freescale/mx31ads/Kconfig" +source "board/freescale/mx31pdk/Kconfig" +source "board/freescale/mx35pdk/Kconfig" +source "board/freescale/mx51evk/Kconfig" +source "board/freescale/mx53ard/Kconfig" +source "board/freescale/mx53evk/Kconfig" +source "board/freescale/mx53loco/Kconfig" +source "board/freescale/mx53smd/Kconfig" +source "board/freescale/mx6qarm2/Kconfig" +source "board/freescale/mx6qsabreauto/Kconfig" +source "board/freescale/mx6sabresd/Kconfig" +source "board/freescale/mx6slevk/Kconfig" +source "board/freescale/mx6sxsabresd/Kconfig" +source "board/freescale/mx6sxsabreauto/Kconfig" +source "board/freescale/mx6sx_17x17_arm2/Kconfig" +source "board/freescale/mx6sx_19x19_arm2/Kconfig" +source "board/freescale/mx7d_12x12_lpddr3_arm2/Kconfig" +source "board/freescale/mx7d_12x12_ddr3_arm2/Kconfig" +source "board/freescale/mx7d_19x19_lpddr3_arm2/Kconfig" +source "board/freescale/mx7d_19x19_ddr3_arm2/Kconfig" +source "board/freescale/mx7dsabresd/Kconfig" +source "board/freescale/mx6ul_14x14_evk/Kconfig" +source "board/freescale/mx6ul_14x14_ddr3_arm2/Kconfig" +source "board/freescale/mx6ul_14x14_lpddr2_arm2/Kconfig" +source "board/freescale/vf610twr/Kconfig" +source "board/gateworks/gw_ventana/Kconfig" +source "board/genesi/mx51_efikamx/Kconfig" +source "board/gumstix/pepper/Kconfig" +source "board/h2200/Kconfig" +source "board/hale/tt01/Kconfig" +source "board/icpdas/lp8x4x/Kconfig" +source "board/imx31_phycore/Kconfig" +source "board/isee/igep0033/Kconfig" +source "board/jornada/Kconfig" +source "board/karo/tx25/Kconfig" +source "board/kosagi/novena/Kconfig" +source "board/logicpd/imx27lite/Kconfig" +source "board/logicpd/imx31_litekit/Kconfig" +source "board/maxbcm/Kconfig" +source "board/mpl/vcma9/Kconfig" +source "board/nest/diamond3/Kconfig" +source "board/nest/flintstone/Kconfig" +source "board/olimex/mx23_olinuxino/Kconfig" +source "board/palmld/Kconfig" +source "board/palmtc/Kconfig" +source "board/palmtreo680/Kconfig" +source "board/phytec/pcm051/Kconfig" +source "board/ppcag/bg0900/Kconfig" +source "board/pxa255_idp/Kconfig" +source "board/samsung/smdk2410/Kconfig" +source "board/sandisk/sansa_fuze_plus/Kconfig" +source "board/scb9328/Kconfig" +source "board/schulercontrol/sc_sps_1/Kconfig" +source "board/siemens/draco/Kconfig" +source "board/siemens/pxm2/Kconfig" +source "board/siemens/rut/Kconfig" +source "board/silica/pengwyn/Kconfig" +source "board/solidrun/hummingboard/Kconfig" +source "board/spear/spear300/Kconfig" +source "board/spear/spear310/Kconfig" +source "board/spear/spear320/Kconfig" +source "board/spear/spear600/Kconfig" +source "board/spear/x600/Kconfig" +source "board/st-ericsson/snowball/Kconfig" +source "board/st-ericsson/u8500/Kconfig" +source "board/st/stv0991/Kconfig" +source "board/sunxi/Kconfig" +source "board/syteco/zmx25/Kconfig" +source "board/tbs/tbs2910/Kconfig" +source "board/ti/am335x/Kconfig" +source "board/ti/am43xx/Kconfig" +source "board/birdland/bav335x/Kconfig" +source "board/ti/ti814x/Kconfig" +source "board/ti/ti816x/Kconfig" +source "board/timll/devkit3250/Kconfig" +source "board/toradex/colibri_pxa270/Kconfig" +source "board/tqc/tqma6/Kconfig" +source "board/trizepsiv/Kconfig" +source "board/ttcontrol/vision2/Kconfig" +source "board/udoo/Kconfig" +source "board/vpac270/Kconfig" +source "board/wandboard/Kconfig" +source "board/warp/Kconfig" +source "board/woodburn/Kconfig" +source "board/work-microwave/work_92105/Kconfig" +source "board/xaeniax/Kconfig" +source "board/xilinx/zynqmp/Kconfig" +source "board/zipitz2/Kconfig" + +source "arch/arm/Kconfig.debug" + +endmenu
diff --git a/u-boot-imx/arch/arm/Kconfig.debug b/u-boot-imx/arch/arm/Kconfig.debug new file mode 100644 index 0000000..624bcf4 --- /dev/null +++ b/u-boot-imx/arch/arm/Kconfig.debug
@@ -0,0 +1,64 @@ +menu "ARM debug" + +config DEBUG_LL + bool "Low-level debugging functions" + depends on !ARM64 + help + Say Y here to include definitions of printascii, printch, printhex + in U-Boot. This is helpful if you are debugging code that + executes before the console is initialized. + +choice + prompt "Low-level debugging port" + depends on DEBUG_LL + + config DEBUG_LL_UART_8250 + bool "Low-level debugging via 8250 UART" + help + Say Y here if you wish the debug print routes to direct + their output to an 8250 UART. You can use this option + to provide the parameters for the 8250 UART rather than + selecting one of the platform specific options above if + you know the parameters for the port. + + This option is preferred over the platform specific + options; the platform specific options are deprecated + and will be soon removed. + +endchoice + +config DEBUG_LL_INCLUDE + string + depends on DEBUG_LL + default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 + default "mach/debug-macro.S" + +# Compatibility options for 8250 +config DEBUG_UART_8250 + bool + +config DEBUG_UART_PHYS + hex "Physical base address of debug UART" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + +# This is not used in U-Boot +config DEBUG_UART_VIRT + hex + default DEBUG_UART_PHYS + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + +config DEBUG_UART_8250_SHIFT + int "Register offset shift for the 8250 debug UART" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + default 2 + +config DEBUG_UART_8250_WORD + bool "Use 32-bit accesses for 8250 UART" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + depends on DEBUG_UART_8250_SHIFT >= 2 + +config DEBUG_UART_8250_FLOW_CONTROL + bool "Enable flow control for 8250 UART" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + +endmenu
diff --git a/u-boot-imx/arch/arm/Makefile b/u-boot-imx/arch/arm/Makefile new file mode 100644 index 0000000..1bbf450 --- /dev/null +++ b/u-boot-imx/arch/arm/Makefile
@@ -0,0 +1,92 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TEGRA),yy) +CONFIG_CPU_V7= +CONFIG_CPU_ARM720T=y +endif + +# This selects which instruction set is used. +arch-$(CONFIG_CPU_ARM720T) =-march=armv4 +arch-$(CONFIG_CPU_ARM920T) =-march=armv4 +arch-$(CONFIG_CPU_ARM926EJS) =-march=armv5te +arch-$(CONFIG_CPU_ARM946ES) =-march=armv4 +arch-$(CONFIG_CPU_SA1100) =-march=armv4 +arch-$(CONFIG_CPU_PXA) = +arch-$(CONFIG_CPU_ARM1136) =-march=armv5 +arch-$(CONFIG_CPU_ARM1176) =-march=armv5t +arch-$(CONFIG_CPU_V7) =$(call cc-option, -march=armv7-a, -march=armv5) +arch-$(CONFIG_ARM64) =-march=armv8-a + +# Evaluate arch cc-option calls now +arch-y := $(arch-y) + +# This selects how we optimise for the processor. +tune-$(CONFIG_CPU_ARM720T) =-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM920T) = +tune-$(CONFIG_CPU_ARM926EJS) = +tune-$(CONFIG_CPU_ARM946ES) = +tune-$(CONFIG_CPU_SA1100) =-mtune=strongarm1100 +tune-$(CONFIG_CPU_PXA) =-mcpu=xscale +tune-$(CONFIG_CPU_ARM1136) = +tune-$(CONFIG_CPU_ARM1176) = +tune-$(CONFIG_CPU_V7) = +tune-$(CONFIG_ARM64) = + +# Evaluate tune cc-option calls now +tune-y := $(tune-y) + +PLATFORM_CPPFLAGS += $(arch-y) $(tune-y) + +# Machine directory name. This list is sorted alphanumerically +# by CONFIG_* macro name. +machine-$(CONFIG_ARCH_AT91) += at91 +machine-$(CONFIG_ARCH_BCM283X) += bcm283x +machine-$(CONFIG_ARCH_DAVINCI) += davinci +machine-$(CONFIG_ARCH_HIGHBANK) += highbank +machine-$(CONFIG_ARCH_KEYSTONE) += keystone +# TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD +machine-$(CONFIG_KIRKWOOD) += kirkwood +# TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA +machine-$(CONFIG_ARCH_NOMADIK) += nomadik +# TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X +machine-$(CONFIG_ORION5X) += orion5x +machine-$(CONFIG_TEGRA) += tegra +machine-$(CONFIG_ARCH_UNIPHIER) += uniphier +machine-$(CONFIG_ARCH_VERSATILE) += versatile + +machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) + +PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) + +libs-y += $(machdirs) + +head-y := arch/arm/cpu/$(CPU)/start.o + +ifeq ($(CONFIG_SPL_BUILD),y) +ifneq ($(CONFIG_SPL_START_S_PATH),) +head-y := $(CONFIG_SPL_START_S_PATH:"%"=%)/start.o +endif +endif + +libs-y += arch/arm/cpu/$(CPU)/ +libs-y += arch/arm/cpu/ +libs-y += arch/arm/lib/ + +ifeq ($(CONFIG_SPL_BUILD),y) +ifneq (,$(CONFIG_MX23)$(CONFIG_MX35)$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx31 mx35)) +libs-y += arch/arm/imx-common/ +endif +else +ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx31 mx35 mxs vf610)) +libs-y += arch/arm/imx-common/ +endif +endif + +ifneq (,$(filter $(SOC), armada-xp kirkwood)) +libs-y += arch/arm/mvebu-common/ +endif + +# deprecated +-include $(machdirs)/config.mk
diff --git a/u-boot-imx/arch/arm/config.mk b/u-boot-imx/arch/arm/config.mk new file mode 100644 index 0000000..c005ce4 --- /dev/null +++ b/u-boot-imx/arch/arm/config.mk
@@ -0,0 +1,134 @@ +# +# (C) Copyright 2000-2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifndef CONFIG_STANDALONE_LOAD_ADDR +ifneq ($(CONFIG_OMAP_COMMON),) +CONFIG_STANDALONE_LOAD_ADDR = 0x80300000 +else +CONFIG_STANDALONE_LOAD_ADDR = 0xc100000 +endif +endif + +LDFLAGS_FINAL += --gc-sections +PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ + -fno-common -ffixed-r9 +PLATFORM_RELFLAGS += $(call cc-option, -msoft-float) \ + $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) + +PLATFORM_CPPFLAGS += -D__ARM__ + +# Choose between ARM/Thumb instruction sets +ifeq ($(CONFIG_SYS_THUMB_BUILD),y) +AFLAGS_IMPLICIT_IT := $(call as-option,-Wa$(comma)-mimplicit-it=always) +PF_CPPFLAGS_ARM := $(AFLAGS_IMPLICIT_IT) \ + $(call cc-option, -mthumb -mthumb-interwork,\ + $(call cc-option,-marm,)\ + $(call cc-option,-mno-thumb-interwork,)\ + ) +else +PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \ + $(call cc-option,-mno-thumb-interwork,) +endif + +# Only test once +ifneq ($(CONFIG_SPL_BUILD),y) +ifeq ($(CONFIG_SYS_THUMB_BUILD),y) +archprepare: checkthumb + +checkthumb: + @if test "$(call cc-version)" -lt "0404"; then \ + echo -n '*** Your GCC does not produce working '; \ + echo 'binaries in THUMB mode.'; \ + echo '*** Your board is configured for THUMB mode.'; \ + false; \ + fi +endif +endif + +# Try if EABI is supported, else fall back to old API, +# i. e. for example: +# - with ELDK 4.2 (EABI supported), use: +# -mabi=aapcs-linux +# - with ELDK 4.1 (gcc 4.x, no EABI), use: +# -mabi=apcs-gnu +# - with ELDK 3.1 (gcc 3.x), use: +# -mapcs-32 +PF_CPPFLAGS_ABI := $(call cc-option,\ + -mabi=aapcs-linux,\ + $(call cc-option,\ + -mapcs-32,\ + $(call cc-option,\ + -mabi=apcs-gnu,\ + )\ + )\ + ) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARM) $(PF_CPPFLAGS_ABI) + +# For EABI, make sure to provide raise() +ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) +# This file is parsed many times, so the string may get added multiple +# times. Also, the prefix needs to be different based on whether +# CONFIG_SPL_BUILD is defined or not. 'filter-out' the existing entry +# before adding the correct one. +PLATFORM_LIBS := arch/arm/lib/eabi_compat.o \ + $(filter-out arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS)) +endif + +# needed for relocation +LDFLAGS_u-boot += -pie + +# +# FIXME: binutils versions < 2.22 have a bug in the assembler where +# branches to weak symbols can be incorrectly optimized in thumb mode +# to a short branch (b.n instruction) that won't reach when the symbol +# gets preempted +# +# http://sourceware.org/bugzilla/show_bug.cgi?id=12532 +# +ifeq ($(CONFIG_SYS_THUMB_BUILD),y) +ifeq ($(GAS_BUG_12532),) +export GAS_BUG_12532:=$(shell if [ $(call binutils-version) -lt 0222 ] ; \ + then echo y; else echo n; fi) +endif +ifeq ($(GAS_BUG_12532),y) +PLATFORM_RELFLAGS += -fno-optimize-sibling-calls +endif +endif + +ifneq ($(CONFIG_SPL_BUILD),y) +# Check that only R_ARM_RELATIVE relocations are generated. +ALL-y += checkarmreloc +# The movt / movw can hardcode 16 bit parts of the addresses in the +# instruction. Relocation is not supported for that case, so disable +# such usage by requiring word relocations. +PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations) +endif + +# limit ourselves to the sections we want in the .bin. +ifdef CONFIG_ARM64 +OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn +else +OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn +endif + +ifdef CONFIG_OF_EMBED +OBJCOPYFLAGS += -j .dtb.init.rodata +endif + +ifneq ($(CONFIG_IMX_CONFIG),) +ifdef CONFIG_SPL +ifndef CONFIG_SPL_BUILD +ALL-y += SPL +endif +else +ifeq ($(CONFIG_OF_SEPARATE),y) +ALL-y += u-boot-dtb.imx +else +ALL-y += u-boot.imx +endif +endif +endif
diff --git a/u-boot-imx/arch/arm/cpu/Makefile b/u-boot-imx/arch/arm/cpu/Makefile new file mode 100644 index 0000000..6bea3d3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/Makefile
@@ -0,0 +1 @@ +obj- += dummy.o
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/Makefile b/u-boot-imx/arch/arm/cpu/arm1136/Makefile new file mode 100644 index 0000000..56a9390 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/Makefile
@@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +obj-y = cpu.o + +obj-$(CONFIG_MX31) += mx31/ +obj-$(CONFIG_MX35) += mx35/
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/cpu.c b/u-boot-imx/arch/arm/cpu/arm1136/cpu.c new file mode 100644 index 0000000..a7aed4b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/cpu.c
@@ -0,0 +1,160 @@ +/* + * (C) Copyright 2004 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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + +#ifdef CONFIG_LCD + { + extern void lcd_disable(void); + extern void lcd_panel_disable(void); + + lcd_disable(); /* proper disable of lcd & panel */ + lcd_panel_disable(); + } +#endif + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +static void cache_flush(void) +{ + unsigned long i = 0; + /* clean entire data cache */ + asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i)); + /* invalidate both caches and flush btb */ + asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i)); + /* mem barrier to sync things */ + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i)); +} + +#ifndef CONFIG_SYS_DCACHE_OFF + +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 32 +#endif + +void invalidate_dcache_all(void) +{ + asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0)); +} + +void flush_dcache_all(void) +{ + asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0)); + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +static int check_cache_range(unsigned long start, unsigned long stop) +{ + int ok = 1; + + if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (!ok) + debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", + start, stop); + + return ok; +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ + if (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ + if (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } + + asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} + +#else /* #ifndef CONFIG_SYS_DCACHE_OFF */ +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_cache(unsigned long start, unsigned long size) +{ +} +#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ + +#if !defined(CONFIG_SYS_ICACHE_OFF) || !defined(CONFIG_SYS_DCACHE_OFF) +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx31/Makefile b/u-boot-imx/arch/arm/cpu/arm1136/mx31/Makefile new file mode 100644 index 0000000..dcbd570 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx31/Makefile
@@ -0,0 +1,14 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += generic.o +obj-y += timer.o +obj-y += devices.o + +ifndef CONFIG_SPL_BUILD +obj-y += relocate.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx31/devices.c b/u-boot-imx/arch/arm/cpu/arm1136/mx31/devices.c new file mode 100644 index 0000000..ae5db86 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx31/devices.c
@@ -0,0 +1,51 @@ +/* + * + * (C) Copyright 2009 Magnus Lilja <lilja.magnus@gmail.com> + * + * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> + +void mx31_uart1_hw_init(void) +{ + /* setup pins for UART1 */ + mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX); + mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX); + mx31_gpio_mux(MUX_RTS1__UART1_RTS_B); + mx31_gpio_mux(MUX_CTS1__UART1_CTS_B); +} + +void mx31_uart2_hw_init(void) +{ + /* setup pins for UART2 */ + mx31_gpio_mux(MUX_RXD2__UART2_RXD_MUX); + mx31_gpio_mux(MUX_TXD2__UART2_TXD_MUX); + mx31_gpio_mux(MUX_RTS2__UART2_RTS_B); + mx31_gpio_mux(MUX_CTS2__UART2_CTS_B); +} + +#ifdef CONFIG_MXC_SPI +/* + * Note: putting several spi setups here makes no sense as they may differ + * at board level (physical pin SS0 of CSPI2 may aswell be used as SS0 of CSPI3) + */ +void mx31_spi2_hw_init(void) +{ + /* SPI2 */ + mx31_gpio_mux(MUX_CSPI2_SS2__CSPI2_SS2_B); + mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); + mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); + mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI); + mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO); + mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B); + mx31_gpio_mux(MUX_CSPI2_SS1__CSPI2_SS1_B); + + /* start SPI2 clock */ + __REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx31/generic.c b/u-boot-imx/arch/arm/cpu/arm1136/mx31/generic.c new file mode 100644 index 0000000..060d46b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx31/generic.c
@@ -0,0 +1,219 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> + +static u32 mx31_decode_pll(u32 reg, u32 infreq) +{ + u32 mfi = GET_PLL_MFI(reg); + s32 mfn = GET_PLL_MFN(reg); + u32 mfd = GET_PLL_MFD(reg); + u32 pd = GET_PLL_PD(reg); + + mfi = mfi <= 5 ? 5 : mfi; + mfn = mfn >= 512 ? mfn - 1024 : mfn; + mfd += 1; + pd += 1; + + return lldiv(2 * (u64)infreq * (mfi * mfd + mfn), + mfd * pd); +} + +static u32 mx31_get_mpl_dpdgck_clk(void) +{ + u32 infreq; + + if ((readl(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM) + infreq = MXC_CLK32 * 1024; + else + infreq = MXC_HCLK; + + return mx31_decode_pll(readl(CCM_MPCTL), infreq); +} + +static u32 mx31_get_mcu_main_clk(void) +{ + /* For now we assume mpl_dpdgck_clk == mcu_main_clk + * which should be correct for most boards + */ + return mx31_get_mpl_dpdgck_clk(); +} + +static u32 mx31_get_ipg_clk(void) +{ + u32 freq = mx31_get_mcu_main_clk(); + u32 pdr0 = readl(CCM_PDR0); + + freq /= GET_PDR0_MAX_PODF(pdr0) + 1; + freq /= GET_PDR0_IPG_PODF(pdr0) + 1; + + return freq; +} + +/* hsp is the clock for the ipu */ +static u32 mx31_get_hsp_clk(void) +{ + u32 freq = mx31_get_mcu_main_clk(); + u32 pdr0 = readl(CCM_PDR0); + + freq /= GET_PDR0_HSP_PODF(pdr0) + 1; + + return freq; +} + +void mx31_dump_clocks(void) +{ + u32 cpufreq = mx31_get_mcu_main_clk(); + printf("mx31 cpu clock: %dMHz\n", cpufreq / 1000000); + printf("ipg clock : %dHz\n", mx31_get_ipg_clk()); + printf("hsp clock : %dHz\n", mx31_get_hsp_clk()); +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return mx31_get_mcu_main_clk(); + case MXC_IPG_CLK: + case MXC_IPG_PERCLK: + case MXC_CSPI_CLK: + case MXC_UART_CLK: + case MXC_ESDHC_CLK: + case MXC_I2C_CLK: + return mx31_get_ipg_clk(); + case MXC_IPU_CLK: + return mx31_get_hsp_clk(); + } + return -1; +} + +u32 imx_get_uartclk(void) +{ + return mxc_get_clock(MXC_UART_CLK); +} + +void mx31_gpio_mux(unsigned long mode) +{ + unsigned long reg, shift, tmp; + + reg = IOMUXC_BASE + (mode & 0x1fc); + shift = (~mode & 0x3) * 8; + + tmp = readl(reg); + tmp &= ~(0xff << shift); + tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift; + writel(tmp, reg); +} + +void mx31_set_pad(enum iomux_pins pin, u32 config) +{ + u32 field, l, reg; + + pin &= IOMUX_PADNUM_MASK; + reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4; + field = (pin + 2) % 3; + + l = readl(reg); + l &= ~(0x1ff << (field * 10)); + l |= config << (field * 10); + writel(l, reg); + +} + +void mx31_set_gpr(enum iomux_gp_func gp, char en) +{ + u32 l; + struct iomuxc_regs *iomuxc = (struct iomuxc_regs *)IOMUXC_BASE; + + l = readl(&iomuxc->gpr); + if (en) + l |= gp; + else + l &= ~gp; + + writel(l, &iomuxc->gpr); +} + +void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs) +{ + struct mx31_weim *weim = (struct mx31_weim *) WEIM_BASE; + struct mx31_weim_cscr *cscr = &weim->cscr[cs]; + + writel(weimcs->upper, &cscr->upper); + writel(weimcs->lower, &cscr->lower); + writel(weimcs->additional, &cscr->additional); +} + +struct mx3_cpu_type mx31_cpu_type[] = { + { .srev = 0x00, .v = 0x10 }, + { .srev = 0x10, .v = 0x11 }, + { .srev = 0x11, .v = 0x11 }, + { .srev = 0x12, .v = 0x1F }, + { .srev = 0x13, .v = 0x1F }, + { .srev = 0x14, .v = 0x12 }, + { .srev = 0x15, .v = 0x12 }, + { .srev = 0x28, .v = 0x20 }, + { .srev = 0x29, .v = 0x20 }, +}; + +u32 get_cpu_rev(void) +{ + u32 i, srev; + + /* read SREV register from IIM module */ + struct iim_regs *iim = (struct iim_regs *)MX31_IIM_BASE_ADDR; + srev = readl(&iim->iim_srev); + + for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) + if (srev == mx31_cpu_type[i].srev) + return mx31_cpu_type[i].v; + + return srev | 0x8000; +} + +static char *get_reset_cause(void) +{ + /* read RCSR register from CCM module */ + struct clock_control_regs *ccm = + (struct clock_control_regs *)CCM_BASE; + + u32 cause = readl(&ccm->rcsr) & 0x07; + + switch (cause) { + case 0x0000: + return "POR"; + case 0x0001: + return "RST"; + case 0x0002: + return "WDOG"; + case 0x0006: + return "JTAG"; + case 0x0007: + return "ARM11P power gating"; + default: + return "unknown reset"; + } +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u32 srev = get_cpu_rev(); + + printf("CPU: Freescale i.MX31 rev %d.%d%s at %d MHz.\n", + (srev & 0xF0) >> 4, (srev & 0x0F), + ((srev & 0x8000) ? " unknown" : ""), + mx31_get_mcu_main_clk() / 1000000); + printf("Reset cause: %s\n", get_reset_cause()); + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx31/relocate.S b/u-boot-imx/arch/arm/cpu/arm1136/mx31/relocate.S new file mode 100644 index 0000000..1c556df --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx31/relocate.S
@@ -0,0 +1,23 @@ +/* + * relocate - i.MX31-specific vector relocation + * + * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +/* + * The i.MX31 SoC is very specific with respect to exceptions: it + * does not provide RAM at the high vectors address (0xFFFF0000), + * thus only the low address (0x00000000) is useable; but that is + * in ROM, so let's avoid relocating the vectors. + */ + .section .text.relocate_vectors,"ax",%progbits + +ENTRY(relocate_vectors) + + bx lr + +ENDPROC(relocate_vectors)
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx31/timer.c b/u-boot-imx/arch/arm/cpu/arm1136/mx31/timer.c new file mode 100644 index 0000000..3a81ce4 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx31/timer.c
@@ -0,0 +1,47 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/io.h> + +#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ + +/* General purpose timers registers */ +#define GPTCR __REG(TIMER_BASE) /* Control register */ +#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */ +#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */ +#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */ + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_FRR (1 << 9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */ +#define GPTCR_TEN 1 /* Timer enable */ + +DECLARE_GLOBAL_DATA_PTR; + +/* The 32768Hz 32-bit timer overruns in 131072 seconds */ +int timer_init(void) +{ + int i; + + /* setup GP Timer 1 */ + GPTCR = GPTCR_SWR; + for (i = 0; i < 100; i++) + GPTCR = 0; /* We have no udelay by now */ + GPTPR = 0; /* 32Khz */ + /* Freerun Mode, PERCLK1 input */ + GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; + + return 0; +} + +unsigned long timer_read_counter(void) +{ + return GPTCNT; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx35/Makefile b/u-boot-imx/arch/arm/cpu/arm1136/mx35/Makefile new file mode 100644 index 0000000..796db9c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx35/Makefile
@@ -0,0 +1,16 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008-2009 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += generic.o +obj-y += timer.o +obj-y += mx35_sdram.o + +ifndef CONFIG_SPL_BUILD +obj-y += relocate.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx35/generic.c b/u-boot-imx/arch/arm/cpu/arm1136/mx35/generic.c new file mode 100644 index 0000000..bc98edd --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx35/generic.c
@@ -0,0 +1,547 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2008-2010 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> +#endif +#include <netdev.h> +#include <spl.h> + +#define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel)) +#define CLK_CODE_ARM(c) (((c) >> 16) & 0xFF) +#define CLK_CODE_AHB(c) (((c) >> 8) & 0xFF) +#define CLK_CODE_PATH(c) ((c) & 0xFF) + +#define CCM_GET_DIVIDER(x, m, o) (((x) & (m)) >> (o)) + +#ifdef CONFIG_FSL_ESDHC +DECLARE_GLOBAL_DATA_PTR; +#endif + +static int g_clk_mux_auto[8] = { + CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1, + CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1, +}; + +static int g_clk_mux_consumer[16] = { + CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(1, 3, 1), -1, + -1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0), + CLK_CODE(1, 8, 1), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1, + -1, -1, CLK_CODE(4, 2, 0), -1, +}; + +static int hsp_div_table[3][16] = { + {4, 3, 2, -1, -1, -1, 1, 5, 4, 3, 2, -1, -1, -1, 1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, 8, 6, 4, -1, -1, -1, 2, -1}, + {3, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1}, +}; + +u32 get_cpu_rev(void) +{ + int reg; + struct iim_regs *iim = + (struct iim_regs *)IIM_BASE_ADDR; + reg = readl(&iim->iim_srev); + if (!reg) { + reg = readw(ROMPATCH_REV); + reg <<= 4; + } else { + reg += CHIP_REV_1_0; + } + + return 0x35000 + (reg & 0xFF); +} + +static u32 get_arm_div(u32 pdr0, u32 *fi, u32 *fd) +{ + int *pclk_mux; + if (pdr0 & MXC_CCM_PDR0_AUTO_CON) { + pclk_mux = g_clk_mux_consumer + + ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >> + MXC_CCM_PDR0_CON_MUX_DIV_OFFSET); + } else { + pclk_mux = g_clk_mux_auto + + ((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >> + MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET); + } + + if ((*pclk_mux) == -1) + return -1; + + if (fi && fd) { + if (!CLK_CODE_PATH(*pclk_mux)) { + *fi = *fd = 1; + return CLK_CODE_ARM(*pclk_mux); + } + if (pdr0 & MXC_CCM_PDR0_AUTO_CON) { + *fi = 3; + *fd = 4; + } else { + *fi = 2; + *fd = 3; + } + } + return CLK_CODE_ARM(*pclk_mux); +} + +static int get_ahb_div(u32 pdr0) +{ + int *pclk_mux; + + pclk_mux = g_clk_mux_consumer + + ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >> + MXC_CCM_PDR0_CON_MUX_DIV_OFFSET); + + if ((*pclk_mux) == -1) + return -1; + + return CLK_CODE_AHB(*pclk_mux); +} + +static u32 decode_pll(u32 reg, u32 infreq) +{ + u32 mfi = (reg >> 10) & 0xf; + s32 mfn = reg & 0x3ff; + u32 mfd = (reg >> 16) & 0x3ff; + u32 pd = (reg >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + mfn = mfn >= 512 ? mfn - 1024 : mfn; + mfd += 1; + pd += 1; + + return lldiv(2 * (u64)infreq * (mfi * mfd + mfn), + mfd * pd); +} + +static u32 get_mcu_main_clk(void) +{ + u32 arm_div = 0, fi = 0, fd = 0; + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd); + fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK); + return fi / (arm_div * fd); +} + +static u32 get_ipg_clk(void) +{ + u32 freq = get_mcu_main_clk(); + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + u32 pdr0 = readl(&ccm->pdr0); + + return freq / (get_ahb_div(pdr0) * 2); +} + +static u32 get_ipg_per_clk(void) +{ + u32 freq = get_mcu_main_clk(); + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + u32 pdr0 = readl(&ccm->pdr0); + u32 pdr4 = readl(&ccm->pdr4); + u32 div; + if (pdr0 & MXC_CCM_PDR0_PER_SEL) { + div = CCM_GET_DIVIDER(pdr4, + MXC_CCM_PDR4_PER0_PODF_MASK, + MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1; + } else { + div = CCM_GET_DIVIDER(pdr0, + MXC_CCM_PDR0_PER_PODF_MASK, + MXC_CCM_PDR0_PER_PODF_OFFSET) + 1; + div *= get_ahb_div(pdr0); + } + return freq / div; +} + +u32 imx_get_uartclk(void) +{ + u32 freq; + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + u32 pdr4 = readl(&ccm->pdr4); + + if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) + freq = get_mcu_main_clk(); + else + freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK); + freq /= CCM_GET_DIVIDER(pdr4, + MXC_CCM_PDR4_UART_PODF_MASK, + MXC_CCM_PDR4_UART_PODF_OFFSET) + 1; + return freq; +} + +unsigned int mxc_get_main_clock(enum mxc_main_clock clk) +{ + u32 nfc_pdf, hsp_podf; + u32 pll, ret_val = 0, usb_podf; + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + + u32 reg = readl(&ccm->pdr0); + u32 reg4 = readl(&ccm->pdr4); + + reg |= 0x1; + + switch (clk) { + case CPU_CLK: + ret_val = get_mcu_main_clk(); + break; + case AHB_CLK: + ret_val = get_mcu_main_clk(); + break; + case HSP_CLK: + if (reg & CLKMODE_CONSUMER) { + hsp_podf = (reg >> 20) & 0x3; + pll = get_mcu_main_clk(); + hsp_podf = hsp_div_table[hsp_podf][(reg>>16)&0xF]; + if (hsp_podf > 0) { + ret_val = pll / hsp_podf; + } else { + puts("mismatch HSP with ARM clock setting\n"); + ret_val = 0; + } + } else { + ret_val = get_mcu_main_clk(); + } + break; + case IPG_CLK: + ret_val = get_ipg_clk(); + break; + case IPG_PER_CLK: + ret_val = get_ipg_per_clk(); + break; + case NFC_CLK: + nfc_pdf = (reg4 >> 28) & 0xF; + pll = get_mcu_main_clk(); + /* AHB/nfc_pdf */ + ret_val = pll / (nfc_pdf + 1); + break; + case USB_CLK: + usb_podf = (reg4 >> 22) & 0x3F; + if (reg4 & 0x200) + pll = get_mcu_main_clk(); + else + pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK); + + ret_val = pll / (usb_podf + 1); + break; + default: + printf("Unknown clock: %d\n", clk); + break; + } + + return ret_val; +} +unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) +{ + u32 ret_val = 0, pdf, pre_pdf, clk_sel; + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + u32 mpdr2 = readl(&ccm->pdr2); + u32 mpdr3 = readl(&ccm->pdr3); + u32 mpdr4 = readl(&ccm->pdr4); + + switch (clk) { + case UART1_BAUD: + case UART2_BAUD: + case UART3_BAUD: + clk_sel = mpdr3 & (1 << 14); + pdf = (mpdr4 >> 10) & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); + break; + case SSI1_BAUD: + pre_pdf = (mpdr2 >> 24) & 0x7; + pdf = mpdr2 & 0x3F; + clk_sel = mpdr2 & (1 << 6); + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case SSI2_BAUD: + pre_pdf = (mpdr2 >> 27) & 0x7; + pdf = (mpdr2 >> 8) & 0x3F; + clk_sel = mpdr2 & (1 << 6); + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case CSI_BAUD: + clk_sel = mpdr2 & (1 << 7); + pdf = (mpdr2 >> 16) & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); + break; + case MSHC_CLK: + pre_pdf = readl(&ccm->pdr1); + clk_sel = (pre_pdf & 0x80); + pdf = (pre_pdf >> 22) & 0x3F; + pre_pdf = (pre_pdf >> 28) & 0x7; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / + ((pre_pdf + 1) * (pdf + 1)); + break; + case ESDHC1_CLK: + clk_sel = mpdr3 & 0x40; + pdf = mpdr3 & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); + break; + case ESDHC2_CLK: + clk_sel = mpdr3 & 0x40; + pdf = (mpdr3 >> 8) & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); + break; + case ESDHC3_CLK: + clk_sel = mpdr3 & 0x40; + pdf = (mpdr3 >> 16) & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); + break; + case SPDIF_CLK: + clk_sel = mpdr3 & 0x400000; + pre_pdf = (mpdr3 >> 29) & 0x7; + pdf = (mpdr3 >> 23) & 0x3F; + ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / + ((pre_pdf + 1) * (pdf + 1)); + break; + default: + printf("%s(): This clock: %d not supported yet\n", + __func__, clk); + break; + } + + return ret_val; +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_mcu_main_clk(); + case MXC_AHB_CLK: + break; + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_IPG_PERCLK: + case MXC_I2C_CLK: + return get_ipg_per_clk(); + case MXC_UART_CLK: + return imx_get_uartclk(); + case MXC_ESDHC1_CLK: + return mxc_get_peri_clock(ESDHC1_CLK); + case MXC_ESDHC2_CLK: + return mxc_get_peri_clock(ESDHC2_CLK); + case MXC_ESDHC3_CLK: + return mxc_get_peri_clock(ESDHC3_CLK); + case MXC_USB_CLK: + return mxc_get_main_clock(USB_CLK); + case MXC_FEC_CLK: + return get_ipg_clk(); + case MXC_CSPI_CLK: + return get_ipg_clk(); + } + return -1; +} + +#ifdef CONFIG_FEC_MXC +/* + * The MX35 has no fuse for MAC, return a NULL MAC + */ +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + memset(mac, 0, 6); +} + +u32 imx_get_fecclk(void) +{ + return mxc_get_clock(MXC_IPG_CLK); +} +#endif + +int do_mx35_showclocks(cmd_tbl_t *cmdtp, + int flag, int argc, char * const argv[]) +{ + u32 cpufreq = get_mcu_main_clk(); + printf("mx35 cpu clock: %dMHz\n", cpufreq / 1000000); + printf("ipg clock : %dHz\n", get_ipg_clk()); + printf("ipg per clock : %dHz\n", get_ipg_per_clk()); + printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK)); + + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx35_showclocks, + "display clocks", + "" +); + +#if defined(CONFIG_DISPLAY_CPUINFO) +static char *get_reset_cause(void) +{ + /* read RCSR register from CCM module */ + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + + u32 cause = readl(&ccm->rcsr) & 0x0F; + + switch (cause) { + case 0x0000: + return "POR"; + case 0x0002: + return "JTAG"; + case 0x0004: + return "RST"; + case 0x0008: + return "WDOG"; + default: + return "unknown reset"; + } +} + +int print_cpuinfo(void) +{ + u32 srev = get_cpu_rev(); + + printf("CPU: Freescale i.MX35 rev %d.%d at %d MHz.\n", + (srev & 0xF0) >> 4, (srev & 0x0F), + get_mcu_main_clk() / 1000000); + + printf("Reset cause: %s\n", get_reset_cause()); + + return 0; +} +#endif + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ + int rc = -ENODEV; + +#if defined(CONFIG_FEC_MXC) + rc = fecmxc_initialize(bis); +#endif + + return rc; +} + +#ifdef CONFIG_FSL_ESDHC +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +int get_clocks(void) +{ +#ifdef CONFIG_FSL_ESDHC +#if CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC2_BASE_ADDR + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); +#elif CONFIG_SYS_FSL_ESDHC_ADDR == MMC_SDHC3_BASE_ADDR + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); +#else + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); +#endif +#endif + return 0; +} + +#define RCSR_MEM_CTL_WEIM 0 +#define RCSR_MEM_CTL_NAND 1 +#define RCSR_MEM_CTL_ATA 2 +#define RCSR_MEM_CTL_EXPANSION 3 +#define RCSR_MEM_TYPE_NOR 0 +#define RCSR_MEM_TYPE_ONENAND 2 +#define RCSR_MEM_TYPE_SD 0 +#define RCSR_MEM_TYPE_I2C 2 +#define RCSR_MEM_TYPE_SPI 3 + +u32 spl_boot_device(void) +{ + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + + u32 rcsr = readl(&ccm->rcsr); + u32 mem_type, mem_ctl; + + /* In external mode, no boot device is returned */ + if ((rcsr >> 10) & 0x03) + return BOOT_DEVICE_NONE; + + mem_ctl = (rcsr >> 25) & 0x03; + mem_type = (rcsr >> 23) & 0x03; + + switch (mem_ctl) { + case RCSR_MEM_CTL_WEIM: + switch (mem_type) { + case RCSR_MEM_TYPE_NOR: + return BOOT_DEVICE_NOR; + case RCSR_MEM_TYPE_ONENAND: + return BOOT_DEVICE_ONENAND; + default: + return BOOT_DEVICE_NONE; + } + case RCSR_MEM_CTL_NAND: + return BOOT_DEVICE_NAND; + case RCSR_MEM_CTL_EXPANSION: + switch (mem_type) { + case RCSR_MEM_TYPE_SD: + return BOOT_DEVICE_MMC1; + case RCSR_MEM_TYPE_I2C: + return BOOT_DEVICE_I2C; + case RCSR_MEM_TYPE_SPI: + return BOOT_DEVICE_SPI; + default: + return BOOT_DEVICE_NONE; + } + } + + return BOOT_DEVICE_NONE; +} + +#ifdef CONFIG_SPL_BUILD +u32 spl_boot_mode(void) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: +#ifdef CONFIG_SPL_FAT_SUPPORT + return MMCSD_MODE_FS; +#else + return MMCSD_MODE_RAW; +#endif + break; + case BOOT_DEVICE_NAND: + return 0; + break; + default: + puts("spl: ERROR: unsupported device\n"); + hang(); + } +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx35/mx35_sdram.c b/u-boot-imx/arch/arm/cpu/arm1136/mx35/mx35_sdram.c new file mode 100644 index 0000000..d358f5f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx35/mx35_sdram.c
@@ -0,0 +1,121 @@ +/* + * Copyright (C) 2012, Stefano Babic <sbabic@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <linux/types.h> +#include <asm/arch/sys_proto.h> + +#define ESDCTL_DDR2_EMR2 0x04000000 +#define ESDCTL_DDR2_EMR3 0x06000000 +#define ESDCTL_PRECHARGE 0x00000400 +#define ESDCTL_DDR2_EN_DLL 0x02000400 +#define ESDCTL_DDR2_RESET_DLL 0x00000333 +#define ESDCTL_DDR2_MR 0x00000233 +#define ESDCTL_DDR2_OCD_DEFAULT 0x02000780 + +enum { + SMODE_NORMAL = 0, + SMODE_PRECHARGE, + SMODE_AUTO_REFRESH, + SMODE_LOAD_REG, + SMODE_MANUAL_REFRESH +}; + +#define set_mode(x, en, m) (x | (en << 31) | (m << 28)) + +static inline void dram_wait(unsigned int count) +{ + volatile unsigned int wait = count; + + while (wait--) + ; + +} + +void mx3_setup_sdram_bank(u32 start_address, u32 ddr2_config, + u32 row, u32 col, u32 dsize, u32 refresh) +{ + struct esdc_regs *esdc = (struct esdc_regs *)ESDCTL_BASE_ADDR; + u32 *cfg_reg, *ctl_reg; + u32 val; + u32 ctlval; + + switch (start_address) { + case CSD0_BASE_ADDR: + cfg_reg = &esdc->esdcfg0; + ctl_reg = &esdc->esdctl0; + break; + case CSD1_BASE_ADDR: + cfg_reg = &esdc->esdcfg1; + ctl_reg = &esdc->esdctl1; + break; + default: + return; + } + + /* The MX35 supports 11 up to 14 rows */ + if (row < 11 || row > 14 || col < 8 || col > 10) + return; + ctlval = (row - 11) << 24 | (col - 8) << 20 | (dsize << 16); + + /* Initialize MISC register for DDR2 */ + val = ESDC_MISC_RST | ESDC_MISC_MDDR_EN | ESDC_MISC_MDDR_DL_RST | + ESDC_MISC_DDR_EN | ESDC_MISC_DDR2_EN; + writel(val, &esdc->esdmisc); + val &= ~(ESDC_MISC_RST | ESDC_MISC_MDDR_DL_RST); + writel(val, &esdc->esdmisc); + + /* + * according to DDR2 specs, wait a while before + * the PRECHARGE_ALL command + */ + dram_wait(0x20000); + + /* Load DDR2 config and timing */ + writel(ddr2_config, cfg_reg); + + /* Precharge ALL */ + writel(set_mode(ctlval, 1, SMODE_PRECHARGE), + ctl_reg); + writel(0xda, start_address + ESDCTL_PRECHARGE); + + /* Load mode */ + writel(set_mode(ctlval, 1, SMODE_LOAD_REG), + ctl_reg); + writeb(0xda, start_address + ESDCTL_DDR2_EMR2); /* EMRS2 */ + writeb(0xda, start_address + ESDCTL_DDR2_EMR3); /* EMRS3 */ + writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ + writeb(0xda, start_address + ESDCTL_DDR2_RESET_DLL); /* Reset DLL */ + + /* Precharge ALL */ + writel(set_mode(ctlval, 1, SMODE_PRECHARGE), + ctl_reg); + writel(0xda, start_address + ESDCTL_PRECHARGE); + + /* Set mode auto refresh : at least two refresh are required */ + writel(set_mode(ctlval, 1, SMODE_AUTO_REFRESH), + ctl_reg); + writel(0xda, start_address); + writel(0xda, start_address); + + writel(set_mode(ctlval, 1, SMODE_LOAD_REG), + ctl_reg); + writeb(0xda, start_address + ESDCTL_DDR2_MR); + writeb(0xda, start_address + ESDCTL_DDR2_OCD_DEFAULT); + + /* OCD mode exit */ + writeb(0xda, start_address + ESDCTL_DDR2_EN_DLL); /* Enable DLL */ + + /* Set normal mode */ + writel(set_mode(ctlval, 1, SMODE_NORMAL) | refresh, + ctl_reg); + + dram_wait(0x20000); + + /* Do not set delay lines, only for MDDR */ +}
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx35/relocate.S b/u-boot-imx/arch/arm/cpu/arm1136/mx35/relocate.S new file mode 100644 index 0000000..43003f8 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx35/relocate.S
@@ -0,0 +1,23 @@ +/* + * relocate - i.MX35-specific vector relocation + * + * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +/* + * The i.MX35 SoC is very specific with respect to exceptions: it + * does not provide RAM at the high vectors address (0xFFFF0000), + * thus only the low address (0x00000000) is useable; but that is + * in ROM, so let's avoid relocating the vectors. + */ + .section .text.relocate_vectors,"ax",%progbits + +ENTRY(relocate_vectors) + + bx lr + +ENDPROC(relocate_vectors)
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/mx35/timer.c b/u-boot-imx/arch/arm/cpu/arm1136/mx35/timer.c new file mode 100644 index 0000000..4edf533 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/mx35/timer.c
@@ -0,0 +1,47 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2008-2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1<<15) /* Software reset */ +#define GPTCR_FRR (1<<9) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */ +#define GPTCR_TEN (1) /* Timer enable */ + +/* + * nothing really to do with interrupts, just starts up a counter. + * The 32KHz 32-bit timer overruns in 134217 seconds + */ +int timer_init(void) +{ + int i; + struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR; + struct ccm_regs *ccm = (struct ccm_regs *)CCM_BASE_ADDR; + + /* setup GP Timer 1 */ + writel(GPTCR_SWR, &gpt->ctrl); + + writel(readl(&ccm->cgr1) | 3 << MXC_CCM_CGR1_GPT_OFFSET, &ccm->cgr1); + + for (i = 0; i < 100; i++) + writel(0, &gpt->ctrl); /* We have no udelay by now */ + writel(0, &gpt->pre); /* prescaler = 1 */ + /* Freerun Mode, 32KHz input */ + writel(readl(&gpt->ctrl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR, + &gpt->ctrl); + writel(readl(&gpt->ctrl) | GPTCR_TEN, &gpt->ctrl); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/start.S b/u-boot-imx/arch/arm/cpu/arm1136/start.S new file mode 100644 index 0000000..1ec79a6 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/start.S
@@ -0,0 +1,93 @@ +/* + * armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com> + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> + +/* + ************************************************************************* + * + * 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 + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + bx lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */ + mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified 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 + + /* + * 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. + */ + 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 */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/u-boot-imx/arch/arm/cpu/arm1136/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/arm1136/u-boot-spl.lds new file mode 100644 index 0000000..97e4a8b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1136/u-boot-spl.lds
@@ -0,0 +1,51 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + arch/arm/cpu/arm1136/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +}
diff --git a/u-boot-imx/arch/arm/cpu/arm1176/Makefile b/u-boot-imx/arch/arm/cpu/arm1176/Makefile new file mode 100644 index 0000000..deec427 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1176/Makefile
@@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +obj-y = cpu.o
diff --git a/u-boot-imx/arch/arm/cpu/arm1176/cpu.c b/u-boot-imx/arch/arm/cpu/arm1176/cpu.c new file mode 100644 index 0000000..2d81651 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1176/cpu.c
@@ -0,0 +1,51 @@ +/* + * (C) Copyright 2004 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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush (void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0)); + /* mem barrier to sync things */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm1176/start.S b/u-boot-imx/arch/arm/cpu/arm1176/start.S new file mode 100644 index 0000000..4c0ab4d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm1176/start.S
@@ -0,0 +1,112 @@ +/* + * armboot - Startup Code for ARM1176 CPU-core + * + * Copyright (c) 2007 Samsung Electronics + * + * Copyright (C) 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by + * jsgood (jsgood.yang@samsung.com) + * Base codes by scsuh (sc.suh) + */ + +#include <asm-offsets.h> +#include <config.h> + +#ifndef CONFIG_SYS_PHY_UBOOT_BASE +#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE +#endif + +/* + ************************************************************************* + * + * 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 + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x3f + orr r0, r0, #0xd3 + msr cpsr, r0 + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +cpu_init_crit: + /* + * When booting from NAND - it has definitely been a reset, so, no need + * to flush caches and disable the MMU + */ +#ifndef CONFIG_SPL_BUILD + /* + * 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 + + /* Prepare to disable the MMU */ + adr r2, mmu_disable_phys + sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE) + b mmu_disable + + .align 5 + /* Run in a single cache-line */ +mmu_disable: + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +mmu_disable_phys: + +#endif + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + bl lowlevel_init /* go setup pll,mux,memory */ + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + mov pc, lr
diff --git a/u-boot-imx/arch/arm/cpu/arm720t/Makefile b/u-boot-imx/arch/arm/cpu/arm720t/Makefile new file mode 100644 index 0000000..243a123 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm720t/Makefile
@@ -0,0 +1,9 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +obj-y = interrupts.o cpu.o
diff --git a/u-boot-imx/arch/arm/cpu/arm720t/cpu.c b/u-boot-imx/arch/arm/cpu/arm720t/cpu.c new file mode 100644 index 0000000..745fccd --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm720t/cpu.c
@@ -0,0 +1,22 @@ +/* + * (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> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * cleanup_before_linux() - Prepare the CPU to jump to Linux + * + * This function is called just before we call Linux, it + * prepares the processor for linux + */ +int cleanup_before_linux(void) +{ + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm720t/interrupts.c b/u-boot-imx/arch/arm/cpu/arm720t/interrupts.c new file mode 100644 index 0000000..e8ba1ae --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm720t/interrupts.c
@@ -0,0 +1,33 @@ +/* + * (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> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#ifdef CONFIG_USE_IRQ +void do_irq (struct pt_regs *pt_regs) +{ +} +#endif + +#if defined(CONFIG_TEGRA) +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + /* No timer routines for tegra as yet */ + lastdec = 0; + timestamp = 0; + + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm720t/start.S b/u-boot-imx/arch/arm/cpu/arm720t/start.S new file mode 100644 index 0000000..ec8e88d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm720t/start.S
@@ -0,0 +1,79 @@ +/* + * armboot - Startup Code for ARM720 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/hardware.h> + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from RAM! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + mov pc, lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + + mov ip, lr + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependent, you will + * find a lowlevel_init.S in your board directory. + */ + bl lowlevel_init + mov lr, ip + + mov pc, lr +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/Makefile b/u-boot-imx/arch/arm/cpu/arm920t/Makefile new file mode 100644 index 0000000..6582938 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/Makefile
@@ -0,0 +1,15 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o + +obj-y += cpu.o +obj-$(CONFIG_USE_IRQ) += interrupts.o + +obj-$(CONFIG_EP93XX) += ep93xx/ +obj-$(CONFIG_IMX) += imx/ +obj-$(CONFIG_S3C24X0) += s3c24x0/
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/cpu.c b/u-boot-imx/arch/arm/cpu/arm920t/cpu.c new file mode 100644 index 0000000..d73b51d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/cpu.c
@@ -0,0 +1,48 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/Makefile b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/Makefile new file mode 100644 index 0000000..638333a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/Makefile
@@ -0,0 +1,21 @@ +# +# Cirrus Logic EP93xx CPU-specific Makefile +# +# Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> +# +# Copyright (C) 2004, 2005 +# Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> +# +# Copyright (C) 2006 +# Dominic Rath <Dominic.Rath@gmx.de> +# +# Based on an original Makefile, which is +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o led.o speed.o timer.o +obj-y += lowlevel_init.o
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/cpu.c b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/cpu.c new file mode 100644 index 0000000..bb5ffd2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/cpu.c
@@ -0,0 +1,37 @@ +/* + * Cirrus Logic EP93xx CPU-specific support. + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> + +/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */ +extern void reset_cpu(ulong addr) +{ + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + uint32_t value; + + /* Unlock DeviceCfg and set SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value |= SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Unlock DeviceCfg and clear SWRST */ + writel(0xAA, &syscon->sysswlock); + value = readl(&syscon->devicecfg); + value &= ~SYSCON_DEVICECFG_SWRST; + writel(value, &syscon->devicecfg); + + /* Dying... */ + while (1) + ; /* noop */ +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/led.c b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/led.c new file mode 100644 index 0000000..6144729 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/led.c
@@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010, 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/ep93xx.h> +#include <config.h> +#include <status_led.h> + +static uint8_t saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF}; +static uint32_t gpio_pin[2] = {1 << STATUS_LED_GREEN, + 1 << STATUS_LED_RED}; + +inline void switch_LED_on(uint8_t led) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr); + saved_state[led] = STATUS_LED_ON; +} + +inline void switch_LED_off(uint8_t led) +{ + register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE; + + writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr); + saved_state[led] = STATUS_LED_OFF; +} + +void red_led_on(void) +{ + switch_LED_on(STATUS_LED_RED); +} + +void red_led_off(void) +{ + switch_LED_off(STATUS_LED_RED); +} + +void green_led_on(void) +{ + switch_LED_on(STATUS_LED_GREEN); +} + +void green_led_off(void) +{ + switch_LED_off(STATUS_LED_GREEN); +} + +void __led_init(led_id_t mask, int state) +{ + __led_set(mask, state); +} + +void __led_toggle(led_id_t mask) +{ + if (STATUS_LED_RED == mask) { + if (STATUS_LED_ON == saved_state[STATUS_LED_RED]) + red_led_off(); + else + red_led_on(); + } else if (STATUS_LED_GREEN == mask) { + if (STATUS_LED_ON == saved_state[STATUS_LED_GREEN]) + green_led_off(); + else + green_led_on(); + } +} + +void __led_set(led_id_t mask, int state) +{ + if (STATUS_LED_RED == mask) { + if (STATUS_LED_ON == state) + red_led_on(); + else + red_led_off(); + } else if (STATUS_LED_GREEN == mask) { + if (STATUS_LED_ON == state) + green_led_on(); + else + green_led_off(); + } +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S new file mode 100644 index 0000000..cfad206 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
@@ -0,0 +1,458 @@ +/* + * Low-level initialization for EP93xx + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * Copyright (C) 2013 + * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru> + * + * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de> + * Copyright (C) 2006 Cirrus Logic Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arch-ep93xx/ep93xx.h> + +/* +/* Configure the SDRAM based on the supplied settings. + * + * Input: r0 - SDRAM DEVCFG register + * r2 - configuration for SDRAM chips + * Output: none + * Modifies: r3, r4 + */ +ep93xx_sdram_config: + /* Program the SDRAM device configuration register. */ + ldr r3, =SDRAM_BASE +#ifdef CONFIG_EDB93XX_SDCS0 + str r0, [r3, #SDRAM_OFF_DEVCFG0] +#endif +#ifdef CONFIG_EDB93XX_SDCS1 + str r0, [r3, #SDRAM_OFF_DEVCFG1] +#endif +#ifdef CONFIG_EDB93XX_SDCS2 + str r0, [r3, #SDRAM_OFF_DEVCFG2] +#endif +#ifdef CONFIG_EDB93XX_SDCS3 + str r0, [r3, #SDRAM_OFF_DEVCFG3] +#endif + + /* Set the Initialize and MRS bits (issue continuous NOP commands + * (INIT & MRS set)) + */ + ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \ + EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \ + EP93XX_SDRAMCTRL_GLOBALCFG_CKE) + str r4, [r3, #SDRAM_OFF_GLCONFIG] + + /* Delay for 200us. */ + mov r4, #0x3000 +delay1: + subs r4, r4, #1 + bne delay1 + + /* Clear the MRS bit to issue a precharge all. */ + ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \ + EP93XX_SDRAMCTRL_GLOBALCFG_CKE) + str r4, [r3, #SDRAM_OFF_GLCONFIG] + + /* Temporarily set the refresh timer to 0x10. Make it really low so + * that refresh cycles are generated. + */ + ldr r4, =0x10 + str r4, [r3, #SDRAM_OFF_REFRSHTIMR] + + /* Delay for at least 80 SDRAM clock cycles. */ + mov r4, #80 +delay2: + subs r4, r4, #1 + bne delay2 + + /* Set the refresh timer to the fastest required for any device + * that might be used. Set 9.6 ms refresh time. + */ + ldr r4, =0x01e0 + str r4, [r3, #SDRAM_OFF_REFRSHTIMR] + + /* Select mode register update mode. */ + ldr r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \ + EP93XX_SDRAMCTRL_GLOBALCFG_MRS) + str r4, [r3, #SDRAM_OFF_GLCONFIG] + + /* Program the mode register on the SDRAM by performing fake read */ + ldr r4, [r2] + + /* Select normal operating mode. */ + ldr r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE + str r4, [r3, #SDRAM_OFF_GLCONFIG] + + /* Return to the caller. */ + mov pc, lr + +/* + * Test to see if the SDRAM has been configured in a usable mode. + * + * Input: r0 - Test address of SDRAM + * Output: r0 - 0 -- Test OK, -1 -- Failed + * Modifies: r0-r5 + */ +ep93xx_sdram_test: + /* Load the test patterns to be written to SDRAM. */ + ldr r1, =0xf00dface + ldr r2, =0xdeadbeef + ldr r3, =0x08675309 + ldr r4, =0xdeafc0ed + + /* Store the test patterns to SDRAM. */ + stmia r0, {r1-r4} + + /* Load the test patterns from SDRAM one at a time and compare them + * to the actual pattern. + */ + ldr r5, [r0] + cmp r5, r1 + ldreq r5, [r0, #0x0004] + cmpeq r5, r2 + ldreq r5, [r0, #0x0008] + cmpeq r5, r3 + ldreq r5, [r0, #0x000c] + cmpeq r5, r4 + + /* Return -1 if a mismatch was encountered, 0 otherwise. */ + mvnne r0, #0xffffffff + moveq r0, #0x00000000 + + /* Return to the caller. */ + mov pc, lr + +/* + * Determine the size of the SDRAM. Use data=address for the scan. + * + * Input: r0 - Start SDRAM address + * Return: r0 - Single block size + * r1 - Valid block mask + * r2 - Total block count + * Modifies: r0-r5 + */ +ep93xx_sdram_size: + /* Store zero at offset zero. */ + str r0, [r0] + + /* Start checking for an alias at 1MB into SDRAM. */ + ldr r1, =0x00100000 + + /* Store the offset at the current offset. */ +check_block_size: + str r1, [r0, r1] + + /* Read back from zero. */ + ldr r2, [r0] + + /* Stop searching of an alias was found. */ + cmp r1, r2 + beq found_block_size + + /* Advance to the next power of two boundary. */ + mov r1, r1, lsl #1 + + /* Loop back if the size has not reached 256MB. */ + cmp r1, #0x10000000 + bne check_block_size + + /* A full 256MB of memory was found, so return it now. */ + ldr r0, =0x10000000 + ldr r1, =0x00000000 + ldr r2, =0x00000001 + mov pc, lr + + /* An alias was found. See if the first block is 128MB in size. */ +found_block_size: + cmp r1, #0x08000000 + + /* The first block is 128MB, so there is no further memory. Return it + * now. + */ + ldreq r0, =0x08000000 + ldreq r1, =0x00000000 + ldreq r2, =0x00000001 + moveq pc, lr + + /* Save the block size, set the block address bits to zero, and + * initialize the block count to one. + */ + mov r3, r1 + ldr r4, =0x00000000 + ldr r5, =0x00000001 + + /* Look for additional blocks of memory by searching for non-aliases. */ +find_blocks: + /* Store zero back to address zero. It may be overwritten. */ + str r0, [r0] + + /* Advance to the next power of two boundary. */ + mov r1, r1, lsl #1 + + /* Store the offset at the current offset. */ + str r1, [r0, r1] + + /* Read back from zero. */ + ldr r2, [r0] + + /* See if a non-alias was found. */ + cmp r1, r2 + + /* If a non-alias was found, then or in the block address bit and + * multiply the block count by two (since there are two unique + * blocks, one with this bit zero and one with it one). + */ + orrne r4, r4, r1 + movne r5, r5, lsl #1 + + /* Continue searching if there are more address bits to check. */ + cmp r1, #0x08000000 + bne find_blocks + + /* Return the block size, address mask, and count. */ + mov r0, r3 + mov r1, r4 + mov r2, r5 + + /* Return to the caller. */ + mov pc, lr + + +.globl lowlevel_init +lowlevel_init: + + mov r6, lr + + /* Make sure caches are off and invalidated. */ + ldr r0, =0x00000000 + mcr p15, 0, r0, c1, c0, 0 + nop + nop + nop + nop + nop + + /* Turn off the green LED and turn on the red LED. If the red LED + * is left on for too long, the external reset circuit described + * by application note AN258 will cause the system to reset. + */ + ldr r1, =EP93XX_LED_DATA + ldr r0, [r1] + bic r0, r0, #EP93XX_LED_GREEN_ON + orr r0, r0, #EP93XX_LED_RED_ON + str r0, [r1] + + /* Undo the silly static memory controller programming performed + * by the boot rom. + */ + ldr r0, =SMC_BASE + + /* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */ + ldr r1, =0x0000fbe0 + + /* Reset EP93XX_OFF_SMCBCR0 */ + ldr r2, [r0] + orr r2, r2, r1 + str r2, [r0] + + ldr r2, [r0, #EP93XX_OFF_SMCBCR1] + orr r2, r2, r1 + str r2, [r0, #EP93XX_OFF_SMCBCR1] + + ldr r2, [r0, #EP93XX_OFF_SMCBCR2] + orr r2, r2, r1 + str r2, [r0, #EP93XX_OFF_SMCBCR2] + + ldr r2, [r0, #EP93XX_OFF_SMCBCR3] + orr r2, r2, r1 + str r2, [r0, #EP93XX_OFF_SMCBCR3] + + ldr r2, [r0, #EP93XX_OFF_SMCBCR6] + orr r2, r2, r1 + str r2, [r0, #EP93XX_OFF_SMCBCR6] + + ldr r2, [r0, #EP93XX_OFF_SMCBCR7] + orr r2, r2, r1 + str r2, [r0, #EP93XX_OFF_SMCBCR7] + + /* Set the PLL1 and processor clock. */ + ldr r0, =SYSCON_BASE +#ifdef CONFIG_EDB9301 + /* 332MHz, giving a 166MHz processor clock. */ + ldr r1, = 0x02b49907 +#else + +#ifdef CONFIG_EDB93XX_INDUSTRIAL + /* 384MHz, giving a 196MHz processor clock. */ + ldr r1, =0x02a4bb38 +#else + /* 400MHz, giving a 200MHz processor clock. */ + ldr r1, =0x02a4e39e +#endif +#endif + str r1, [r0, #SYSCON_OFF_CLKSET1] + + nop + nop + nop + nop + nop + + /* Need to make sure that SDRAM is configured correctly before + * coping the code into it. + */ + +#ifdef CONFIG_EDB93XX_SDCS0 + mov r11, #SDRAM_DEVCFG0_BASE +#endif +#ifdef CONFIG_EDB93XX_SDCS1 + mov r11, #SDRAM_DEVCFG1_BASE +#endif +#ifdef CONFIG_EDB93XX_SDCS2 + mov r11, #SDRAM_DEVCFG2_BASE +#endif +#ifdef CONFIG_EDB93XX_SDCS3 + ldr r0, =SYSCON_BASE + ldr r0, [r0, #SYSCON_OFF_SYSCFG] + ands r0, r0, #SYSCON_SYSCFG_LASDO + moveq r11, #SDRAM_DEVCFG3_ASD0_BASE + movne r11, #SDRAM_DEVCFG3_ASD1_BASE +#endif + /* See Table 13-5 in EP93xx datasheet for more info about DRAM + * register mapping */ + + /* Try a 32-bit wide configuration of SDRAM. */ + ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \ + EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \ + EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \ + EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2) + + /* Set burst count: 4 and CAS: 2 + * Burst mode [A11:A10]; CAS [A16:A14] + */ + orr r2, r11, #0x00008800 + bl ep93xx_sdram_config + + /* Test the SDRAM. */ + mov r0, r11 + bl ep93xx_sdram_test + cmp r0, #0x00000000 + beq ep93xx_sdram_done + + /* Try a 16-bit wide configuration of SDRAM. */ + ldr r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \ + EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \ + EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \ + EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \ + EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH) + + /* Set burst count: 8, CAS: 2, sequential burst + * Accoring to Table 13-3 for 16bit operations mapping must be shifted. + * Burst mode [A10:A9]; CAS [A15:A13] + */ + orr r2, r11, #0x00004600 + bl ep93xx_sdram_config + + /* Test the SDRAM. */ + mov r0, r11 + bl ep93xx_sdram_test + cmp r0, #0x00000000 + beq ep93xx_sdram_done + + /* Turn off the red LED. */ + ldr r0, =EP93XX_LED_DATA + ldr r1, [r0] + bic r1, r1, #EP93XX_LED_RED_ON + str r1, [r0] + + /* There is no SDRAM so flash the green LED. */ +flash_green: + orr r1, r1, #EP93XX_LED_GREEN_ON + str r1, [r0] + ldr r2, =0x00010000 +flash_green_delay_1: + subs r2, r2, #1 + bne flash_green_delay_1 + bic r1, r1, #EP93XX_LED_GREEN_ON + str r1, [r0] + ldr r2, =0x00010000 +flash_green_delay_2: + subs r2, r2, #1 + bne flash_green_delay_2 + orr r1, r1, #EP93XX_LED_GREEN_ON + str r1, [r0] + ldr r2, =0x00010000 +flash_green_delay_3: + subs r2, r2, #1 + bne flash_green_delay_3 + bic r1, r1, #EP93XX_LED_GREEN_ON + str r1, [r0] + ldr r2, =0x00050000 +flash_green_delay_4: + subs r2, r2, #1 + bne flash_green_delay_4 + b flash_green + + +ep93xx_sdram_done: + ldr r1, =EP93XX_LED_DATA + ldr r0, [r1] + bic r0, r0, #EP93XX_LED_RED_ON + str r0, [r1] + + /* Determine the size of the SDRAM. */ + mov r0, r11 + bl ep93xx_sdram_size + + /* Save the SDRAM characteristics. */ + mov r8, r0 + mov r9, r1 + mov r10, r2 + + /* Compute total memory size into r1 */ + mul r1, r8, r10 +#ifdef CONFIG_EDB93XX_SDCS0 + ldr r2, [r0, #SDRAM_OFF_DEVCFG0] +#endif +#ifdef CONFIG_EDB93XX_SDCS1 + ldr r2, [r0, #SDRAM_OFF_DEVCFG1] +#endif +#ifdef CONFIG_EDB93XX_SDCS2 + ldr r2, [r0, #SDRAM_OFF_DEVCFG2] +#endif +#ifdef CONFIG_EDB93XX_SDCS3 + ldr r2, [r0, #SDRAM_OFF_DEVCFG3] +#endif + + /* Consider small DRAM size as: + * < 32Mb for 32bit bus + * < 64Mb for 16bit bus + */ + tst r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH + moveq r1, r1, lsr #1 + cmp r1, #0x02000000 + +#if defined(CONFIG_EDB9301) + /* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */ + movlt r1, #0x03f0 + movge r1, #0x01e0 +#else + /* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */ + movlt r1, #0x0600 + movge r1, #0x2f0 +#endif + str r1, [r0, #SDRAM_OFF_REFRSHTIMR] + + /* Save the memory configuration information. */ + orr r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE + stmia r0, {r8-r11} + + mov lr, r6 + mov pc, lr
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/speed.c b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/speed.c new file mode 100644 index 0000000..9dc60b6 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/speed.c
@@ -0,0 +1,96 @@ +/* + * Cirrus Logic EP93xx PLL support. + * + * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <div64.h> + +/* + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ + +/* + * return the PLL output frequency + * + * PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1) + * / (X2IPD + 1) / 2^PS + */ +static ulong get_PLLCLK(uint32_t *pllreg) +{ + uint8_t i; + const uint32_t clkset = readl(pllreg); + uint64_t rate = CONFIG_SYS_CLK_FREQ; + rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1; + rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1; + do_div(rate, (clkset & 0x1f) + 1); /* X2IPD */ + for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++) + rate >>= 1; + + return (ulong)rate; +} + +/* return FCLK frequency */ +ulong get_FCLK() +{ + const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t fclk_div = + fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7]; + const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div; + + return fclk_rate; +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t hclk_div = + hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7]; + const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div; + + return hclk_rate; +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + const uint8_t pclk_divisors[] = { 1, 2, 4, 8 }; + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + + const uint32_t clkset1 = readl(&syscon->clkset1); + const uint8_t pclk_div = + pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3]; + const ulong pclk_rate = get_HCLK() / pclk_div; + + return pclk_rate; +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE; + ulong uclk_rate; + + const uint32_t value = readl(&syscon->pwrcnt); + if (value & SYSCON_PWRCNT_UART_BAUD) + uclk_rate = CONFIG_SYS_CLK_FREQ; + else + uclk_rate = CONFIG_SYS_CLK_FREQ / 2; + + return uclk_rate; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/timer.c b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/timer.c new file mode 100644 index 0000000..c2f239a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/ep93xx/timer.c
@@ -0,0 +1,120 @@ +/* + * Cirrus Logic EP93xx timer support. + * + * Copyright (C) 2009, 2010 Matthias Kaehlcke <matthias@kaehlcke.net> + * + * Copyright (C) 2004, 2005 + * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> + * + * Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support, + * author unknown. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/types.h> +#include <asm/arch/ep93xx.h> +#include <asm/io.h> +#include <div64.h> + +#define TIMER_CLKSEL (1 << 3) +#define TIMER_ENABLE (1 << 7) + +#define TIMER_FREQ 508469 /* ticks / second */ +#define TIMER_MAX_VAL 0xFFFFFFFF + +static struct ep93xx_timer +{ + unsigned long long ticks; + unsigned long last_read; +} timer; + +static inline unsigned long long usecs_to_ticks(unsigned long usecs) +{ + unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ; + do_div(ticks, 1000 * 1000); + + return ticks; +} + +static inline void read_timer(void) +{ + struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; + const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value); + + if (now >= timer.last_read) + timer.ticks += now - timer.last_read; + else + /* an overflow occurred */ + timer.ticks += TIMER_MAX_VAL - timer.last_read + now; + + timer.last_read = now; +} + +/* + * Get the number of ticks (in CONFIG_SYS_HZ resolution) + */ +unsigned long long get_ticks(void) +{ + unsigned long long sys_ticks; + + read_timer(); + + sys_ticks = timer.ticks * CONFIG_SYS_HZ; + do_div(sys_ticks, TIMER_FREQ); + + return sys_ticks; +} + +unsigned long get_timer_masked(void) +{ + return get_ticks(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void __udelay(unsigned long usec) +{ + unsigned long long target; + + read_timer(); + + target = timer.ticks + usecs_to_ticks(usec); + + while (timer.ticks < target) + read_timer(); +} + +int timer_init(void) +{ + struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE; + + /* use timer 3 with 508KHz and free running, not enabled now */ + writel(TIMER_CLKSEL, &timer_regs->timer3.control); + + /* set initial timer value */ + writel(TIMER_MAX_VAL, &timer_regs->timer3.load); + + /* Enable the timer */ + writel(TIMER_ENABLE | TIMER_CLKSEL, + &timer_regs->timer3.control); + + /* Reset the timer */ + read_timer(); + timer.ticks = 0; + + return 0; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/imx/Makefile b/u-boot-imx/arch/arm/cpu/arm920t/imx/Makefile new file mode 100644 index 0000000..54ce646 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/imx/Makefile
@@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += generic.o +obj-y += speed.o +obj-y += timer.o
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/imx/generic.c b/u-boot-imx/arch/arm/cpu/arm920t/imx/generic.c new file mode 100644 index 0000000..1441ab4 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/imx/generic.c
@@ -0,0 +1,77 @@ +/* + * arch/arm/mach-imx/generic.c + * + * author: Sascha Hauer + * Created: april 20th, 2004 + * Copyright: Synertronixx GmbH + * + * Common code for i.MX machines + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#ifdef CONFIG_IMX + +#include <asm/arch/imx-regs.h> + +void imx_gpio_mode(int gpio_mode) +{ + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10; + unsigned int tmp; + + /* Pullup enable */ + if(gpio_mode & GPIO_PUEN) + PUEN(port) |= (1<<pin); + else + PUEN(port) &= ~(1<<pin); + + /* Data direction */ + if(gpio_mode & GPIO_OUT) + DDIR(port) |= 1<<pin; + else + DDIR(port) &= ~(1<<pin); + + /* Primary / alternate function */ + if(gpio_mode & GPIO_AF) + GPR(port) |= (1<<pin); + else + GPR(port) &= ~(1<<pin); + + /* use as gpio? */ + if( ocr == 3 ) + GIUS(port) |= (1<<pin); + else + GIUS(port) &= ~(1<<pin); + + /* Output / input configuration */ + /* FIXME: I'm not very sure about OCR and ICONF, someone + * should have a look over it + */ + if(pin<16) { + tmp = OCR1(port); + tmp &= ~( 3<<(pin*2)); + tmp |= (ocr << (pin*2)); + OCR1(port) = tmp; + + if( gpio_mode & GPIO_AOUT ) + ICONFA1(port) &= ~( 3<<(pin*2)); + if( gpio_mode & GPIO_BOUT ) + ICONFB1(port) &= ~( 3<<(pin*2)); + } else { + tmp = OCR2(port); + tmp &= ~( 3<<((pin-16)*2)); + tmp |= (ocr << ((pin-16)*2)); + OCR2(port) = tmp; + + if( gpio_mode & GPIO_AOUT ) + ICONFA2(port) &= ~( 3<<((pin-16)*2)); + if( gpio_mode & GPIO_BOUT ) + ICONFB2(port) &= ~( 3<<((pin-16)*2)); + } +} + +#endif /* CONFIG_IMX */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/imx/speed.c b/u-boot-imx/arch/arm/cpu/arm920t/imx/speed.c new file mode 100644 index 0000000..1951313 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/imx/speed.c
@@ -0,0 +1,86 @@ +/* + * + * (c) 2004 Sascha Hauer <sascha@saschahauer.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <common.h> +#if defined (CONFIG_IMX) + +#include <asm/arch/imx-regs.h> + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * SH FIXME: 16780000 in our case + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +ulong get_systemPLLCLK(void) +{ + /* FIXME: We assume System_SEL = 0 here */ + u32 spctl0 = SPCTL0; + u32 mfi = (spctl0 >> 10) & 0xf; + u32 mfn = spctl0 & 0x3f; + u32 mfd = (spctl0 >> 16) & 0x3f; + u32 pd = (spctl0 >> 26) & 0xf; + + mfi = mfi<=5 ? 5 : mfi; + + return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_mcuPLLCLK(void) +{ + /* FIXME: We assume System_SEL = 0 here */ + u32 mpctl0 = MPCTL0; + u32 mfi = (mpctl0 >> 10) & 0xf; + u32 mfn = mpctl0 & 0x3f; + u32 mfd = (mpctl0 >> 16) & 0x3f; + u32 pd = (mpctl0 >> 26) & 0xf; + + mfi = mfi<=5 ? 5 : mfi; + + return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1); +} + +ulong get_FCLK(void) +{ + return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK(); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1; + printf("bclkdiv: %d\n", bclkdiv); + return get_systemPLLCLK() / bclkdiv; +} + +/* return BCLK frequency */ +ulong get_BCLK(void) +{ + return get_HCLK(); +} + +ulong get_PERCLK1(void) +{ + return get_systemPLLCLK() / (((PCDR) & 0xf)+1); +} + +ulong get_PERCLK2(void) +{ + return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1); +} + +ulong get_PERCLK3(void) +{ + return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1); +} + +#endif /* defined (CONFIG_IMX) */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/imx/timer.c b/u-boot-imx/arch/arm/cpu/arm920t/imx/timer.c new file mode 100644 index 0000000..b62558f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/imx/timer.c
@@ -0,0 +1,107 @@ +/* + * (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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#if defined (CONFIG_IMX) + +#include <asm/arch/imx-regs.h> + +int timer_init (void) +{ + int i; + /* setup GP Timer 1 */ + TCTL1 = TCTL_SWR; + for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ + TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ + TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ + + /* Reset the timer */ + TCTL1 &= ~TCTL_TEN; + TCTL1 |= TCTL_TEN; /* Enable timer */ + + return (0); +} + +/* + * timer without interrupts + */ +ulong get_timer (ulong base) +{ + return get_timer_masked() - base; +} + +ulong get_timer_masked (void) +{ + return TCN1; +} + +void udelay_masked (unsigned long usec) +{ + ulong endtime = get_timer_masked() + usec; + signed long diff; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +void __udelay (unsigned long usec) +{ + udelay_masked(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + + return tbclk; +} + +/* + * Reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu (ulong ignored) +{ + /* Disable watchdog and set Time-Out field to 0 */ + WCR = 0x00000000; + + /* Write Service Sequence */ + WSR = 0x00005555; + WSR = 0x0000AAAA; + + /* Enable watchdog */ + WCR = 0x00000001; + + while (1); + /*NOTREACHED*/ +} + +#endif /* defined (CONFIG_IMX) */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/interrupts.c b/u-boot-imx/arch/arm/cpu/arm920t/interrupts.c new file mode 100644 index 0000000..0e04d36 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/interrupts.c
@@ -0,0 +1,27 @@ +/* + * (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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/proc-armv/ptrace.h> + +#if defined (CONFIG_ARCH_INTEGRATOR) +void do_irq (struct pt_regs *pt_regs) +{ + /* ASSUMED to be a timer interrupt */ + /* Just clear it - count handled in */ + /* integratorap.c */ + *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x0C) = 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/Makefile b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/Makefile new file mode 100644 index 0000000..e44c549 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/Makefile
@@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_USE_IRQ) += interrupts.o +obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o +obj-y += speed.o +obj-y += timer.o
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c new file mode 100644 index 0000000..fede51a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/cpu_info.c
@@ -0,0 +1,38 @@ +/* + * (C) Copyright 2010 + * David Mueller <d.mueller@elsoft.ch> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +typedef ulong (*getfreq)(void); + +static const getfreq freq_f[] = { + get_FCLK, + get_HCLK, + get_PCLK, +}; + +static const char freq_c[] = { 'F', 'H', 'P' }; + +int print_cpuinfo(void) +{ + int i; + char buf[32]; +/* the S3C2400 seems to be lacking a CHIP ID register */ +#ifndef CONFIG_S3C2400 + ulong cpuid; + struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio(); + + cpuid = readl(&gpio->gstatus1); + printf("CPUID: %8lX\n", cpuid); +#endif + for (i = 0; i < ARRAY_SIZE(freq_f); i++) + printf("%cCLK: %8s MHz\n", freq_c[i], strmhz(buf, freq_f[i]())); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/interrupts.c b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/interrupts.c new file mode 100644 index 0000000..036e3b9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/interrupts.c
@@ -0,0 +1,26 @@ +/* + * (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> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#include <asm/arch/s3c24x0_cpu.h> +#include <asm/proc-armv/ptrace.h> + +void do_irq (struct pt_regs *pt_regs) +{ + struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt(); + u_int32_t intpnd = readl(&irq->INTPND); + +}
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/speed.c b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/speed.c new file mode 100644 index 0000000..3701c5d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/speed.c
@@ -0,0 +1,102 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include <common.h> +#ifdef CONFIG_S3C24X0 + +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +#define MPLL 0 +#define UPLL 1 + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + ulong r, m, p, s; + + if (pllreg == MPLL) + r = readl(&clk_power->mpllcon); + else if (pllreg == UPLL) + r = readl(&clk_power->upllcon); + else + hang(); + + m = ((r & 0xFF000) >> 12) + 8; + p = ((r & 0x003F0) >> 4) + 2; + s = r & 0x3; + +#if defined(CONFIG_S3C2440) + if (pllreg == MPLL) + return 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s)); +#endif + return (CONFIG_SYS_CLK_FREQ * m) / (p << s); + +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(MPLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); +#ifdef CONFIG_S3C2440 + switch (readl(&clk_power->clkdivn) & 0x6) { + default: + case 0: + return get_FCLK(); + case 2: + return get_FCLK() / 2; + case 4: + return (readl(&clk_power->camdivn) & (1 << 9)) ? + get_FCLK() / 8 : get_FCLK() / 4; + case 6: + return (readl(&clk_power->camdivn) & (1 << 8)) ? + get_FCLK() / 6 : get_FCLK() / 3; + } +#else + return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK(); +#endif +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); + + return (readl(&clk_power->clkdivn) & 1) ? get_HCLK() / 2 : get_HCLK(); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(UPLL); +} + +#endif /* CONFIG_S3C24X0 */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/timer.c b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/timer.c new file mode 100644 index 0000000..ba1e616 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/s3c24x0/timer.c
@@ -0,0 +1,160 @@ +/* + * (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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#ifdef CONFIG_S3C24X0 + +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +DECLARE_GLOBAL_DATA_PTR; + +int timer_init(void) +{ + struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); + ulong tmr; + + /* use PWM Timer 4 because it has no output */ + /* prescaler for Timer 4 is 16 */ + writel(0x0f00, &timers->tcfg0); + if (gd->arch.tbu == 0) { + /* + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 + * (default) and prescaler = 16. Should be 10390 + * @33.25MHz and 15625 @ 50 MHz + */ + gd->arch.tbu = get_PCLK() / (2 * 16 * 100); + gd->arch.timer_rate_hz = get_PCLK() / (2 * 16); + } + /* load value for 10 ms timeout */ + writel(gd->arch.tbu, &timers->tcntb4); + /* auto load, manual update of timer 4 */ + tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000; + writel(tmr, &timers->tcon); + /* auto load, start timer 4 */ + tmr = (tmr & ~0x0700000) | 0x0500000; + writel(tmr, &timers->tcon); + gd->arch.lastinc = 0; + gd->arch.tbl = 0; + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void __udelay (unsigned long usec) +{ + ulong tmo; + ulong start = get_ticks(); + + tmo = usec / 1000; + tmo *= (gd->arch.tbu * 100); + tmo /= 1000; + + while ((ulong) (get_ticks() - start) < tmo) + /*NOP*/; +} + +ulong get_timer_masked(void) +{ + ulong tmr = get_ticks(); + + return tmr / (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); +} + +void udelay_masked(unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= (gd->arch.tbu * 100); + tmo /= 1000; + } else { + tmo = usec * (gd->arch.tbu * 100); + tmo /= (1000 * 1000); + } + + endtime = get_ticks() + tmo; + + do { + ulong now = get_ticks(); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + struct s3c24x0_timers *timers = s3c24x0_get_base_timers(); + ulong now = readl(&timers->tcnto4) & 0xffff; + + if (gd->arch.lastinc >= now) { + /* normal mode */ + gd->arch.tbl += gd->arch.lastinc - now; + } else { + /* we have an overflow ... */ + gd->arch.tbl += gd->arch.lastinc + gd->arch.tbu - now; + } + gd->arch.lastinc = now; + + return gd->arch.tbl; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} + +/* + * reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu(ulong ignored) +{ + struct s3c24x0_watchdog *watchdog; + + watchdog = s3c24x0_get_base_watchdog(); + + /* Disable watchdog */ + writel(0x0000, &watchdog->wtcon); + + /* Initialize watchdog timer count register */ + writel(0x0001, &watchdog->wtcnt); + + /* Enable watchdog timer; assert reset at timer timeout */ + writel(0x0021, &watchdog->wtcon); + + while (1) + /* loop forever and wait for reset to happen */; + + /*NOTREACHED*/ +} + +#endif /* CONFIG_S3C24X0 */
diff --git a/u-boot-imx/arch/arm/cpu/arm920t/start.S b/u-boot-imx/arch/arm/cpu/arm920t/start.S new file mode 100644 index 0000000..0740450 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm920t/start.S
@@ -0,0 +1,149 @@ +/* + * armboot - Startup Code for ARM920 CPU-core + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <common.h> +#include <config.h> + +/* + ************************************************************************* + * + * Startup Code (called from the ARM reset exception vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0xd3 + msr cpsr, r0 + +#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) + /* + * relocate exception table + */ + ldr r0, =_start + ldr r1, =0x0 + mov r2, #16 +copyex: + subs r2, r2, #1 + ldr r3, [r0], #4 + str r3, [r1], #4 + bne copyex +#endif + +#ifdef CONFIG_S3C24X0 + /* turn off the watchdog */ + +# if defined(CONFIG_S3C2400) +# define pWTCON 0x15300000 +# define INTMSK 0x14400008 /* Interrupt-Controller base addresses */ +# define CLKDIVN 0x14800014 /* clock divisor register */ +#else +# define pWTCON 0x53000000 +# define INTMSK 0x4A000008 /* Interrupt-Controller base addresses */ +# define INTSUBMSK 0x4A00001C +# define CLKDIVN 0x4C000014 /* clock divisor register */ +# endif + + ldr r0, =pWTCON + mov r1, #0x0 + str r1, [r0] + + /* + * mask all IRQs by setting all bits in the INTMR - default + */ + mov r1, #0xffffffff + ldr r0, =INTMSK + str r1, [r0] +# if defined(CONFIG_S3C2410) + ldr r1, =0x3ff + ldr r0, =INTSUBMSK + str r1, [r0] +# endif + + /* FCLK:HCLK:PCLK = 1:2:4 */ + /* default FCLK is 120 MHz ! */ + ldr r0, =CLKDIVN + mov r1, #3 + str r1, [r0] +#endif /* CONFIG_S3C24X0 */ + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + mov pc, lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +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 + + /* + * before relocating, we have to setup RAM timing + * because memory timing is board-dependend, you will + * find a lowlevel_init.S in your board directory. + */ + mov ip, lr + + bl lowlevel_init + + mov lr, ip + mov pc, lr +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/Makefile new file mode 100644 index 0000000..63fa159 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/Makefile
@@ -0,0 +1,22 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +obj-y = cpu.o cache.o + +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_NO_CPU_SUPPORT_CODE +extra-y := +endif +endif + +obj-$(CONFIG_ARMADA100) += armada100/ +obj-$(if $(filter lpc32xx,$(SOC)),y) += lpc32xx/ +obj-$(CONFIG_MX25) += mx25/ +obj-$(CONFIG_MX27) += mx27/ +obj-$(if $(filter mxs,$(SOC)),y) += mxs/ +obj-$(if $(filter spear,$(SOC)),y) += spear/
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/Makefile new file mode 100644 index 0000000..fca98ef --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/Makefile
@@ -0,0 +1,9 @@ +# +# (C) Copyright 2010 +# Marvell Semiconductor <www.marvell.com> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o timer.o dram.o
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/cpu.c b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/cpu.c new file mode 100644 index 0000000..8b02d0b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -0,0 +1,92 @@ +/* + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * Contributor: Mahavir Jain <mjain@marvell.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/armada100.h> + +#define UARTCLK14745KHZ (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1)) +#define SET_MRVL_ID (1<<8) +#define L2C_RAM_SEL (1<<4) + +int arch_cpu_init(void) +{ + u32 val; + struct armd1cpu_registers *cpuregs = + (struct armd1cpu_registers *) ARMD1_CPU_BASE; + + struct armd1apb1_registers *apb1clkres = + (struct armd1apb1_registers *) ARMD1_APBC1_BASE; + + struct armd1mpmu_registers *mpmu = + (struct armd1mpmu_registers *) ARMD1_MPMU_BASE; + + /* set SEL_MRVL_ID bit in ARMADA100_CPU_CONF register */ + val = readl(&cpuregs->cpu_conf); + val = val | SET_MRVL_ID; + writel(val, &cpuregs->cpu_conf); + + /* Enable Clocks for all hardware units */ + writel(0xFFFFFFFF, &mpmu->acgr); + + /* Turn on AIB and AIB-APB Functional clock */ + writel(APBC_APBCLK | APBC_FNCLK, &apb1clkres->aib); + + /* ensure L2 cache is not mapped as SRAM */ + val = readl(&cpuregs->cpu_conf); + val = val & ~(L2C_RAM_SEL); + writel(val, &cpuregs->cpu_conf); + + /* Enable GPIO clock */ + writel(APBC_APBCLK, &apb1clkres->gpio); + +#ifdef CONFIG_I2C_MV + /* Enable general I2C clock */ + writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0); + writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0); + + /* Enable power I2C clock */ + writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1); + writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1); +#endif + + /* + * Enable Functional and APB clock at 14.7456MHz + * for configured UART console + */ +#if (CONFIG_SYS_NS16550_COM1 == ARMD1_UART3_BASE) + writel(UARTCLK14745KHZ, &apb1clkres->uart3); +#elif (CONFIG_SYS_NS16550_COM1 == ARMD1_UART2_BASE) + writel(UARTCLK14745KHZ, &apb1clkres->uart2); +#else + writel(UARTCLK14745KHZ, &apb1clkres->uart1); +#endif + icache_enable(); + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u32 id; + struct armd1cpu_registers *cpuregs = + (struct armd1cpu_registers *) ARMD1_CPU_BASE; + + id = readl(&cpuregs->chip_id); + printf("SoC: Armada 88AP%X-%X\n", (id & 0xFFF), (id >> 0x10)); + return 0; +} +#endif + +#ifdef CONFIG_I2C_MV +void i2c_clk_enable(void) +{ +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/dram.c b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/dram.c new file mode 100644 index 0000000..8d7c71f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/dram.c
@@ -0,0 +1,116 @@ +/* + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com>, + * Contributor: Mahavir Jain <mjain@marvell.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/armada100.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * ARMADA100 DRAM controller supports upto 8 banks + * for chip select 0 and 1 + */ + +/* + * DDR Memory Control Registers + * Refer Datasheet Appendix A.17 + */ +struct armd1ddr_map_registers { + u32 cs; /* Memory Address Map Register -CS */ + u32 pad[3]; +}; + +struct armd1ddr_registers { + u8 pad[0x100 - 0x000]; + struct armd1ddr_map_registers mmap[2]; +}; + +/* + * armd1_sdram_base - reads SDRAM Base Address Register + */ +u32 armd1_sdram_base(int chip_sel) +{ + struct armd1ddr_registers *ddr_regs = + (struct armd1ddr_registers *)ARMD1_DRAM_BASE; + u32 result = 0; + u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); + + if (!CS_valid) + return 0; + + result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000; + return result; +} + +/* + * armd1_sdram_size - reads SDRAM size + */ +u32 armd1_sdram_size(int chip_sel) +{ + struct armd1ddr_registers *ddr_regs = + (struct armd1ddr_registers *)ARMD1_DRAM_BASE; + u32 result = 0; + u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs); + + if (!CS_valid) + return 0; + + result = readl(&ddr_regs->mmap[chip_sel].cs); + result = (result >> 16) & 0xF; + if (result < 0x7) { + printf("Unknown DRAM Size\n"); + return -1; + } else { + return ((0x8 << (result - 0x7)) * 1024 * 1024); + } +} + +#ifndef CONFIG_SYS_BOARD_DRAM_INIT +int dram_init(void) +{ + int i; + + gd->ram_size = 0; + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = armd1_sdram_base(i); + gd->bd->bi_dram[i].size = armd1_sdram_size(i); + /* + * It is assumed that all memory banks are consecutive + * and without gaps. + * If the gap is found, ram_size will be reported for + * consecutive memory only + */ + if (gd->bd->bi_dram[i].start != gd->ram_size) + break; + + gd->ram_size += gd->bd->bi_dram[i].size; + + } + + for (; i < CONFIG_NR_DRAM_BANKS; i++) { + /* If above loop terminated prematurely, we need to set + * remaining banks' start address & size as 0. Otherwise other + * u-boot functions and Linux kernel gets wrong values which + * could result in crash */ + gd->bd->bi_dram[i].start = 0; + gd->bd->bi_dram[i].size = 0; + } + return 0; +} + +/* + * If this function is not defined here, + * board.c alters dram bank zero configuration defined above. + */ +void dram_init_banksize(void) +{ + dram_init(); +} +#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/timer.c new file mode 100644 index 0000000..bbd0505 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/armada100/timer.c
@@ -0,0 +1,194 @@ +/* + * (C) Copyright 2010 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * Contributor: Mahavir Jain <mjain@marvell.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/armada100.h> + +/* + * Timer registers + * Refer Section A.6 in Datasheet + */ +struct armd1tmr_registers { + u32 clk_ctrl; /* Timer clk control reg */ + u32 match[9]; /* Timer match registers */ + u32 count[3]; /* Timer count registers */ + u32 status[3]; + u32 ie[3]; + u32 preload[3]; /* Timer preload value */ + u32 preload_ctrl[3]; + u32 wdt_match_en; + u32 wdt_match_r; + u32 wdt_val; + u32 wdt_sts; + u32 icr[3]; + u32 wdt_icr; + u32 cer; /* Timer count enable reg */ + u32 cmr; + u32 ilr[3]; + u32 wcr; + u32 wfar; + u32 wsar; + u32 cvwr; +}; + +#define TIMER 0 /* Use TIMER 0 */ +/* Each timer has 3 match registers */ +#define MATCH_CMP(x) ((3 * TIMER) + x) +#define TIMER_LOAD_VAL 0xffffffff +#define COUNT_RD_REQ 0x1 + +DECLARE_GLOBAL_DATA_PTR; +/* Using gd->arch.tbu from timestamp and gd->arch.tbl for lastdec */ + +/* For preventing risk of instability in reading counter value, + * first set read request to register cvwr and then read same + * register after it captures counter value. + */ +ulong read_timer(void) +{ + struct armd1tmr_registers *armd1timers = + (struct armd1tmr_registers *) ARMD1_TIMER_BASE; + volatile int loop=100; + + writel(COUNT_RD_REQ, &armd1timers->cvwr); + while (loop--); + return(readl(&armd1timers->cvwr)); +} + +ulong get_timer_masked(void) +{ + ulong now = read_timer(); + + if (now >= gd->arch.tbl) { + /* normal mode */ + gd->arch.tbu += now - gd->arch.tbl; + } else { + /* we have an overflow ... */ + gd->arch.tbu += now + TIMER_LOAD_VAL - gd->arch.tbl; + } + gd->arch.tbl = now; + + return gd->arch.tbu; +} + +ulong get_timer(ulong base) +{ + return ((get_timer_masked() / (CONFIG_SYS_HZ_CLOCK / 1000)) - + base); +} + +void __udelay(unsigned long usec) +{ + ulong delayticks; + ulong endtime; + + delayticks = (usec * (CONFIG_SYS_HZ_CLOCK / 1000000)); + endtime = get_timer_masked() + delayticks; + + while (get_timer_masked() < endtime); +} + +/* + * init the Timer + */ +int timer_init(void) +{ + struct armd1apb1_registers *apb1clkres = + (struct armd1apb1_registers *) ARMD1_APBC1_BASE; + struct armd1tmr_registers *armd1timers = + (struct armd1tmr_registers *) ARMD1_TIMER_BASE; + + /* Enable Timer clock at 3.25 MHZ */ + writel(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3), &apb1clkres->timers); + + /* load value into timer */ + writel(0x0, &armd1timers->clk_ctrl); + /* Use Timer 0 Match Resiger 0 */ + writel(TIMER_LOAD_VAL, &armd1timers->match[MATCH_CMP(0)]); + /* Preload value is 0 */ + writel(0x0, &armd1timers->preload[TIMER]); + /* Enable match comparator 0 for Timer 0 */ + writel(0x1, &armd1timers->preload_ctrl[TIMER]); + + /* Enable timer 0 */ + writel(0x1, &armd1timers->cer); + /* init the gd->arch.tbu and gd->arch.tbl value */ + gd->arch.tbl = read_timer(); + gd->arch.tbu = 0; + + return 0; +} + +#define MPMU_APRR_WDTR (1<<4) +#define TMR_WFAR 0xbaba /* WDT Register First key */ +#define TMP_WSAR 0xeb10 /* WDT Register Second key */ + +/* + * This function uses internal Watchdog Timer + * based reset mechanism. + * Steps to write watchdog registers (protected access) + * 1. Write key value to TMR_WFAR reg. + * 2. Write key value to TMP_WSAR reg. + * 3. Perform write operation. + */ +void reset_cpu (unsigned long ignored) +{ + struct armd1mpmu_registers *mpmu = + (struct armd1mpmu_registers *) ARMD1_MPMU_BASE; + struct armd1tmr_registers *armd1timers = + (struct armd1tmr_registers *) ARMD1_TIMER_BASE; + u32 val; + + /* negate hardware reset to the WDT after system reset */ + val = readl(&mpmu->aprr); + val = val | MPMU_APRR_WDTR; + writel(val, &mpmu->aprr); + + /* reset/enable WDT clock */ + writel(APBC_APBCLK | APBC_FNCLK | APBC_RST, &mpmu->wdtpcr); + readl(&mpmu->wdtpcr); + writel(APBC_APBCLK | APBC_FNCLK, &mpmu->wdtpcr); + readl(&mpmu->wdtpcr); + + /* clear previous WDT status */ + writel(TMR_WFAR, &armd1timers->wfar); + writel(TMP_WSAR, &armd1timers->wsar); + writel(0, &armd1timers->wdt_sts); + + /* set match counter */ + writel(TMR_WFAR, &armd1timers->wfar); + writel(TMP_WSAR, &armd1timers->wsar); + writel(0xf, &armd1timers->wdt_match_r); + + /* enable WDT reset */ + writel(TMR_WFAR, &armd1timers->wfar); + writel(TMP_WSAR, &armd1timers->wsar); + writel(0x3, &armd1timers->wdt_match_en); + + while(1); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return (ulong)CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/cache.c b/u-boot-imx/arch/arm/cpu/arm926ejs/cache.c new file mode 100644 index 0000000..8d7873c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/cache.c
@@ -0,0 +1,102 @@ +/* + * (C) Copyright 2011 + * Ilya Yanok, EmCraft Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <linux/types.h> +#include <common.h> + +#ifndef CONFIG_SYS_DCACHE_OFF + +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 32 +#endif + +void invalidate_dcache_all(void) +{ + asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0)); +} + +void flush_dcache_all(void) +{ + asm volatile( + "0:" + "mrc p15, 0, r15, c7, c14, 3\n" + "bne 0b\n" + "mcr p15, 0, %0, c7, c10, 4\n" + : : "r"(0) : "memory" + ); +} + +static int check_cache_range(unsigned long start, unsigned long stop) +{ + int ok = 1; + + if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (!ok) + debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", + start, stop); + + return ok; +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ + if (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ + if (!check_cache_range(start, stop)) + return; + + while (start < stop) { + asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start)); + start += CONFIG_SYS_CACHELINE_SIZE; + } + + asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0)); +} + +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} +#else /* #ifndef CONFIG_SYS_DCACHE_OFF */ +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_cache(unsigned long start, unsigned long size) +{ +} +#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ + +/* + * Stub implementations for l2 cache operations + */ +__weak void l2_cache_disable(void) {}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/cpu.c b/u-boot-imx/arch/arm/cpu/arm926ejs/cpu.c new file mode 100644 index 0000000..a90ce30 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/cpu.c
@@ -0,0 +1,53 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + l2_cache_disable(); + + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ +#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); +#endif +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/Makefile new file mode 100644 index 0000000..4837377 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/Makefile
@@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o clk.o devices.o timer.o + +obj-$(CONFIG_SPL_BUILD) += dram.o lowlevel_init.o
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/clk.c b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/clk.c new file mode 100644 index 0000000..1ef8a36 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/clk.c
@@ -0,0 +1,138 @@ +/* + * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/io.h> + +static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; + +unsigned int get_sys_clk_rate(void) +{ + if (readl(&clk->sysclk_ctrl) & CLK_SYSCLK_PLL397) + return RTC_CLK_FREQUENCY * 397; + else + return OSC_CLK_FREQUENCY; +} + +unsigned int get_hclk_pll_rate(void) +{ + unsigned long long fin, fref, fcco, fout; + u32 val, m_div, n_div, p_div; + + /* + * Valid frequency ranges: + * 1 * 10^6 <= Fin <= 20 * 10^6 + * 1 * 10^6 <= Fref <= 27 * 10^6 + * 156 * 10^6 <= Fcco <= 320 * 10^6 + */ + + fref = fin = get_sys_clk_rate(); + if (fin > 20000000ULL || fin < 1000000ULL) + return 0; + + val = readl(&clk->hclkpll_ctrl); + m_div = ((val & CLK_HCLK_PLL_FEEDBACK_DIV_MASK) >> 1) + 1; + n_div = ((val & CLK_HCLK_PLL_PREDIV_MASK) >> 9) + 1; + if (val & CLK_HCLK_PLL_DIRECT) + p_div = 0; + else + p_div = ((val & CLK_HCLK_PLL_POSTDIV_MASK) >> 11) + 1; + p_div = 1 << p_div; + + if (val & CLK_HCLK_PLL_BYPASS) { + do_div(fin, p_div); + return fin; + } + + do_div(fref, n_div); + if (fref > 27000000ULL || fref < 1000000ULL) + return 0; + + fout = fref * m_div; + if (val & CLK_HCLK_PLL_FEEDBACK) { + fcco = fout; + do_div(fout, p_div); + } else + fcco = fout * p_div; + + if (fcco > 320000000ULL || fcco < 156000000ULL) + return 0; + + return fout; +} + +unsigned int get_hclk_clk_div(void) +{ + u32 val; + + val = readl(&clk->hclkdiv_ctrl) & CLK_HCLK_ARM_PLL_DIV_MASK; + + return 1 << val; +} + +unsigned int get_hclk_clk_rate(void) +{ + return get_hclk_pll_rate() / get_hclk_clk_div(); +} + +unsigned int get_periph_clk_div(void) +{ + u32 val; + + val = readl(&clk->hclkdiv_ctrl) & CLK_HCLK_PERIPH_DIV_MASK; + + return (val >> 2) + 1; +} + +unsigned int get_periph_clk_rate(void) +{ + if (!(readl(&clk->pwr_ctrl) & CLK_PWR_NORMAL_RUN)) + return get_sys_clk_rate(); + + return get_hclk_pll_rate() / get_periph_clk_div(); +} + +unsigned int get_sdram_clk_rate(void) +{ + unsigned int src_clk; + + if (!(readl(&clk->pwr_ctrl) & CLK_PWR_NORMAL_RUN)) + return get_sys_clk_rate(); + + src_clk = get_hclk_pll_rate(); + + if (readl(&clk->sdramclk_ctrl) & CLK_SDRAM_DDR_SEL) { + /* using DDR */ + switch (readl(&clk->hclkdiv_ctrl) & CLK_HCLK_DDRAM_MASK) { + case CLK_HCLK_DDRAM_HALF: + return src_clk/2; + case CLK_HCLK_DDRAM_NOMINAL: + return src_clk; + default: + return 0; + } + } else { + /* using SDR */ + switch (readl(&clk->hclkdiv_ctrl) & CLK_HCLK_ARM_PLL_DIV_MASK) { + case CLK_HCLK_ARM_PLL_DIV_4: + return src_clk/4; + case CLK_HCLK_ARM_PLL_DIV_2: + return src_clk/2; + case CLK_HCLK_ARM_PLL_DIV_1: + return src_clk; + default: + return 0; + } + } +} + +int get_serial_clock(void) +{ + return get_periph_clk_rate(); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c new file mode 100644 index 0000000..f757474 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/cpu.c
@@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/wdt.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; +static struct wdt_regs *wdt = (struct wdt_regs *)WDT_BASE; + +void reset_cpu(ulong addr) +{ + /* Enable watchdog clock */ + setbits_le32(&clk->timclk_ctrl, CLK_TIMCLK_WATCHDOG); + + /* Reset pulse length is 13005 peripheral clock frames */ + writel(13000, &wdt->pulse); + + /* Force WDOG_RESET2 and RESOUT_N signal active */ + writel(WDTIM_MCTRL_RESFRC2 | WDTIM_MCTRL_RESFRC1 | WDTIM_MCTRL_M_RES2, + &wdt->mctrl); + + while (1) + /* NOP */; +} + +#if defined(CONFIG_ARCH_CPU_INIT) +int arch_cpu_init(void) +{ + /* + * It might be necessary to flush data cache, if U-boot is loaded + * from kickstart bootloader, e.g. from S1L loader + */ + flush_dcache_all(); + + return 0; +} +#else +#error "You have to select CONFIG_ARCH_CPU_INIT" +#endif + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + printf("CPU: NXP LPC32XX\n"); + printf("CPU clock: %uMHz\n", get_hclk_pll_rate() / 1000000); + printf("AHB bus clock: %uMHz\n", get_hclk_clk_rate() / 1000000); + printf("Peripheral clock: %uMHz\n", get_periph_clk_rate() / 1000000); + + return 0; +} +#endif + +#ifdef CONFIG_LPC32XX_ETH +int cpu_eth_init(bd_t *bis) +{ + lpc32xx_eth_initialize(bis); + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/devices.c new file mode 100644 index 0000000..5a453e3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/devices.c
@@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/uart.h> +#include <asm/arch/mux.h> +#include <asm/io.h> +#include <dm.h> + +static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; +static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; +static struct mux_regs *mux = (struct mux_regs *)MUX_BASE; + +void lpc32xx_uart_init(unsigned int uart_id) +{ + if (uart_id < 1 || uart_id > 7) + return; + + /* Disable loopback mode, if it is set by S1L bootloader */ + clrbits_le32(&ctrl->loop, + UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); + + if (uart_id < 3 || uart_id > 6) + return; + + /* Enable UART system clock */ + setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); + + /* Set UART into autoclock mode */ + clrsetbits_le32(&ctrl->clkmode, + UART_CLKMODE_MASK(uart_id), + UART_CLKMODE_AUTO(uart_id)); + + /* Bypass pre-divider of UART clock */ + writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), + &clk->u3clk + (uart_id - 3)); +} + +void lpc32xx_mac_init(void) +{ + /* Enable MAC interface */ + writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER + | CLK_MAC_MII, &clk->macclk_ctrl); +} + +void lpc32xx_mlc_nand_init(void) +{ + /* Enable NAND interface */ + writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl); +} + +void lpc32xx_i2c_init(unsigned int devnum) +{ + /* Enable I2C interface */ + uint32_t ctrl = readl(&clk->i2cclk_ctrl); + if (devnum == 1) + ctrl |= CLK_I2C1_ENABLE; + if (devnum == 2) + ctrl |= CLK_I2C2_ENABLE; + writel(ctrl, &clk->i2cclk_ctrl); +} + +U_BOOT_DEVICE(lpc32xx_gpios) = { + .name = "gpio_lpc32xx" +}; + +/* Mux for SCK0, MISO0, MOSI0. We do not use SSEL0. */ + +#define P_MUX_SET_SSP0 0x1600 + +void lpc32xx_ssp_init(void) +{ + /* Enable SSP0 interface */ + writel(CLK_SSP0_ENABLE_CLOCK, &clk->ssp_ctrl); + /* Mux SSP0 pins */ + writel(P_MUX_SET_SSP0, &mux->p_mux_set); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/dram.c b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/dram.c new file mode 100644 index 0000000..1eea8e2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/dram.c
@@ -0,0 +1,77 @@ +/* + * LPC32xx dram init + * + * (C) Copyright 2014 DENX Software Engineering GmbH + * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr> + * + * This is called by SPL to gain access to the SDR DRAM. + * + * This code runs from SRAM. + * + * Actual CONFIG_LPC32XX_SDRAM_* parameters must be provided + * by the board configuration file. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/wdt.h> +#include <asm/arch/emc.h> +#include <asm/io.h> + +static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; +static struct emc_regs *emc = (struct emc_regs *)EMC_BASE; + +void ddr_init(struct emc_dram_settings *dram) +{ + uint32_t ck; + + /* Enable EMC interface and choose little endian mode */ + writel(1, &emc->ctrl); + writel(0, &emc->config); + /* Select maximum EMC Dynamic Memory Refresh Time */ + writel(0x7FF, &emc->refresh); + /* Determine CLK */ + ck = get_sdram_clk_rate(); + /* Configure SDRAM */ + writel(dram->cmddelay, &clk->sdramclk_ctrl); + writel(dram->config0, &emc->config0); + writel(dram->rascas0, &emc->rascas0); + writel(dram->rdconfig, &emc->read_config); + /* Set timings */ + writel((ck / dram->trp) & 0x0000000F, &emc->t_rp); + writel((ck / dram->tras) & 0x0000000F, &emc->t_ras); + writel((ck / dram->tsrex) & 0x0000007F, &emc->t_srex); + writel((ck / dram->twr) & 0x0000000F, &emc->t_wr); + writel((ck / dram->trc) & 0x0000001F, &emc->t_rc); + writel((ck / dram->trfc) & 0x0000001F, &emc->t_rfc); + writel((ck / dram->txsr) & 0x000000FF, &emc->t_xsr); + writel(dram->trrd, &emc->t_rrd); + writel(dram->tmrd, &emc->t_mrd); + writel(dram->tcdlr, &emc->t_cdlr); + /* Dynamic refresh */ + writel((((ck / dram->refresh) >> 4) & 0x7FF), &emc->refresh); + udelay(10); + /* Force all clocks, enable inverted ck, issue NOP command */ + writel(0x00000193, &emc->control); + udelay(100); + /* Keep all clocks enabled, issue a PRECHARGE ALL command */ + writel(0x00000113, &emc->control); + /* Fast dynamic refresh for at least a few SDRAM ck cycles */ + writel((((128) >> 4) & 0x7FF), &emc->refresh); + udelay(10); + /* set correct dynamic refresh timing */ + writel((((ck / dram->refresh) >> 4) & 0x7FF), &emc->refresh); + udelay(10); + /* set normal mode to CAS=3 */ + writel(0x00000093, &emc->control); + readl(EMC_DYCS0_BASE | dram->mode); + /* set extended mode to all zeroes */ + writel(0x00000093, &emc->control); + readl(EMC_DYCS0_BASE | dram->emode); + /* stop forcing clocks, keep inverted clock, issue normal mode */ + writel(0x00000010, &emc->control); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S new file mode 100644 index 0000000..4b8053e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/lowlevel_init.S
@@ -0,0 +1,45 @@ +/* + * WORK Microwave work_92105 board low level init + * + * (C) Copyright 2014 DENX Software Engineering GmbH + * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr> + * + * Low level init is called from SPL to set up the clocks. + * On entry, the LPC3250 is in Direct Run mode with all clocks + * running at 13 MHz; on exit, ARM clock is 208 MHz, HCLK is + * 104 MHz and PCLK is 13 MHz. + * + * This code must run from SRAM so that the clock changes do + * not prevent it from executing. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl lowlevel_init + +lowlevel_init: + + /* Set ARM, HCLK, PCLK dividers for normal mode */ + ldr r0, =0x0000003D + ldr r1, =0x40004040 + str r0, [r1] + + /* Start HCLK PLL for 208 MHz */ + ldr r0, =0x0001401E + ldr r1, =0x40004058 + str r0, [r1] + + /* wait for HCLK PLL to lock */ +1: + ldr r0, [r1] + ands r0, r0, #1 + beq 1b + + /* switch to normal mode */ + ldr r1, =0x40004044 + ldr r0, [r1] + orr r0, #0x00000004 + str r0, [r1] + + /* Return to U-boot via saved link register */ + mov pc, lr
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/timer.c new file mode 100644 index 0000000..dc1217e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/lpc32xx/timer.c
@@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/timer.h> +#include <asm/io.h> + +static struct timer_regs *timer0 = (struct timer_regs *)TIMER0_BASE; +static struct timer_regs *timer1 = (struct timer_regs *)TIMER1_BASE; +static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; + +static void lpc32xx_timer_clock(u32 bit, int enable) +{ + if (enable) + setbits_le32(&clk->timclk_ctrl1, bit); + else + clrbits_le32(&clk->timclk_ctrl1, bit); +} + +static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq) +{ + writel(TIMER_TCR_COUNTER_RESET, &timer->tcr); + writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr); + writel(0, &timer->tc); + writel(0, &timer->pr); + + /* Count mode is every rising PCLK edge */ + writel(TIMER_CTCR_MODE_TIMER, &timer->ctcr); + + /* Set prescale counter value */ + writel((get_periph_clk_rate() / freq) - 1, &timer->pr); +} + +static void lpc32xx_timer_count(struct timer_regs *timer, int enable) +{ + if (enable) + writel(TIMER_TCR_COUNTER_ENABLE, &timer->tcr); + else + writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr); +} + +int timer_init(void) +{ + lpc32xx_timer_clock(CLK_TIMCLK_TIMER0, 1); + lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ); + lpc32xx_timer_count(timer0, 1); + + return 0; +} + +ulong get_timer(ulong base) +{ + return readl(&timer0->tc) - base; +} + +void __udelay(unsigned long usec) +{ + lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 1); + lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000); + lpc32xx_timer_count(timer1, 1); + + while (readl(&timer1->tc) < usec) + /* NOP */; + + lpc32xx_timer_count(timer1, 0); + lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 0); +} + +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/Makefile new file mode 100644 index 0000000..ebc0407 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/Makefile
@@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ + +obj-y = generic.o timer.o reset.o + +ifndef CONFIG_SPL_BUILD +obj-y += relocate.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/generic.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/generic.c new file mode 100644 index 0000000..8912098 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/generic.c
@@ -0,0 +1,249 @@ +/* + * (C) Copyright 2009 DENX Software Engineering + * Author: John Rigby <jrigby@gmail.com> + * + * Based on mx27/generic.c: + * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org> + * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> + +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> + +DECLARE_GLOBAL_DATA_PTR; +#endif + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref) +{ + unsigned int mfi = (pll >> CCM_PLL_MFI_SHIFT) + & CCM_PLL_MFI_MASK; + int mfn = (pll >> CCM_PLL_MFN_SHIFT) + & CCM_PLL_MFN_MASK; + unsigned int mfd = (pll >> CCM_PLL_MFD_SHIFT) + & CCM_PLL_MFD_MASK; + unsigned int pd = (pll >> CCM_PLL_PD_SHIFT) + & CCM_PLL_PD_MASK; + + mfi = mfi <= 5 ? 5 : mfi; + mfn = mfn >= 512 ? mfn - 1024 : mfn; + mfd += 1; + pd += 1; + + return lldiv(2 * (u64) f_ref * (mfi * mfd + mfn), + mfd * pd); +} + +static ulong imx_get_mpllclk(void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong fref = MXC_HCLK; + + return imx_decode_pll(readl(&ccm->mpctl), fref); +} + +static ulong imx_get_armclk(void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong cctl = readl(&ccm->cctl); + ulong fref = imx_get_mpllclk(); + ulong div; + + if (cctl & CCM_CCTL_ARM_SRC) + fref = lldiv((u64) fref * 3, 4); + + div = ((cctl >> CCM_CCTL_ARM_DIV_SHIFT) + & CCM_CCTL_ARM_DIV_MASK) + 1; + + return fref / div; +} + +static ulong imx_get_ahbclk(void) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong cctl = readl(&ccm->cctl); + ulong fref = imx_get_armclk(); + ulong div; + + div = ((cctl >> CCM_CCTL_AHB_DIV_SHIFT) + & CCM_CCTL_AHB_DIV_MASK) + 1; + + return fref / div; +} + +static ulong imx_get_ipgclk(void) +{ + return imx_get_ahbclk() / 2; +} + +static ulong imx_get_perclk(int clk) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong fref = imx_get_ahbclk(); + ulong div; + + div = readl(&ccm->pcdr[CCM_PERCLK_REG(clk)]); + div = ((div >> CCM_PERCLK_SHIFT(clk)) & CCM_PERCLK_MASK) + 1; + + return fref / div; +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + if (clk >= MXC_CLK_NUM) + return -1; + switch (clk) { + case MXC_ARM_CLK: + return imx_get_armclk(); + case MXC_AHB_CLK: + return imx_get_ahbclk(); + case MXC_IPG_CLK: + case MXC_CSPI_CLK: + case MXC_FEC_CLK: + return imx_get_ipgclk(); + default: + return imx_get_perclk(clk); + } +} + +u32 get_cpu_rev(void) +{ + u32 srev; + u32 system_rev = 0x25000; + + /* read SREV register from IIM module */ + struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; + srev = readl(&iim->iim_srev); + + switch (srev) { + case 0x00: + system_rev |= CHIP_REV_1_0; + break; + case 0x01: + system_rev |= CHIP_REV_1_1; + break; + case 0x02: + system_rev |= CHIP_REV_1_2; + break; + default: + system_rev |= 0x8000; + break; + } + + return system_rev; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +static char *get_reset_cause(void) +{ + /* read RCSR register from CCM module */ + struct ccm_regs *ccm = + (struct ccm_regs *)IMX_CCM_BASE; + + u32 cause = readl(&ccm->rcsr) & 0x0f; + + if (cause == 0) + return "POR"; + else if (cause == 1) + return "RST"; + else if ((cause & 2) == 2) + return "WDOG"; + else if ((cause & 4) == 4) + return "SW RESET"; + else if ((cause & 8) == 8) + return "JTAG"; + else + return "unknown reset"; + +} + +int print_cpuinfo(void) +{ + char buf[32]; + u32 cpurev = get_cpu_rev(); + + printf("CPU: Freescale i.MX25 rev%d.%d%s at %s MHz\n", + (cpurev & 0xF0) >> 4, (cpurev & 0x0F), + ((cpurev & 0x8000) ? " unknown" : ""), + strmhz(buf, imx_get_armclk())); + printf("Reset cause: %s\n", get_reset_cause()); + return 0; +} +#endif + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_DCACHE_OFF + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +#endif +} + +#if defined(CONFIG_FEC_MXC) +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + ulong val; + + val = readl(&ccm->cgr0); + val |= (1 << 23); + writel(val, &ccm->cgr0); + return fecmxc_initialize(bis); +} +#endif + +int get_clocks(void) +{ +#ifdef CONFIG_FSL_ESDHC +#if CONFIG_SYS_FSL_ESDHC_ADDR == IMX_MMC_SDHC2_BASE + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); +#else + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC1_CLK); +#endif +#endif + return 0; +} + +#ifdef CONFIG_FSL_ESDHC +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +#ifdef CONFIG_FEC_MXC +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + int i; + struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; + struct fuse_bank *bank = &iim->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + + for (i = 0; i < 6; i++) + mac[i] = readl(&fuse->mac_addr[i]) & 0xff; +} +#endif /* CONFIG_FEC_MXC */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/relocate.S b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/relocate.S new file mode 100644 index 0000000..8ebb81f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/relocate.S
@@ -0,0 +1,23 @@ +/* + * relocate - i.MX25-specific vector relocation + * + * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +/* + * The i.MX25 SoC is very specific with respect to exceptions: it + * does not provide RAM at the high vectors address (0xFFFF0000), + * thus only the low address (0x00000000) is useable; but that is + * in ROM, so let's avoid relocating the vectors. + */ + .section .text.relocate_vectors,"ax",%progbits + +ENTRY(relocate_vectors) + + bx lr + +ENDPROC(relocate_vectors)
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/reset.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/reset.c new file mode 100644 index 0000000..5db689d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/reset.c
@@ -0,0 +1,40 @@ +/* + * (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> + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +/* + * Reset the cpu by setting up the watchdog timer and let it time out + */ +void reset_cpu(ulong ignored) +{ + struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; + /* Disable watchdog and set Time-Out field to 0 */ + writew(0, ®s->wcr); + + /* Write Service Sequence */ + writew(WSR_UNLOCK1, ®s->wsr); + writew(WSR_UNLOCK2, ®s->wsr); + + /* Enable watchdog */ + writew(WCR_WDE, ®s->wcr); + + while (1) ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/timer.c new file mode 100644 index 0000000..7f19791 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx25/timer.c
@@ -0,0 +1,49 @@ +/* + * (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> + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> + * + * (C) Copyright 2009 DENX Software Engineering + * Author: John Rigby <jrigby@gmail.com> + * Add support for MX25 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +/* nothing really to do with interrupts, just starts up a counter. */ +/* The 32KHz 32-bit timer overruns in 134217 seconds */ +int timer_init(void) +{ + int i; + struct gpt_regs *gpt = (struct gpt_regs *)IMX_GPT1_BASE; + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; + + /* setup GP Timer 1 */ + writel(GPT_CTRL_SWR, &gpt->ctrl); + + writel(readl(&ccm->cgr1) | CCM_CGR1_GPT1, &ccm->cgr1); + + for (i = 0; i < 100; i++) + writel(0, &gpt->ctrl); /* We have no udelay by now */ + writel(0, &gpt->pre); /* prescaler = 1 */ + /* Freerun Mode, 32KHz input */ + writel(readl(&gpt->ctrl) | GPT_CTRL_CLKSOURCE_32 | GPT_CTRL_FRR, + &gpt->ctrl); + writel(readl(&gpt->ctrl) | GPT_CTRL_TEN, &gpt->ctrl); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/Makefile new file mode 100644 index 0000000..0edf144 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/Makefile
@@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ + +obj-y = generic.o reset.o timer.o + +ifndef CONFIG_SPL_BUILD +obj-y += relocate.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/generic.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/generic.c new file mode 100644 index 0000000..5ee9f07 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/generic.c
@@ -0,0 +1,379 @@ +/* + * Copyright (c) 2008 Eric Jarrige <eric.jarrige@armadeus.org> + * Copyright (c) 2009 Ilya Yanok <yanok@emcraft.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#ifdef CONFIG_MXC_MMC +#include <asm/arch/mxcmmc.h> +#endif + +/* + * get the system pll clock in Hz + * + * mfi + mfn / (mfd +1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +static unsigned int imx_decode_pll(unsigned int pll, unsigned int f_ref) +{ + unsigned int mfi = (pll >> 10) & 0xf; + unsigned int mfn = pll & 0x3ff; + unsigned int mfd = (pll >> 16) & 0x3ff; + unsigned int pd = (pll >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + + return lldiv(2 * (u64)f_ref * (mfi * (mfd + 1) + mfn), + (mfd + 1) * (pd + 1)); +} + +static ulong clk_in_32k(void) +{ + return 1024 * CONFIG_MX27_CLK32; +} + +static ulong clk_in_26m(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + if (readl(&pll->cscr) & CSCR_OSC26M_DIV1P5) { + /* divide by 1.5 */ + return 26000000 * 2 / 3; + } else { + return 26000000; + } +} + +static ulong imx_get_mpllclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref; + + if (cscr & CSCR_MCU_SEL) + fref = clk_in_26m(); + else + fref = clk_in_32k(); + + return imx_decode_pll(readl(&pll->mpctl0), fref); +} + +static ulong imx_get_armclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref = imx_get_mpllclk(); + ulong div; + + if (!(cscr & CSCR_ARM_SRC_MPLL)) + fref = lldiv((fref * 2), 3); + + div = ((cscr >> 12) & 0x3) + 1; + + return lldiv(fref, div); +} + +static ulong imx_get_ahbclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref = imx_get_mpllclk(); + ulong div; + + div = ((cscr >> 8) & 0x3) + 1; + + return lldiv(fref * 2, 3 * div); +} + +static __attribute__((unused)) ulong imx_get_spllclk(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + ulong cscr = readl(&pll->cscr); + ulong fref; + + if (cscr & CSCR_SP_SEL) + fref = clk_in_26m(); + else + fref = clk_in_32k(); + + return imx_decode_pll(readl(&pll->spctl0), fref); +} + +static ulong imx_decode_perclk(ulong div) +{ + return lldiv((imx_get_mpllclk() * 2), (div * 3)); +} + +static ulong imx_get_perclk1(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk((readl(&pll->pcdr1) & 0x3f) + 1); +} + +static ulong imx_get_perclk2(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 8) & 0x3f) + 1); +} + +static __attribute__((unused)) ulong imx_get_perclk3(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 16) & 0x3f) + 1); +} + +static __attribute__((unused)) ulong imx_get_perclk4(void) +{ + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + return imx_decode_perclk(((readl(&pll->pcdr1) >> 24) & 0x3f) + 1); +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return imx_get_armclk(); + case MXC_I2C_CLK: + return imx_get_ahbclk()/2; + case MXC_UART_CLK: + return imx_get_perclk1(); + case MXC_FEC_CLK: + return imx_get_ahbclk(); + case MXC_ESDHC_CLK: + return imx_get_perclk2(); + } + return -1; +} + + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo (void) +{ + char buf[32]; + + printf("CPU: Freescale i.MX27 at %s MHz\n\n", + strmhz(buf, imx_get_mpllclk())); + return 0; +} +#endif + +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FEC_MXC) + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + /* enable FEC clock */ + writel(readl(&pll->pccr1) | PCCR1_HCLK_FEC, &pll->pccr1); + writel(readl(&pll->pccr0) | PCCR0_FEC_EN, &pll->pccr0); + return fecmxc_initialize(bis); +#else + return 0; +#endif +} + +/* + * Initializes on-chip MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ +#ifdef CONFIG_MXC_MMC + return mxc_mmc_init(bis); +#else + return 0; +#endif +} + +void imx_gpio_mode(int gpio_mode) +{ + struct gpio_port_regs *regs = (struct gpio_port_regs *)IMX_GPIO_BASE; + unsigned int pin = gpio_mode & GPIO_PIN_MASK; + unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT; + unsigned int aout = (gpio_mode & GPIO_AOUT_MASK) >> GPIO_AOUT_SHIFT; + unsigned int bout = (gpio_mode & GPIO_BOUT_MASK) >> GPIO_BOUT_SHIFT; + unsigned int tmp; + + /* Pullup enable */ + if (gpio_mode & GPIO_PUEN) { + writel(readl(®s->port[port].puen) | (1 << pin), + ®s->port[port].puen); + } else { + writel(readl(®s->port[port].puen) & ~(1 << pin), + ®s->port[port].puen); + } + + /* Data direction */ + if (gpio_mode & GPIO_OUT) { + writel(readl(®s->port[port].gpio_dir) | 1 << pin, + ®s->port[port].gpio_dir); + } else { + writel(readl(®s->port[port].gpio_dir) & ~(1 << pin), + ®s->port[port].gpio_dir); + } + + /* Primary / alternate function */ + if (gpio_mode & GPIO_AF) { + writel(readl(®s->port[port].gpr) | (1 << pin), + ®s->port[port].gpr); + } else { + writel(readl(®s->port[port].gpr) & ~(1 << pin), + ®s->port[port].gpr); + } + + /* use as gpio? */ + if (!(gpio_mode & (GPIO_PF | GPIO_AF))) { + writel(readl(®s->port[port].gius) | (1 << pin), + ®s->port[port].gius); + } else { + writel(readl(®s->port[port].gius) & ~(1 << pin), + ®s->port[port].gius); + } + + /* Output / input configuration */ + if (pin < 16) { + tmp = readl(®s->port[port].ocr1); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + writel(tmp, ®s->port[port].ocr1); + + writel(readl(®s->port[port].iconfa1) & ~(3 << (pin * 2)), + ®s->port[port].iconfa1); + writel(readl(®s->port[port].iconfa1) | aout << (pin * 2), + ®s->port[port].iconfa1); + writel(readl(®s->port[port].iconfb1) & ~(3 << (pin * 2)), + ®s->port[port].iconfb1); + writel(readl(®s->port[port].iconfb1) | bout << (pin * 2), + ®s->port[port].iconfb1); + } else { + pin -= 16; + + tmp = readl(®s->port[port].ocr2); + tmp &= ~(3 << (pin * 2)); + tmp |= (ocr << (pin * 2)); + writel(tmp, ®s->port[port].ocr2); + + writel(readl(®s->port[port].iconfa2) & ~(3 << (pin * 2)), + ®s->port[port].iconfa2); + writel(readl(®s->port[port].iconfa2) | aout << (pin * 2), + ®s->port[port].iconfa2); + writel(readl(®s->port[port].iconfb2) & ~(3 << (pin * 2)), + ®s->port[port].iconfb2); + writel(readl(®s->port[port].iconfb2) | bout << (pin * 2), + ®s->port[port].iconfb2); + } +} + +#ifdef CONFIG_MXC_UART +void mx27_uart1_init_pins(void) +{ + int i; + unsigned int mode[] = { + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + +} +#endif /* CONFIG_MXC_UART */ + +#ifdef CONFIG_FEC_MXC +void mx27_fec_init_pins(void) +{ + int i; + unsigned int mode[] = { + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC | GPIO_PUEN, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_CLR, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); +} + +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + int i; + struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; + struct fuse_bank *bank = &iim->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + + for (i = 0; i < 6; i++) + mac[6 - 1 - i] = readl(&fuse->mac_addr[i]) & 0xff; +} +#endif /* CONFIG_FEC_MXC */ + +#ifdef CONFIG_MXC_MMC +void mx27_sd1_init_pins(void) +{ + int i; + unsigned int mode[] = { + PE18_PF_SD1_D0, + PE19_PF_SD1_D1, + PE20_PF_SD1_D2, + PE21_PF_SD1_D3, + PE22_PF_SD1_CMD, + PE23_PF_SD1_CLK, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + +} + +void mx27_sd2_init_pins(void) +{ + int i; + unsigned int mode[] = { + PB4_PF_SD2_D0, + PB5_PF_SD2_D1, + PB6_PF_SD2_D2, + PB7_PF_SD2_D3, + PB8_PF_SD2_CMD, + PB9_PF_SD2_CLK, + }; + + for (i = 0; i < ARRAY_SIZE(mode); i++) + imx_gpio_mode(mode[i]); + +} +#endif /* CONFIG_MXC_MMC */ + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif /* CONFIG_SYS_DCACHE_OFF */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/relocate.S b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/relocate.S new file mode 100644 index 0000000..0c4b272 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/relocate.S
@@ -0,0 +1,51 @@ +/* + * relocate - i.MX27-specific vector relocation + * + * Copyright (c) 2013 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> + +/* + * The i.MX27 SoC is very specific with respect to exceptions: it + * does not provide RAM at the high vectors address (0xFFFF0000), + * thus only the low address (0x00000000) is useable; but that is + * in ROM. Therefore, vectors cannot be changed at all. + * + * However, these ROM-based vectors actually just perform indirect + * calls through pointers located in RAM at SoC-specific addresses, + * as follows: + * + * Offset Exception Use by ROM code + * 0x00000000 reset indirect branch to [0x00000014] + * 0x00000004 undefined instruction indirect branch to [0xfffffef0] + * 0x00000008 software interrupt indirect branch to [0xfffffef4] + * 0x0000000c prefetch abort indirect branch to [0xfffffef8] + * 0x00000010 data abort indirect branch to [0xfffffefc] + * 0x00000014 (reserved in ARMv5) vector to ROM reset: 0xc0000000 + * 0x00000018 IRQ indirect branch to [0xffffff00] + * 0x0000001c FIQ indirect branch to [0xffffff04] + * + * In order to initialize exceptions on i.MX27, we must copy U-Boot's + * indirect (not exception!) vector table into 0xfffffef0..0xffffff04 + * taking care not to copy vectors number 5 (reserved exception). + */ + + .section .text.relocate_vectors,"ax",%progbits + +ENTRY(relocate_vectors) + + ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ + ldr r1, =32 /* size of vector table */ + add r0, r0, r1 /* skip to indirect table */ + ldr r1, =0xFFFFFEF0 /* i.MX27 indirect table */ + ldmia r0!, {r2-r8} /* load indirect vectors 1..7 */ + stmia r1!, {r2-r5, r7,r8} /* write all but vector 5 */ + + bx lr + +ENDPROC(relocate_vectors)
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/reset.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/reset.c new file mode 100644 index 0000000..f7b4a1c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/reset.c
@@ -0,0 +1,41 @@ +/* + * (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> + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +/* + * Reset the cpu by setting up the watchdog timer and let it time out + */ +void reset_cpu(ulong ignored) +{ + struct wdog_regs *regs = (struct wdog_regs *)IMX_WDT_BASE; + /* Disable watchdog and set Time-Out field to 0 */ + writel(0x00000000, ®s->wcr); + + /* Write Service Sequence */ + writel(0x00005555, ®s->wsr); + writel(0x0000AAAA, ®s->wsr); + + /* Enable watchdog */ + writel(WCR_WDE, ®s->wcr); + + while (1); + /*NOTREACHED*/ +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/timer.c new file mode 100644 index 0000000..40fe2aa --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mx27/timer.c
@@ -0,0 +1,162 @@ +/* + * (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> + * + * (C) Copyright 2009 + * Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +/* General purpose timers bitfields */ +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_FRR (1 << 8) /* Freerun / restart */ +#define GPTCR_CLKSOURCE_32 (4 << 1) /* Clock source */ +#define GPTCR_TEN 1 /* Timer enable */ + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp (gd->arch.tbl) +#define lastinc (gd->arch.lastinc) + +/* + * "time" is measured in 1 / CONFIG_SYS_HZ seconds, + * "tick" is internal timer period + */ +#ifdef CONFIG_MX27_TIMER_HIGH_PRECISION +/* ~0.4% error - measured with stop-watch on 100s boot-delay */ +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, CONFIG_MX27_CLK32); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + time *= CONFIG_MX27_CLK32; + do_div(time, CONFIG_SYS_HZ); + return time; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * CONFIG_MX27_CLK32 + 999999; + do_div(us, 1000000); + return us; +} +#else +/* ~2% error */ +#define TICK_PER_TIME ((CONFIG_MX27_CLK32 + CONFIG_SYS_HZ / 2) / \ + CONFIG_SYS_HZ) +#define US_PER_TICK (1000000 / CONFIG_MX27_CLK32) + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + do_div(tick, TICK_PER_TIME); + return tick; +} + +static inline unsigned long long time_to_tick(unsigned long long time) +{ + return time * TICK_PER_TIME; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us += US_PER_TICK - 1; + do_div(us, US_PER_TICK); + return us; +} +#endif + +/* nothing really to do with interrupts, just starts up a counter. */ +/* The 32768Hz 32-bit timer overruns in 131072 seconds */ +int timer_init(void) +{ + int i; + struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; + struct pll_regs *pll = (struct pll_regs *)IMX_PLL_BASE; + + /* setup GP Timer 1 */ + writel(GPTCR_SWR, ®s->gpt_tctl); + + writel(readl(&pll->pccr0) | PCCR0_GPT1_EN, &pll->pccr0); + writel(readl(&pll->pccr1) | PCCR1_PERCLK1_EN, &pll->pccr1); + + for (i = 0; i < 100; i++) + writel(0, ®s->gpt_tctl); /* We have no udelay by now */ + writel(0, ®s->gpt_tprer); /* 32Khz */ + /* Freerun Mode, PERCLK1 input */ + writel(readl(®s->gpt_tctl) | GPTCR_CLKSOURCE_32 | GPTCR_FRR, + ®s->gpt_tctl); + writel(readl(®s->gpt_tctl) | GPTCR_TEN, ®s->gpt_tctl); + + return 0; +} + +unsigned long long get_ticks(void) +{ + struct gpt_regs *regs = (struct gpt_regs *)IMX_TIM1_BASE; + ulong now = readl(®s->gpt_tcn); /* current tick value */ + + if (now >= lastinc) { + /* + * normal mode (non roll) + * move stamp forward with absolut diff ticks + */ + timestamp += (now - lastinc); + } else { + /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + } + lastinc = now; + return timestamp; +} + +ulong get_timer_masked(void) +{ + /* + * get_ticks() returns a long long (64 bit), it wraps in + * 2^64 / CONFIG_MX27_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ + * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in + * 5 * 10^6 days - long enough. + */ + return tick_to_time(get_ticks()); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds AND preserve advance timstamp value */ +void __udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = us_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; +} + +ulong get_tbclk(void) +{ + return CONFIG_MX27_CLK32; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/Makefile new file mode 100644 index 0000000..6c59494 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/Makefile
@@ -0,0 +1,85 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-$(CONFIG_SPL_BUILD) := start.o + +obj-y = clock.o mxs.o iomux.o timer.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o +endif + +# Specify the target for use in elftosb call +MKIMAGE_TARGET-$(CONFIG_MX23) = mxsimage.mx23.cfg +MKIMAGE_TARGET-$(CONFIG_MX28) = mxsimage.mx28.cfg + +# Generate HAB-capable IVT +# +# Note on computing the post-IVT size field value for the U-Boot binary. +# The value is the result of adding the following: +# -> The size of U-Boot binary aligned to 64B (u-boot.bin) +# -> The size of IVT block aligned to 64B (u-boot.ivt) +# -> The size of U-Boot signature (u-boot.sig), 3904 B +# -> The 64B hole in front of U-Boot binary for 'struct mxs_spl_data' passing +# +quiet_cmd_mkivt_mxs = MXSIVT $@ +cmd_mkivt_mxs = \ + sz=`expr \`stat -c "%s" $^\` + 64 + 3904 + 128` ; \ + echo -n "0x402000d1 $2 0 0 0 $3 $4 0 $$sz 0 0 0 0 0 0 0" | \ + tr -s " " | xargs -d " " -i printf "%08x\n" "{}" | rev | \ + sed "s/\(.\)\(.\)/\\\\\\\\x\2\1\n/g" | xargs -i printf "{}" >$@ + +# Align binary to 64B +quiet_cmd_mkalign_mxs = MXSALGN $@ +cmd_mkalign_mxs = \ + dd if=$^ of=$@ ibs=64 conv=sync 2>/dev/null && \ + mv $@ $^ + +# Assemble the CSF file +quiet_cmd_mkcsfreq_mxs = MXSCSFR $@ +cmd_mkcsfreq_mxs = \ + ivt=$(word 1,$^) ; \ + bin=$(word 2,$^) ; \ + csf=$(word 3,$^) ; \ + sed "s@VENDOR@$(VENDOR)@g;s@BOARD@$(BOARD)@g" "$$csf" | \ + sed '/^\#\#Blocks/ d' > $@ ; \ + echo " Blocks = $2 0x0 `stat -c '%s' $$bin` \"$$bin\" , \\" >> $@ ; \ + echo " $3 0x0 0x40 \"$$ivt\"" >> $@ + +# Sign files +quiet_cmd_mkcst_mxs = MXSCST $@ +cmd_mkcst_mxs = cst -o $@ < $^ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) + +spl/u-boot-spl.ivt: spl/u-boot-spl.bin + $(call if_changed,mkalign_mxs) + $(call if_changed,mkivt_mxs,$(CONFIG_SPL_TEXT_BASE),\ + 0x00008000,0x00008040) + +u-boot.ivt: u-boot.bin + $(call if_changed,mkalign_mxs) + $(call if_changed,mkivt_mxs,$(CONFIG_SYS_TEXT_BASE),\ + 0x40001000,0x40001040) + +spl/u-boot-spl.csf: spl/u-boot-spl.ivt spl/u-boot-spl.bin board/$(VENDOR)/$(BOARD)/sign/u-boot-spl.csf + $(call if_changed,mkcsfreq_mxs,$(CONFIG_SPL_TEXT_BASE),0x8000) + +u-boot.csf: u-boot.ivt u-boot.bin board/$(VENDOR)/$(BOARD)/sign/u-boot.csf + $(call if_changed,mkcsfreq_mxs,$(CONFIG_SYS_TEXT_BASE),0x40001000) + +%.sig: %.csf + $(call if_changed,mkcst_mxs) + +quiet_cmd_mkimage_mxs = MKIMAGE $@ +cmd_mkimage_mxs = $(objtree)/tools/mkimage -n $< -T mxsimage $@ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) + +u-boot.sb: $(src)/$(MKIMAGE_TARGET-y) u-boot.bin spl/u-boot-spl.bin FORCE + $(call if_changed,mkimage_mxs) + +u-boot-signed.sb: $(src)/mxsimage-signed.cfg u-boot.ivt u-boot.sig spl/u-boot-spl.ivt spl/u-boot-spl.sig FORCE + $(call if_changed,mkimage_mxs)
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/clock.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/clock.c new file mode 100644 index 0000000..ca020ca --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/clock.c
@@ -0,0 +1,436 @@ +/* + * Freescale i.MX23/i.MX28 clock setup code + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * Based on code from LTIB: + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> + +/* + * The PLL frequency is 480MHz and XTAL frequency is 24MHz + * iMX23: datasheet section 4.2 + * iMX28: datasheet section 10.2 + */ +#define PLL_FREQ_KHZ 480000 +#define PLL_FREQ_COEF 18 +#define XTAL_FREQ_KHZ 24000 + +#define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000) +#define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000) + +#if defined(CONFIG_MX23) +#define MXC_SSPCLK_MAX MXC_SSPCLK0 +#elif defined(CONFIG_MX28) +#define MXC_SSPCLK_MAX MXC_SSPCLK3 +#endif + +static uint32_t mxs_get_pclk(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + uint32_t clkctrl, clkseq, div; + uint8_t clkfrac, frac; + + clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu); + + /* No support of fractional divider calculation */ + if (clkctrl & + (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) { + return 0; + } + + clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); + + /* XTAL Path */ + if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) { + div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >> + CLKCTRL_CPU_DIV_XTAL_OFFSET; + return XTAL_FREQ_MHZ / div; + } + + /* REF Path */ + clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]); + frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; + div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK; + return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; +} + +static uint32_t mxs_get_hclk(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + uint32_t div; + uint32_t clkctrl; + + clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus); + + /* No support of fractional divider calculation */ + if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN) + return 0; + + div = clkctrl & CLKCTRL_HBUS_DIV_MASK; + return mxs_get_pclk() / div; +} + +static uint32_t mxs_get_emiclk(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + uint32_t clkctrl, clkseq, div; + uint8_t clkfrac, frac; + + clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); + clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi); + + /* XTAL Path */ + if (clkseq & CLKCTRL_CLKSEQ_BYPASS_EMI) { + div = (clkctrl & CLKCTRL_EMI_DIV_XTAL_MASK) >> + CLKCTRL_EMI_DIV_XTAL_OFFSET; + return XTAL_FREQ_MHZ / div; + } + + /* REF Path */ + clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]); + frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; + div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK; + return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; +} + +static uint32_t mxs_get_gpmiclk(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; +#if defined(CONFIG_MX23) + uint8_t *reg = + &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]; +#elif defined(CONFIG_MX28) + uint8_t *reg = + &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]; +#endif + uint32_t clkctrl, clkseq, div; + uint8_t clkfrac, frac; + + clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq); + clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi); + + /* XTAL Path */ + if (clkseq & CLKCTRL_CLKSEQ_BYPASS_GPMI) { + div = clkctrl & CLKCTRL_GPMI_DIV_MASK; + return XTAL_FREQ_MHZ / div; + } + + /* REF Path */ + clkfrac = readb(reg); + frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK; + div = clkctrl & CLKCTRL_GPMI_DIV_MASK; + return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div; +} + +/* + * Set IO clock frequency, in kHz + */ +void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint32_t div; + int io_reg; + + if (freq == 0) + return; + + if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) + return; + + div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq; + + if (div < 18) + div = 18; + + if (div > 35) + div = 35; + + io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_set[io_reg]); + writeb(CLKCTRL_FRAC_CLKGATE | (div & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac0[io_reg]); + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_clr[io_reg]); +} + +/* + * Get IO clock, returns IO clock in kHz + */ +static uint32_t mxs_get_ioclk(enum mxs_ioclock io) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint8_t ret; + int io_reg; + + if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) + return 0; + + io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */ + + ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) & + CLKCTRL_FRAC_FRAC_MASK; + + return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret; +} + +/* + * Configure SSP clock frequency, in kHz + */ +void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint32_t clk, clkreg; + + if (ssp > MXC_SSPCLK_MAX) + return; + + clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + + (ssp * sizeof(struct mxs_register_32)); + + clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE); + while (readl(clkreg) & CLKCTRL_SSP_CLKGATE) + ; + + if (xtal) + clk = XTAL_FREQ_KHZ; + else + clk = mxs_get_ioclk(ssp >> 1); + + if (freq > clk) + return; + + /* Calculate the divider and cap it if necessary */ + clk /= freq; + if (clk > CLKCTRL_SSP_DIV_MASK) + clk = CLKCTRL_SSP_DIV_MASK; + + clrsetbits_le32(clkreg, CLKCTRL_SSP_DIV_MASK, clk); + while (readl(clkreg) & CLKCTRL_SSP_BUSY) + ; + + if (xtal) + writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, + &clkctrl_regs->hw_clkctrl_clkseq_set); + else + writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp, + &clkctrl_regs->hw_clkctrl_clkseq_clr); +} + +/* + * Return SSP frequency, in kHz + */ +static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint32_t clkreg; + uint32_t clk, tmp; + + if (ssp > MXC_SSPCLK_MAX) + return 0; + + tmp = readl(&clkctrl_regs->hw_clkctrl_clkseq); + if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp)) + return XTAL_FREQ_KHZ; + + clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) + + (ssp * sizeof(struct mxs_register_32)); + + tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK; + + if (tmp == 0) + return 0; + + clk = mxs_get_ioclk(ssp >> 1); + + return clk / tmp; +} + +/* + * Set SSP/MMC bus frequency, in kHz) + */ +void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq) +{ + struct mxs_ssp_regs *ssp_regs; + const enum mxs_sspclock clk = mxs_ssp_clock_by_bus(bus); + const uint32_t sspclk = mxs_get_sspclk(clk); + uint32_t reg; + uint32_t divide, rate, tgtclk; + + ssp_regs = mxs_ssp_regs_by_bus(bus); + + /* + * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)), + * CLOCK_DIVIDE has to be an even value from 2 to 254, and + * CLOCK_RATE could be any integer from 0 to 255. + */ + for (divide = 2; divide < 254; divide += 2) { + rate = sspclk / freq / divide; + if (rate <= 256) + break; + } + + tgtclk = sspclk / divide / rate; + while (tgtclk > freq) { + rate++; + tgtclk = sspclk / divide / rate; + } + if (rate > 256) + rate = 256; + + /* Always set timeout the maximum */ + reg = SSP_TIMING_TIMEOUT_MASK | + (divide << SSP_TIMING_CLOCK_DIVIDE_OFFSET) | + ((rate - 1) << SSP_TIMING_CLOCK_RATE_OFFSET); + writel(reg, &ssp_regs->hw_ssp_timing); + + debug("SPI%d: Set freq rate to %d KHz (requested %d KHz)\n", + bus, tgtclk, freq); +} + +void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + uint32_t fp, x, k_rest, k_best, x_best, tk; + int32_t k_best_l = 999, k_best_t = 0, x_best_l = 0xff, x_best_t = 0xff; + + if (freq == 0) + return; + +#if defined(CONFIG_MX23) + writel(CLKCTRL_CLKSEQ_BYPASS_PIX, &clkctrl_regs->hw_clkctrl_clkseq_clr); +#elif defined(CONFIG_MX28) + writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF, &clkctrl_regs->hw_clkctrl_clkseq_clr); +#endif + + /* + * / 18 \ 1 1 + * freq kHz = | 480000000 Hz * -- | * --- * ------ + * \ x / k 1000 + * + * 480000000 Hz 18 + * ------------ * -- + * freq kHz x + * k = ------------------- + * 1000 + */ + + fp = ((PLL_FREQ_KHZ * 1000) / freq) * 18; + + for (x = 18; x <= 35; x++) { + tk = fp / x; + if ((tk / 1000 == 0) || (tk / 1000 > 255)) + continue; + + k_rest = tk % 1000; + + if (k_rest < (k_best_l % 1000)) { + k_best_l = tk; + x_best_l = x; + } + + if (k_rest > (k_best_t % 1000)) { + k_best_t = tk; + x_best_t = x; + } + } + + if (1000 - (k_best_t % 1000) > (k_best_l % 1000)) { + k_best = k_best_l; + x_best = x_best_l; + } else { + k_best = k_best_t; + x_best = x_best_t; + } + + k_best /= 1000; + +#if defined(CONFIG_MX23) + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_PIX]); + + writel(CLKCTRL_PIX_CLKGATE, + &clkctrl_regs->hw_clkctrl_pix_set); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_pix, + CLKCTRL_PIX_DIV_MASK | CLKCTRL_PIX_CLKGATE, + k_best << CLKCTRL_PIX_DIV_OFFSET); + + while (readl(&clkctrl_regs->hw_clkctrl_pix) & CLKCTRL_PIX_BUSY) + ; +#elif defined(CONFIG_MX28) + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac1_set[CLKCTRL_FRAC1_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE | (x_best & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_PIX]); + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac1_clr[CLKCTRL_FRAC1_PIX]); + + writel(CLKCTRL_DIS_LCDIF_CLKGATE, + &clkctrl_regs->hw_clkctrl_lcdif_set); + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_lcdif, + CLKCTRL_DIS_LCDIF_DIV_MASK | CLKCTRL_DIS_LCDIF_CLKGATE, + k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET); + + while (readl(&clkctrl_regs->hw_clkctrl_lcdif) & CLKCTRL_DIS_LCDIF_BUSY) + ; +#endif +} + +uint32_t mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return mxs_get_pclk() * 1000000; + case MXC_GPMI_CLK: + return mxs_get_gpmiclk() * 1000000; + case MXC_AHB_CLK: + case MXC_IPG_CLK: + return mxs_get_hclk() * 1000000; + case MXC_EMI_CLK: + return mxs_get_emiclk(); + case MXC_IO0_CLK: + return mxs_get_ioclk(MXC_IOCLK0); + case MXC_IO1_CLK: + return mxs_get_ioclk(MXC_IOCLK1); + case MXC_XTAL_CLK: + return XTAL_FREQ_KHZ * 1000; + case MXC_SSP0_CLK: + return mxs_get_sspclk(MXC_SSPCLK0); +#ifdef CONFIG_MX28 + case MXC_SSP1_CLK: + return mxs_get_sspclk(MXC_SSPCLK1); + case MXC_SSP2_CLK: + return mxs_get_sspclk(MXC_SSPCLK2); + case MXC_SSP3_CLK: + return mxs_get_sspclk(MXC_SSPCLK3); +#endif + } + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/iomux.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/iomux.c new file mode 100644 index 0000000..2e6be06 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/iomux.c
@@ -0,0 +1,97 @@ +/* + * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH, + * <armlinux@phytec.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/iomux.h> +#include <asm/arch/imx-regs.h> + +#if defined(CONFIG_MX23) +#define DRIVE_OFFSET 0x200 +#define PULL_OFFSET 0x400 +#elif defined(CONFIG_MX28) +#define DRIVE_OFFSET 0x300 +#define PULL_OFFSET 0x600 +#else +#error "Please select CONFIG_MX23 or CONFIG_MX28" +#endif + +/* + * configures a single pad in the iomuxer + */ +int mxs_iomux_setup_pad(iomux_cfg_t pad) +{ + u32 reg, ofs, bp, bm; + void *iomux_base = (void *)MXS_PINCTRL_BASE; + struct mxs_register_32 *mxs_reg; + + /* muxsel */ + ofs = 0x100; + ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10; + bp = PAD_PIN(pad) % 16 * 2; + bm = 0x3 << bp; + reg = readl(iomux_base + ofs); + reg &= ~bm; + reg |= PAD_MUXSEL(pad) << bp; + writel(reg, iomux_base + ofs); + + /* drive */ + ofs = DRIVE_OFFSET; + ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10; + /* mA */ + if (PAD_MA_VALID(pad)) { + bp = PAD_PIN(pad) % 8 * 4; + bm = 0x3 << bp; + reg = readl(iomux_base + ofs); + reg &= ~bm; + reg |= PAD_MA(pad) << bp; + writel(reg, iomux_base + ofs); + } + /* vol */ + if (PAD_VOL_VALID(pad)) { + bp = PAD_PIN(pad) % 8 * 4 + 2; + mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs); + if (PAD_VOL(pad)) + writel(1 << bp, &mxs_reg->reg_set); + else + writel(1 << bp, &mxs_reg->reg_clr); + } + + /* pull */ + if (PAD_PULL_VALID(pad)) { + ofs = PULL_OFFSET; + ofs += PAD_BANK(pad) * 0x10; + bp = PAD_PIN(pad); + mxs_reg = (struct mxs_register_32 *)(iomux_base + ofs); + if (PAD_PULL(pad)) + writel(1 << bp, &mxs_reg->reg_set); + else + writel(1 << bp, &mxs_reg->reg_clr); + } + + return 0; +} + +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count) +{ + const iomux_cfg_t *p = pad_list; + int i; + int ret; + + for (i = 0; i < count; i++) { + ret = mxs_iomux_setup_pad(*p); + if (ret) + return ret; + p++; + } + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs.c new file mode 100644 index 0000000..ef130ae --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs.c
@@ -0,0 +1,301 @@ +/* + * Freescale i.MX23/i.MX28 common code + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * Based on code from LTIB: + * Copyright (C) 2010 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/imx-common/dma.h> +#include <asm/arch/gpio.h> +#include <asm/arch/iomux.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Lowlevel init isn't used on i.MX28, so just have a dummy here */ +inline void lowlevel_init(void) {} + +void reset_cpu(ulong ignored) __attribute__((noreturn)); + +void reset_cpu(ulong ignored) +{ + struct mxs_rtc_regs *rtc_regs = + (struct mxs_rtc_regs *)MXS_RTC_BASE; + struct mxs_lcdif_regs *lcdif_regs = + (struct mxs_lcdif_regs *)MXS_LCDIF_BASE; + + /* + * Shut down the LCD controller as it interferes with BootROM boot mode + * pads sampling. + */ + writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr); + + /* Wait 1 uS before doing the actual watchdog reset */ + writel(1, &rtc_regs->hw_rtc_watchdog); + writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set); + + /* Endless loop, reset will exit from here */ + for (;;) + ; +} + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +/* + * This function will craft a jumptable at 0x0 which will redirect interrupt + * vectoring to proper location of U-Boot in RAM. + * + * The structure of the jumptable will be as follows: + * ldr pc, [pc, #0x18] ..... for each vector, thus repeated 8 times + * <destination address> ... for each previous ldr, thus also repeated 8 times + * + * The "ldr pc, [pc, #0x18]" instruction above loads address from memory at + * offset 0x18 from current value of PC register. Note that PC is already + * incremented by 4 when computing the offset, so the effective offset is + * actually 0x20, this the associated <destination address>. Loading the PC + * register with an address performs a jump to that address. + */ +void mx28_fixup_vt(uint32_t start_addr) +{ + /* ldr pc, [pc, #0x18] */ + const uint32_t ldr_pc = 0xe59ff018; + /* Jumptable location is 0x0 */ + uint32_t *vt = (uint32_t *)0x0; + int i; + + for (i = 0; i < 8; i++) { + /* cppcheck-suppress nullPointer */ + vt[i] = ldr_pc; + /* cppcheck-suppress nullPointer */ + vt[i + 8] = start_addr + (4 * i); + } +} + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + mx28_fixup_vt(gd->relocaddr); + return 0; +} +#endif + +int arch_cpu_init(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + extern uint32_t _start; + + mx28_fixup_vt((uint32_t)&_start); + + /* + * Enable NAND clock + */ + /* Clear bypass bit */ + writel(CLKCTRL_CLKSEQ_BYPASS_GPMI, + &clkctrl_regs->hw_clkctrl_clkseq_set); + + /* Set GPMI clock to ref_gpmi / 12 */ + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi, + CLKCTRL_GPMI_CLKGATE | CLKCTRL_GPMI_DIV_MASK, 1); + + udelay(1000); + + /* + * Configure GPIO unit + */ + mxs_gpio_init(); + +#ifdef CONFIG_APBH_DMA + /* Start APBH DMA */ + mxs_dma_init(); +#endif + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +static const char *get_cpu_type(void) +{ + struct mxs_digctl_regs *digctl_regs = + (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; + + switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { + case HW_DIGCTL_CHIPID_MX23: + return "23"; + case HW_DIGCTL_CHIPID_MX28: + return "28"; + default: + return "??"; + } +} + +static const char *get_cpu_rev(void) +{ + struct mxs_digctl_regs *digctl_regs = + (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; + uint8_t rev = readl(&digctl_regs->hw_digctl_chipid) & 0x000000FF; + + switch (readl(&digctl_regs->hw_digctl_chipid) & HW_DIGCTL_CHIPID_MASK) { + case HW_DIGCTL_CHIPID_MX23: + switch (rev) { + case 0x0: + return "1.0"; + case 0x1: + return "1.1"; + case 0x2: + return "1.2"; + case 0x3: + return "1.3"; + case 0x4: + return "1.4"; + default: + return "??"; + } + case HW_DIGCTL_CHIPID_MX28: + switch (rev) { + case 0x1: + return "1.2"; + default: + return "??"; + } + default: + return "??"; + } +} + +int print_cpuinfo(void) +{ + struct mxs_spl_data *data = (struct mxs_spl_data *) + ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); + + printf("CPU: Freescale i.MX%s rev%s at %d MHz\n", + get_cpu_type(), + get_cpu_rev(), + mxc_get_clock(MXC_ARM_CLK) / 1000000); + printf("BOOT: %s\n", mxs_boot_modes[data->boot_mode_idx].mode); + return 0; +} +#endif + +int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + printf("CPU: %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000); + printf("BUS: %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000); + printf("EMI: %3d MHz\n", mxc_get_clock(MXC_EMI_CLK)); + printf("GPMI: %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000); + return 0; +} + +/* + * Initializes on-chip ethernet controllers. + */ +#if defined(CONFIG_MX28) && defined(CONFIG_CMD_NET) +int cpu_eth_init(bd_t *bis) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + /* Turn on ENET clocks */ + clrbits_le32(&clkctrl_regs->hw_clkctrl_enet, + CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE); + + /* Set up ENET PLL for 50 MHz */ + /* Power on ENET PLL */ + writel(CLKCTRL_PLL2CTRL0_POWER, + &clkctrl_regs->hw_clkctrl_pll2ctrl0_set); + + udelay(10); + + /* Gate on ENET PLL */ + writel(CLKCTRL_PLL2CTRL0_CLKGATE, + &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr); + + /* Enable pad output */ + setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN); + + return 0; +} +#endif + +__weak void mx28_adjust_mac(int dev_id, unsigned char *mac) +{ + mac[0] = 0x00; + mac[1] = 0x04; /* Use FSL vendor MAC address by default */ + + if (dev_id == 1) /* Let MAC1 be MAC0 + 1 by default */ + mac[5] += 1; +} + +#ifdef CONFIG_MX28_FEC_MAC_IN_OCOTP + +#define MXS_OCOTP_MAX_TIMEOUT 1000000 +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + struct mxs_ocotp_regs *ocotp_regs = + (struct mxs_ocotp_regs *)MXS_OCOTP_BASE; + uint32_t data; + + memset(mac, 0, 6); + + writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set); + + if (mxs_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY, + MXS_OCOTP_MAX_TIMEOUT)) { + printf("MXS FEC: Can't get MAC from OCOTP\n"); + return; + } + + data = readl(&ocotp_regs->hw_ocotp_cust0); + + mac[2] = (data >> 24) & 0xff; + mac[3] = (data >> 16) & 0xff; + mac[4] = (data >> 8) & 0xff; + mac[5] = data & 0xff; + mx28_adjust_mac(dev_id, mac); +} +#else +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + memset(mac, 0, 6); +} +#endif + +int mxs_dram_init(void) +{ + struct mxs_spl_data *data = (struct mxs_spl_data *) + ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); + + if (data->mem_dram_size == 0) { + printf("MXS:\n" + "Error, the RAM size passed up from SPL is 0!\n"); + hang(); + } + + gd->ram_size = data->mem_dram_size; + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks, + "display clocks", + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs_init.h b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs_init.h new file mode 100644 index 0000000..1200ae1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxs_init.h
@@ -0,0 +1,29 @@ +/* + * Freescale i.MX28 SPL functions + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __M28_INIT_H__ +#define __M28_INIT_H__ + +void early_delay(int delay); + +void mxs_power_init(void); + +#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT +void mxs_power_wait_pswitch(void); +#else +static inline void mxs_power_wait_pswitch(void) { } +#endif + +void mxs_mem_init(void); +uint32_t mxs_mem_get_size(void); + +void mxs_lradc_init(void); +void mxs_lradc_enable_batt_measurement(void); + +#endif /* __M28_INIT_H__ */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg new file mode 100644 index 0000000..83953da --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg
@@ -0,0 +1,11 @@ +DISPLAYPROGRESS +SECTION 0x0 BOOTABLE + TAG LAST + LOAD 0x1000 spl/u-boot-spl.bin + LOAD 0x8000 spl/u-boot-spl.ivt + LOAD 0x8040 spl/u-boot-spl.sig + CALL HAB 0x8000 0x0 + LOAD 0x40002000 u-boot.bin + LOAD 0x40001000 u-boot.ivt + LOAD 0x40001040 u-boot.sig + CALL HAB 0x40001000 0x0
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg new file mode 100644 index 0000000..e702809 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
@@ -0,0 +1,7 @@ +DISPLAYPROGRESS +SECTION 0x0 BOOTABLE + TAG LAST + LOAD 0x1000 spl/u-boot-spl.bin + CALL 0x1000 0x0 + LOAD 0x40002000 u-boot.bin + CALL 0x40002000 0x0
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg new file mode 100644 index 0000000..3f7bf59 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
@@ -0,0 +1,9 @@ +DISPLAYPROGRESS +SECTION 0x0 BOOTABLE + TAG LAST + LOAD 0x1000 spl/u-boot-spl.bin + LOAD IVT 0x8000 0x1000 + CALL HAB 0x8000 0x0 + LOAD 0x40002000 u-boot.bin + LOAD IVT 0x8000 0x40002000 + CALL HAB 0x8000 0x0
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_boot.c new file mode 100644 index 0000000..d7956e5 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -0,0 +1,178 @@ +/* + * Freescale i.MX28 Boot setup + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <asm/gpio.h> +#include <linux/compiler.h> + +#include "mxs_init.h" + +DECLARE_GLOBAL_DATA_PTR; +static gd_t gdata __section(".data"); +#ifdef CONFIG_SPL_SERIAL_SUPPORT +static bd_t bdata __section(".data"); +#endif + +/* + * This delay function is intended to be used only in early stage of boot, where + * clock are not set up yet. The timer used here is reset on every boot and + * takes a few seconds to roll. The boot doesn't take that long, so to keep the + * code simple, it doesn't take rolling into consideration. + */ +void early_delay(int delay) +{ + struct mxs_digctl_regs *digctl_regs = + (struct mxs_digctl_regs *)MXS_DIGCTL_BASE; + + uint32_t st = readl(&digctl_regs->hw_digctl_microseconds); + st += delay; + while (st > readl(&digctl_regs->hw_digctl_microseconds)) + ; +} + +#define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL) +static const iomux_cfg_t iomux_boot[] = { +#if defined(CONFIG_MX23) + MX23_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, + MX23_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, +#elif defined(CONFIG_MX28) + MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD, + MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD, + MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD, + MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD, + MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD, + MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD, +#endif +}; + +static uint8_t mxs_get_bootmode_index(void) +{ + uint8_t bootmode = 0; + int i; + uint8_t masked; + + /* Setup IOMUX of bootmode pads to GPIO */ + mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot)); + +#if defined(CONFIG_MX23) + /* Setup bootmode pins as GPIO input */ + gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0); + gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1); + gpio_direction_input(MX23_PAD_LCD_D02__GPIO_1_2); + gpio_direction_input(MX23_PAD_LCD_D03__GPIO_1_3); + gpio_direction_input(MX23_PAD_LCD_D05__GPIO_1_5); + + /* Read bootmode pads */ + bootmode |= (gpio_get_value(MX23_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; + bootmode |= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; +#elif defined(CONFIG_MX28) + /* Setup bootmode pins as GPIO input */ + gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0); + gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1); + gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2); + gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3); + gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4); + gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5); + + /* Read bootmode pads */ + bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0; + bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1; + bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2; + bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3; + bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4; + bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5; +#endif + + for (i = 0; i < ARRAY_SIZE(mxs_boot_modes); i++) { + masked = bootmode & mxs_boot_modes[i].boot_mask; + if (masked == mxs_boot_modes[i].boot_pads) + break; + } + + return i; +} + +static void mxs_spl_fixup_vectors(void) +{ + /* + * Copy our vector table to 0x0, since due to HAB, we cannot + * be loaded to 0x0. We want to have working vectoring though, + * thus this fixup. Our vectoring table is PIC, so copying is + * fine. + */ + extern uint32_t _start; + + /* cppcheck-suppress nullPointer */ + memcpy(0x0, &_start, 0x60); +} + +static void mxs_spl_console_init(void) +{ +#ifdef CONFIG_SPL_SERIAL_SUPPORT + gd->bd = &bdata; + gd->baudrate = CONFIG_BAUDRATE; + serial_init(); + gd->have_console = 1; +#endif +} + +void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, + const iomux_cfg_t *iomux_setup, + const unsigned int iomux_size) +{ + struct mxs_spl_data *data = (struct mxs_spl_data *) + ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); + uint8_t bootmode = mxs_get_bootmode_index(); + gd = &gdata; + + mxs_spl_fixup_vectors(); + + mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size); + + mxs_spl_console_init(); + debug("SPL: Serial Console Initialised\n"); + + mxs_power_init(); + + mxs_mem_init(); + data->mem_dram_size = mxs_mem_get_size(); + + data->boot_mode_idx = bootmode; + + mxs_power_wait_pswitch(); + + if (mxs_boot_modes[data->boot_mode_idx].boot_pads == MXS_BM_JTAG) { + debug("SPL: Waiting for JTAG user\n"); + asm volatile ("x: b x"); + } +} + +/* Support aparatus */ +inline void board_init_f(unsigned long bootflag) +{ + for (;;) + ; +} + +inline void board_init_r(gd_t *id, ulong dest_addr) +{ + for (;;) + ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c new file mode 100644 index 0000000..96bd32f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_lradc_init.c
@@ -0,0 +1,79 @@ +/* + * Freescale i.MX28 Battery measurement init + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +#include "mxs_init.h" + +void mxs_lradc_init(void) +{ + struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE; + + debug("SPL: Initialisating LRADC\n"); + + writel(LRADC_CTRL0_SFTRST, ®s->hw_lradc_ctrl0_clr); + writel(LRADC_CTRL0_CLKGATE, ®s->hw_lradc_ctrl0_clr); + writel(LRADC_CTRL0_ONCHIP_GROUNDREF, ®s->hw_lradc_ctrl0_clr); + + clrsetbits_le32(®s->hw_lradc_ctrl3, + LRADC_CTRL3_CYCLE_TIME_MASK, + LRADC_CTRL3_CYCLE_TIME_6MHZ); + + clrsetbits_le32(®s->hw_lradc_ctrl4, + LRADC_CTRL4_LRADC7SELECT_MASK | + LRADC_CTRL4_LRADC6SELECT_MASK, + LRADC_CTRL4_LRADC7SELECT_CHANNEL7 | + LRADC_CTRL4_LRADC6SELECT_CHANNEL10); +} + +void mxs_lradc_enable_batt_measurement(void) +{ + struct mxs_lradc_regs *regs = (struct mxs_lradc_regs *)MXS_LRADC_BASE; + + debug("SPL: Enabling LRADC battery measurement\n"); + + /* Check if the channel is present at all. */ + if (!(readl(®s->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT)) { + debug("SPL: LRADC channel 7 is not present - aborting\n"); + return; + } + + debug("SPL: LRADC channel 7 is present - configuring\n"); + + writel(LRADC_CTRL1_LRADC7_IRQ_EN, ®s->hw_lradc_ctrl1_clr); + writel(LRADC_CTRL1_LRADC7_IRQ, ®s->hw_lradc_ctrl1_clr); + + clrsetbits_le32(®s->hw_lradc_conversion, + LRADC_CONVERSION_SCALE_FACTOR_MASK, + LRADC_CONVERSION_SCALE_FACTOR_LI_ION); + writel(LRADC_CONVERSION_AUTOMATIC, ®s->hw_lradc_conversion_set); + + /* Configure the channel. */ + writel((1 << 7) << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, + ®s->hw_lradc_ctrl2_clr); + writel(0xffffffff, ®s->hw_lradc_ch7_clr); + clrbits_le32(®s->hw_lradc_ch7, LRADC_CH_NUM_SAMPLES_MASK); + writel(LRADC_CH_ACCUMULATE, ®s->hw_lradc_ch7_clr); + + /* Schedule the channel. */ + writel(1 << 7, ®s->hw_lradc_ctrl0_set); + + /* Start the channel sampling. */ + writel(((1 << 7) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) | + ((1 << 3) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) | + 100, ®s->hw_lradc_delay3); + + writel(0xffffffff, ®s->hw_lradc_ch7_clr); + writel(LRADC_DELAY_KICK, ®s->hw_lradc_delay3_set); + + debug("SPL: LRADC channel 7 configuration complete\n"); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c new file mode 100644 index 0000000..a744e5d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
@@ -0,0 +1,360 @@ +/* + * Freescale i.MX28 RAM init + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <linux/compiler.h> + +#include "mxs_init.h" + +static uint32_t dram_vals[] = { +/* + * i.MX28 DDR2 at 200MHz + */ +#if defined(CONFIG_MX28) + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00010101, 0x01010101, + 0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101, + 0x00000100, 0x00000100, 0x00000000, 0x00000002, + 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8, + 0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612, + 0x02030202, 0x00c8001c, 0x00000000, 0x00000000, + 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, + 0x00012100, 0xffff0303, 0x00012100, 0xffff0303, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000612, 0x01000F02, + 0x06120612, 0x00000200, 0x00020007, 0xf4004a27, + 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07000300, + 0x07000300, 0x07400300, 0x07400300, 0x00000005, + 0x00000000, 0x00000000, 0x01000000, 0x01020408, + 0x08040201, 0x000f1133, 0x00000000, 0x00001f04, + 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, + 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00010000, 0x00030404, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x01010000, + 0x01000000, 0x03030000, 0x00010303, 0x01020202, + 0x00000000, 0x02040303, 0x21002103, 0x00061200, + 0x06120612, 0x04420442, 0x04420442, 0x00040004, + 0x00040004, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff + +/* + * i.MX23 DDR at 133MHz + */ +#elif defined(CONFIG_MX23) + 0x01010001, 0x00010100, 0x01000101, 0x00000001, + 0x00000101, 0x00000000, 0x00010000, 0x01000001, + 0x00000000, 0x00000001, 0x07000200, 0x00070202, + 0x02020000, 0x04040a01, 0x00000201, 0x02040000, + 0x02000000, 0x19000f08, 0x0d0d0000, 0x02021313, + 0x02061521, 0x0000000a, 0x00080008, 0x00200020, + 0x00200020, 0x00200020, 0x000003f7, 0x00000000, + 0x00000000, 0x00000020, 0x00000020, 0x00c80000, + 0x000a23cd, 0x000000c8, 0x00006665, 0x00000000, + 0x00000101, 0x00040001, 0x00000000, 0x00000000, + 0x00010000 +#else +#error Unsupported memory initialization +#endif +}; + +__weak void mxs_adjust_memory_params(uint32_t *dram_vals) +{ + debug("SPL: Using default SDRAM parameters\n"); +} + +#ifdef CONFIG_MX28 +static void initialize_dram_values(void) +{ + int i; + + debug("SPL: Setting mx28 board specific SDRAM parameters\n"); + mxs_adjust_memory_params(dram_vals); + + debug("SPL: Applying SDRAM parameters\n"); + for (i = 0; i < ARRAY_SIZE(dram_vals); i++) + writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); +} +#else +static void initialize_dram_values(void) +{ + int i; + + debug("SPL: Setting mx23 board specific SDRAM parameters\n"); + mxs_adjust_memory_params(dram_vals); + + /* + * HW_DRAM_CTL27, HW_DRAM_CTL28 and HW_DRAM_CTL35 are not initialized as + * per FSL bootlets code. + * + * mx23 Reference Manual marks HW_DRAM_CTL27 and HW_DRAM_CTL28 as + * "reserved". + * HW_DRAM_CTL8 is setup as the last element. + * So skip the initialization of these HW_DRAM_CTL registers. + */ + debug("SPL: Applying SDRAM parameters\n"); + for (i = 0; i < ARRAY_SIZE(dram_vals); i++) { + if (i == 8 || i == 27 || i == 28 || i == 35) + continue; + writel(dram_vals[i], MXS_DRAM_BASE + (4 * i)); + } + + /* + * Enable tRAS lockout in HW_DRAM_CTL08 ; it must be the last + * element to be set + */ + writel((1 << 24), MXS_DRAM_BASE + (4 * 8)); +} +#endif + +static void mxs_mem_init_clock(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; +#if defined(CONFIG_MX23) + /* Fractional divider for ref_emi is 33 ; 480 * 18 / 33 = 266MHz */ + const unsigned char divider = 33; +#elif defined(CONFIG_MX28) + /* Fractional divider for ref_emi is 21 ; 480 * 18 / 21 = 411MHz */ + const unsigned char divider = 21; +#endif + + debug("SPL: Initialising FRAC0\n"); + + /* Gate EMI clock */ + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_set[CLKCTRL_FRAC0_EMI]); + + /* Set fractional divider for ref_emi */ + writeb(CLKCTRL_FRAC_CLKGATE | (divider & CLKCTRL_FRAC_FRAC_MASK), + &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_EMI]); + + /* Ungate EMI clock */ + writeb(CLKCTRL_FRAC_CLKGATE, + &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]); + + early_delay(11000); + + /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */ + writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) | + (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET), + &clkctrl_regs->hw_clkctrl_emi); + + /* Unbypass EMI */ + writel(CLKCTRL_CLKSEQ_BYPASS_EMI, + &clkctrl_regs->hw_clkctrl_clkseq_clr); + + early_delay(10000); + debug("SPL: FRAC0 Initialised\n"); +} + +static void mxs_mem_setup_cpu_and_hbus(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + debug("SPL: Setting CPU and HBUS clock frequencies\n"); + + /* Set fractional divider for ref_cpu to 480 * 18 / 19 = 454MHz + * and ungate CPU clock */ + writeb(19 & CLKCTRL_FRAC_FRAC_MASK, + (uint8_t *)&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]); + + /* Set CPU bypass */ + writel(CLKCTRL_CLKSEQ_BYPASS_CPU, + &clkctrl_regs->hw_clkctrl_clkseq_set); + + /* HBUS = 151MHz */ + writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set); + writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK, + &clkctrl_regs->hw_clkctrl_hbus_clr); + + early_delay(10000); + + /* CPU clock divider = 1 */ + clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu, + CLKCTRL_CPU_DIV_CPU_MASK, 1); + + /* Disable CPU bypass */ + writel(CLKCTRL_CLKSEQ_BYPASS_CPU, + &clkctrl_regs->hw_clkctrl_clkseq_clr); + + early_delay(15000); +} + +static void mxs_mem_setup_vdda(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Configuring VDDA\n"); + + writel((0xc << POWER_VDDACTRL_TRG_OFFSET) | + (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) | + POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW, + &power_regs->hw_power_vddactrl); +} + +uint32_t mxs_mem_get_size(void) +{ + uint32_t sz, da; + uint32_t *vt = (uint32_t *)0x20; + /* The following is "subs pc, r14, #4", used as return from DABT. */ + const uint32_t data_abort_memdetect_handler = 0xe25ef004; + + /* Replace the DABT handler. */ + da = vt[4]; + vt[4] = data_abort_memdetect_handler; + + sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); + + /* Restore the old DABT handler. */ + vt[4] = da; + + return sz; +} + +#ifdef CONFIG_MX23 +static void mx23_mem_setup_vddmem(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Setting mx23 VDDMEM\n"); + + /* We must wait before and after disabling the current limiter! */ + early_delay(10000); + + clrbits_le32(&power_regs->hw_power_vddmemctrl, + POWER_VDDMEMCTRL_ENABLE_ILIMIT); + + early_delay(10000); + +} + +static void mx23_mem_init(void) +{ + debug("SPL: Initialising mx23 SDRAM Controller\n"); + + /* + * Reset/ungate the EMI block. This is essential, otherwise the system + * suffers from memory instability. This thing is mx23 specific and is + * no longer present on mx28. + */ + mxs_reset_block((struct mxs_register_32 *)MXS_EMI_BASE); + + mx23_mem_setup_vddmem(); + + /* + * Configure the DRAM registers + */ + + /* Clear START and SREFRESH bit from DRAM_CTL8 */ + clrbits_le32(MXS_DRAM_BASE + 0x20, (1 << 16) | (1 << 8)); + + initialize_dram_values(); + + /* Set START bit in DRAM_CTL8 */ + setbits_le32(MXS_DRAM_BASE + 0x20, 1 << 16); + + clrbits_le32(MXS_DRAM_BASE + 0x40, 1 << 17); + + /* Wait for EMI_STAT bit DRAM_HALTED */ + for (;;) { + if (!(readl(MXS_EMI_BASE + 0x10) & (1 << 1))) + break; + early_delay(1000); + } + + /* Adjust EMI port priority. */ + clrsetbits_le32(0x80020000, 0x1f << 16, 0x2); + early_delay(20000); + + setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 19); + setbits_le32(MXS_DRAM_BASE + 0x40, 1 << 11); +} +#endif + +#ifdef CONFIG_MX28 +static void mx28_mem_init(void) +{ + struct mxs_pinctrl_regs *pinctrl_regs = + (struct mxs_pinctrl_regs *)MXS_PINCTRL_BASE; + + debug("SPL: Initialising mx28 SDRAM Controller\n"); + + /* Set DDR2 mode */ + writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2, + &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set); + + /* + * Configure the DRAM registers + */ + + /* Clear START bit from DRAM_CTL16 */ + clrbits_le32(MXS_DRAM_BASE + 0x40, 1); + + initialize_dram_values(); + + /* Clear SREFRESH bit from DRAM_CTL17 */ + clrbits_le32(MXS_DRAM_BASE + 0x44, 1); + + /* Set START bit in DRAM_CTL16 */ + setbits_le32(MXS_DRAM_BASE + 0x40, 1); + + /* Wait for bit 20 (DRAM init complete) in DRAM_CTL58 */ + while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20))) + ; +} +#endif + +void mxs_mem_init(void) +{ + early_delay(11000); + + mxs_mem_init_clock(); + + mxs_mem_setup_vdda(); + +#if defined(CONFIG_MX23) + mx23_mem_init(); +#elif defined(CONFIG_MX28) + mx28_mem_init(); +#endif + + early_delay(10000); + + mxs_mem_setup_cpu_and_hbus(); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c new file mode 100644 index 0000000..c342217 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -0,0 +1,1256 @@ +/* + * Freescale i.MX28 Boot PMIC init + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> + +#include "mxs_init.h" + +#ifdef CONFIG_SYS_MXS_VDD5V_ONLY +#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ + POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2 +#else +#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ + POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL +#endif +/** + * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL + * + * This function switches the CPU core clock from PLL to 24MHz XTAL + * oscilator. This is necessary if the PLL is being reconfigured to + * prevent crash of the CPU core. + */ +static void mxs_power_clock2xtal(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + debug("SPL: Switching CPU clock to 24MHz XTAL\n"); + + /* Set XTAL as CPU reference clock */ + writel(CLKCTRL_CLKSEQ_BYPASS_CPU, + &clkctrl_regs->hw_clkctrl_clkseq_set); +} + +/** + * mxs_power_clock2pll() - Switch CPU core clock source to PLL + * + * This function switches the CPU core clock from 24MHz XTAL oscilator + * to PLL. This can only be called once the PLL has re-locked and once + * the PLL is stable after reconfiguration. + */ +static void mxs_power_clock2pll(void) +{ + struct mxs_clkctrl_regs *clkctrl_regs = + (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; + + debug("SPL: Switching CPU core clock source to PLL\n"); + + /* + * TODO: Are we really? It looks like we turn on PLL0, but we then + * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already + * set by mxs_power_clock2xtal()). Clearing this bit here seems to + * introduce some instability (causing the CPU core to hang). Maybe + * we aren't giving PLL0 enough time to stabilise? + */ + setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0, + CLKCTRL_PLL0CTRL0_POWER); + early_delay(100); + + /* + * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a + * wait on the PLL0 LOCK bit? + */ + setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq, + CLKCTRL_CLKSEQ_BYPASS_CPU); +} + +/** + * mxs_power_set_auto_restart() - Set the auto-restart bit + * + * This function ungates the RTC block and sets the AUTO_RESTART + * bit to work around a design bug on MX28EVK Rev. A . + */ + +static void mxs_power_set_auto_restart(void) +{ + struct mxs_rtc_regs *rtc_regs = + (struct mxs_rtc_regs *)MXS_RTC_BASE; + + debug("SPL: Setting auto-restart bit\n"); + + writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr); + while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST) + ; + + writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr); + while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE) + ; + + /* Do nothing if flag already set */ + if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART) + return; + + while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) + ; + + setbits_le32(&rtc_regs->hw_rtc_persistent0, + RTC_PERSISTENT0_AUTO_RESTART); + writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set); + writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr); + while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) + ; + while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK) + ; +} + +/** + * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter + * + * This function configures the VDDIO, VDDA and VDDD linear regulators output + * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching + * converter. This is the recommended setting for the case where we use both + * linear regulators and DC-DC converter to power the VDDIO rail. + */ +static void mxs_power_set_linreg(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + /* Set linear regulator 25mV below switching converter */ + debug("SPL: Setting VDDD 25mV below DC-DC converters\n"); + clrsetbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_LINREG_OFFSET_MASK, + POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); + + debug("SPL: Setting VDDA 25mV below DC-DC converters\n"); + clrsetbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_LINREG_OFFSET_MASK, + POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW); + + debug("SPL: Setting VDDIO 25mV below DC-DC converters\n"); + clrsetbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_LINREG_OFFSET_MASK, + POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); +} + +/** + * mxs_get_batt_volt() - Measure battery input voltage + * + * This function retrieves the battery input voltage and returns it. + */ +static int mxs_get_batt_volt(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t volt = readl(&power_regs->hw_power_battmonitor); + volt &= POWER_BATTMONITOR_BATT_VAL_MASK; + volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET; + volt *= 8; + + debug("SPL: Battery Voltage = %dmV\n", volt); + return volt; +} + +/** + * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot + * + * This function checks if the battery input voltage is higher than 3.6V and + * therefore allows the system to successfully boot using this power source. + */ +static int mxs_is_batt_ready(void) +{ + return (mxs_get_batt_volt() >= 3600); +} + +/** + * mxs_is_batt_good() - Test if battery is operational at all + * + * This function starts recharging the battery and tests if the input current + * provided by the 5V input recharging the battery is also sufficient to power + * the DC-DC converter. + */ +static int mxs_is_batt_good(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t volt = mxs_get_batt_volt(); + + if ((volt >= 2400) && (volt <= 4300)) { + debug("SPL: Battery is good\n"); + return 1; + } + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); + writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, + &power_regs->hw_power_5vctrl_clr); + + clrsetbits_le32(&power_regs->hw_power_charge, + POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, + POWER_CHARGE_STOP_ILIMIT_10MA | 0x3); + + writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr); + writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, + &power_regs->hw_power_5vctrl_clr); + + early_delay(500000); + + volt = mxs_get_batt_volt(); + + if (volt >= 3500) { + debug("SPL: Battery Voltage too high\n"); + return 0; + } + + if (volt >= 2400) { + debug("SPL: Battery is good\n"); + return 1; + } + + writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, + &power_regs->hw_power_charge_clr); + writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set); + + debug("SPL: Battery Voltage too low\n"); + return 0; +} + +/** + * mxs_power_setup_5v_detect() - Start the 5V input detection comparator + * + * This function enables the 5V detection comparator and sets the 5V valid + * threshold to 4.4V . We use 4.4V threshold here to make sure that even + * under high load, the voltage drop on the 5V input won't be so critical + * to cause undervolt on the 4P2 linear regulator supplying the DC-DC + * converter and thus making the system crash. + */ +static void mxs_power_setup_5v_detect(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + /* Start 5V detection */ + debug("SPL: Starting 5V input detection comparator\n"); + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_VBUSVALID_TRSH_MASK, + POWER_5VCTRL_VBUSVALID_TRSH_4V4 | + POWER_5VCTRL_PWRUP_VBUS_CMPS); +} + +/** + * mxs_src_power_init() - Preconfigure the power block + * + * This function configures reasonable values for the DC-DC control loop + * and battery monitor. + */ +static void mxs_src_power_init(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Pre-Configuring power block\n"); + + /* Improve efficieny and reduce transient ripple */ + writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST | + POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set); + + clrsetbits_le32(&power_regs->hw_power_dclimits, + POWER_DCLIMITS_POSLIMIT_BUCK_MASK, + 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET); + + setbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_EN_BATADJ); + + /* Increase the RCSCALE level for quick DCDC response to dynamic load */ + clrsetbits_le32(&power_regs->hw_power_loopctrl, + POWER_LOOPCTRL_EN_RCSCALE_MASK, + POWER_LOOPCTRL_RCSCALE_THRESH | + POWER_LOOPCTRL_EN_RCSCALE_8X); + + clrsetbits_le32(&power_regs->hw_power_minpwr, + POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); + + /* 5V to battery handoff ... FIXME */ + setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); + early_delay(30); + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); +} + +/** + * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator + * + * This function configures the necessary parameters for the 4P2 linear + * regulator to supply the DC-DC converter from 5V input. + */ +static void mxs_power_init_4p2_params(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Configuring common 4P2 regulator params\n"); + + /* Setup 4P2 parameters */ + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, + POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_HEADROOM_ADJ_MASK, + 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); + + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_DROPOUT_CTRL_MASK, + DCDC4P2_DROPOUT_CONFIG); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); +} + +/** + * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2 + * @xfer: Select if the input shall be enabled or disabled + * + * This function enables or disables the 4P2 input into the DC-DC converter. + */ +static void mxs_enable_4p2_dcdc_input(int xfer) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo; + uint32_t prev_5v_brnout, prev_5v_droop; + + debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling"); + + prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_PWDN_5VBRNOUT; + prev_5v_droop = readl(&power_regs->hw_power_ctrl) & + POWER_CTRL_ENIRQ_VDD5V_DROOP; + + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); + writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, + &power_regs->hw_power_reset); + + clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP); + + if (xfer && (readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_ENABLE_DCDC)) { + return; + } + + /* + * Recording orignal values that will be modified temporarlily + * to handle a chip bug. See chip errata for CQ ENGR00115837 + */ + tmp = readl(&power_regs->hw_power_5vctrl); + vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK; + vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT; + + pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO; + + /* + * Disable mechanisms that get erroneously tripped by when setting + * the DCDC4P2 EN_DCDC + */ + clrbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_VBUSVALID_5VDETECT | + POWER_5VCTRL_VBUSVALID_TRSH_MASK); + + writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set); + + if (xfer) { + setbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_DCDC_XFER); + early_delay(20); + clrbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_DCDC_XFER); + + setbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_ENABLE_DCDC); + } else { + setbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC); + } + + early_delay(25); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh); + + if (vbus_5vdetect) + writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set); + + if (!pwd_bo) + clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO); + + while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) + writel(POWER_CTRL_VBUS_VALID_IRQ, + &power_regs->hw_power_ctrl_clr); + + if (prev_5v_brnout) { + writel(POWER_5VCTRL_PWDN_5VBRNOUT, + &power_regs->hw_power_5vctrl_set); + writel(POWER_RESET_UNLOCK_KEY, + &power_regs->hw_power_reset); + } else { + writel(POWER_5VCTRL_PWDN_5VBRNOUT, + &power_regs->hw_power_5vctrl_clr); + writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, + &power_regs->hw_power_reset); + } + + while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ) + writel(POWER_CTRL_VDD5V_DROOP_IRQ, + &power_regs->hw_power_ctrl_clr); + + if (prev_5v_droop) + clrbits_le32(&power_regs->hw_power_ctrl, + POWER_CTRL_ENIRQ_VDD5V_DROOP); + else + setbits_le32(&power_regs->hw_power_ctrl, + POWER_CTRL_ENIRQ_VDD5V_DROOP); +} + +/** + * mxs_power_init_4p2_regulator() - Start the 4P2 regulator + * + * This function enables the 4P2 regulator and switches the DC-DC converter + * to use the 4P2 input. + */ +static void mxs_power_init_4p2_regulator(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t tmp, tmp2; + + debug("SPL: Enabling 4P2 regulator\n"); + + setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); + + writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set); + + writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + &power_regs->hw_power_5vctrl_clr); + clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK); + + /* Power up the 4p2 rail and logic/control */ + writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, + &power_regs->hw_power_5vctrl_clr); + + /* + * Start charging up the 4p2 capacitor. We ramp of this charge + * gradually to avoid large inrush current from the 5V cable which can + * cause transients/problems + */ + debug("SPL: Charging 4P2 capacitor\n"); + mxs_enable_4p2_dcdc_input(0); + + if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { + /* + * If we arrived here, we were unable to recover from mx23 chip + * errata 5837. 4P2 is disabled and sufficient battery power is + * not present. Exiting to not enable DCDC power during 5V + * connected state. + */ + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC); + writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, + &power_regs->hw_power_5vctrl_set); + + debug("SPL: Unable to recover from mx23 errata 5837\n"); + hang(); + } + + /* + * Here we set the 4p2 brownout level to something very close to 4.2V. + * We then check the brownout status. If the brownout status is false, + * the voltage is already close to the target voltage of 4.2V so we + * can go ahead and set the 4P2 current limit to our max target limit. + * If the brownout status is true, we need to ramp us the current limit + * so that we don't cause large inrush current issues. We step up the + * current limit until the brownout status is false or until we've + * reached our maximum defined 4p2 current limit. + */ + debug("SPL: Setting 4P2 brownout level\n"); + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_BO_MASK, + 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */ + + if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) { + setbits_le32(&power_regs->hw_power_5vctrl, + 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); + } else { + tmp = (readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >> + POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; + while (tmp < 0x3f) { + if (!(readl(&power_regs->hw_power_sts) & + POWER_STS_DCDC_4P2_BO)) { + tmp = readl(&power_regs->hw_power_5vctrl); + tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; + early_delay(100); + writel(tmp, &power_regs->hw_power_5vctrl); + break; + } else { + tmp++; + tmp2 = readl(&power_regs->hw_power_5vctrl); + tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; + tmp2 |= tmp << + POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; + writel(tmp2, &power_regs->hw_power_5vctrl); + early_delay(100); + } + } + } + + clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); + writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); +} + +/** + * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source + * + * This function configures the DC-DC converter to be supplied from the 4P2 + * linear regulator. + */ +static void mxs_power_init_dcdc_4p2_source(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Switching DC-DC converters to 4P2\n"); + + if (!(readl(&power_regs->hw_power_dcdc4p2) & + POWER_DCDC4P2_ENABLE_DCDC)) { + debug("SPL: Already switched - aborting\n"); + hang(); + } + + mxs_enable_4p2_dcdc_input(1); + + if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC); + writel(POWER_5VCTRL_ENABLE_DCDC, + &power_regs->hw_power_5vctrl_clr); + writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, + &power_regs->hw_power_5vctrl_set); + } +} + +/** + * mxs_power_enable_4p2() - Power up the 4P2 regulator + * + * This function drives the process of powering up the 4P2 linear regulator + * and switching the DC-DC converter input over to the 4P2 linear regulator. + */ +static void mxs_power_enable_4p2(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t vdddctrl, vddactrl, vddioctrl; + uint32_t tmp; + + debug("SPL: Powering up 4P2 regulator\n"); + + vdddctrl = readl(&power_regs->hw_power_vdddctrl); + vddactrl = readl(&power_regs->hw_power_vddactrl); + vddioctrl = readl(&power_regs->hw_power_vddioctrl); + + setbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | + POWER_VDDDCTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | + POWER_VDDACTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); + + mxs_power_init_4p2_params(); + mxs_power_init_4p2_regulator(); + + /* Shutdown battery (none present) */ + if (!mxs_is_batt_ready()) { + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_BO_MASK); + writel(POWER_CTRL_DCDC4P2_BO_IRQ, + &power_regs->hw_power_ctrl_clr); + writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, + &power_regs->hw_power_ctrl_clr); + } + + mxs_power_init_dcdc_4p2_source(); + + writel(vdddctrl, &power_regs->hw_power_vdddctrl); + early_delay(20); + writel(vddactrl, &power_regs->hw_power_vddactrl); + early_delay(20); + writel(vddioctrl, &power_regs->hw_power_vddioctrl); + + /* + * Check if FET is enabled on either powerout and if so, + * disable load. + */ + tmp = 0; + tmp |= !(readl(&power_regs->hw_power_vdddctrl) & + POWER_VDDDCTRL_DISABLE_FET); + tmp |= !(readl(&power_regs->hw_power_vddactrl) & + POWER_VDDACTRL_DISABLE_FET); + tmp |= !(readl(&power_regs->hw_power_vddioctrl) & + POWER_VDDIOCTRL_DISABLE_FET); + if (tmp) + writel(POWER_CHARGE_ENABLE_LOAD, + &power_regs->hw_power_charge_clr); + + debug("SPL: 4P2 regulator powered-up\n"); +} + +/** + * mxs_boot_valid_5v() - Boot from 5V supply + * + * This function configures the power block to boot from valid 5V input. + * This is called only if the 5V is reliable and can properly supply the + * CPU. This function proceeds to configure the 4P2 converter to be supplied + * from the 5V input. + */ +static void mxs_boot_valid_5v(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Booting from 5V supply\n"); + + /* + * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V + * disconnect event. FIXME + */ + writel(POWER_5VCTRL_VBUSVALID_5VDETECT, + &power_regs->hw_power_5vctrl_set); + + /* Configure polarity to check for 5V disconnection. */ + writel(POWER_CTRL_POLARITY_VBUSVALID | + POWER_CTRL_POLARITY_VDD5V_GT_VDDIO, + &power_regs->hw_power_ctrl_clr); + + writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ, + &power_regs->hw_power_ctrl_clr); + + mxs_power_enable_4p2(); +} + +/** + * mxs_powerdown() - Shut down the system + * + * This function powers down the CPU completely. + */ +static void mxs_powerdown(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("Powering Down\n"); + + writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset); + writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, + &power_regs->hw_power_reset); +} + +/** + * mxs_batt_boot() - Configure the power block to boot from battery input + * + * This function configures the power block to boot from the battery voltage + * supply. + */ +static void mxs_batt_boot(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Configuring power block to boot from battery\n"); + + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC); + + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2); + writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr); + + /* 5V to battery handoff. */ + setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); + early_delay(30); + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); + + writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr); + + clrsetbits_le32(&power_regs->hw_power_minpwr, + POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); + + mxs_power_set_linreg(); + + clrbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG); + + clrbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG); + + clrbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_DISABLE_FET); + + setbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_PWD_CHARGE_4P2_MASK); + + setbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_ENABLE_DCDC); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); + + mxs_power_enable_4p2(); +} + +/** + * mxs_handle_5v_conflict() - Test if the 5V input is reliable + * + * This function tests if the 5V input can reliably supply the system. If it + * can, then proceed to configuring the system to boot from 5V source, otherwise + * try booting from battery supply. If we can not boot from battery supply + * either, shut down the system. + */ +static void mxs_handle_5v_conflict(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t tmp; + + debug("SPL: Resolving 5V conflict\n"); + + setbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_BO_OFFSET_MASK); + + for (;;) { + tmp = readl(&power_regs->hw_power_sts); + + if (tmp & POWER_STS_VDDIO_BO) { + /* + * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes + * unreliable + */ + debug("SPL: VDDIO has a brownout\n"); + mxs_powerdown(); + break; + } + + if (tmp & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n"); + mxs_boot_valid_5v(); + break; + } else { + debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n"); + mxs_powerdown(); + break; + } + + /* + * TODO: I can't see this being reached. We'll either + * powerdown or boot from a stable 5V supply. + */ + if (tmp & POWER_STS_PSWITCH_MASK) { + debug("SPL: POWER_STS_PSWITCH_MASK is set\n"); + mxs_batt_boot(); + break; + } + } +} + +/** + * mxs_5v_boot() - Configure the power block to boot from 5V input + * + * This function handles configuration of the power block when supplied by + * a 5V input. + */ +static void mxs_5v_boot(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Configuring power block to boot from 5V input\n"); + + /* + * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID, + * but their implementation always returns 1 so we omit it here. + */ + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: 5V VDD good\n"); + mxs_boot_valid_5v(); + return; + } + + early_delay(1000); + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + debug("SPL: 5V VDD good (after delay)\n"); + mxs_boot_valid_5v(); + return; + } + + debug("SPL: 5V VDD not good\n"); + mxs_handle_5v_conflict(); +} + +/** + * mxs_init_batt_bo() - Configure battery brownout threshold + * + * This function configures the battery input brownout threshold. The value + * at which the battery brownout happens is configured to 3.0V in the code. + */ +static void mxs_init_batt_bo(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Initialising battery brown-out level to 3.0V\n"); + + /* Brownout at 3V */ + clrsetbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_BRWNOUT_LVL_MASK, + 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET); + + writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr); + writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr); +} + +/** + * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter + * + * This function turns off the VDDD linear regulator and therefore makes + * the VDDD rail be supplied only by the DC-DC converter. + */ +static void mxs_switch_vddd_to_dcdc_source(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Switching VDDD to DC-DC converters\n"); + + clrsetbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_LINREG_OFFSET_MASK, + POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); + + clrbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | + POWER_VDDDCTRL_DISABLE_STEPPING); +} + +/** + * mxs_power_configure_power_source() - Configure power block source + * + * This function is the core of the power configuration logic. The function + * selects the power block input source and configures the whole power block + * accordingly. After the configuration is complete and the system is stable + * again, the function switches the CPU clock source back to PLL. Finally, + * the function switches the voltage rails to DC-DC converter. + */ +static void mxs_power_configure_power_source(void) +{ + int batt_ready, batt_good; + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + struct mxs_lradc_regs *lradc_regs = + (struct mxs_lradc_regs *)MXS_LRADC_BASE; + + debug("SPL: Configuring power source\n"); + + mxs_src_power_init(); + + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + batt_ready = mxs_is_batt_ready(); + if (batt_ready) { + /* 5V source detected, good battery detected. */ + mxs_batt_boot(); + } else { + batt_good = mxs_is_batt_good(); + if (!batt_good) { + /* 5V source detected, bad battery detected. */ + writel(LRADC_CONVERSION_AUTOMATIC, + &lradc_regs->hw_lradc_conversion_clr); + clrbits_le32(&power_regs->hw_power_battmonitor, + POWER_BATTMONITOR_BATT_VAL_MASK); + } + mxs_5v_boot(); + } + } else { + /* 5V not detected, booting from battery. */ + mxs_batt_boot(); + } + + /* + * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced + * from USB VBUS + */ + mxs_power_clock2pll(); + + mxs_init_batt_bo(); + + mxs_switch_vddd_to_dcdc_source(); + +#ifdef CONFIG_MX23 + /* Fire up the VDDMEM LinReg now that we're all set. */ + debug("SPL: Enabling mx23 VDDMEM linear regulator\n"); + writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT, + &power_regs->hw_power_vddmemctrl); +#endif +} + +/** + * mxs_enable_output_rail_protection() - Enable power rail protection + * + * This function enables overload protection on the power rails. This is + * triggered if the power rails' voltage drops rapidly due to overload and + * in such case, the supply to the powerrail is cut-off, protecting the + * CPU from damage. Note that under such condition, the system will likely + * crash or misbehave. + */ +static void mxs_enable_output_rail_protection(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Enabling output rail protection\n"); + + writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | + POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr); + + setbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_PWDN_BRNOUT); +} + +/** + * mxs_get_vddio_power_source_off() - Get VDDIO rail power source + * + * This function tests if the VDDIO rail is supplied by linear regulator + * or by the DC-DC converter. Returns 1 if powered by linear regulator, + * returns 0 if powered by the DC-DC converter. + */ +static int mxs_get_vddio_power_source_off(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t tmp; + + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + tmp = readl(&power_regs->hw_power_vddioctrl); + if (tmp & POWER_VDDIOCTRL_DISABLE_FET) { + if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == + POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { + return 1; + } + } + + if (!(readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_ENABLE_DCDC)) { + if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == + POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { + return 1; + } + } + } + + return 0; + +} + +/** + * mxs_get_vddd_power_source_off() - Get VDDD rail power source + * + * This function tests if the VDDD rail is supplied by linear regulator + * or by the DC-DC converter. Returns 1 if powered by linear regulator, + * returns 0 if powered by the DC-DC converter. + */ +static int mxs_get_vddd_power_source_off(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t tmp; + + tmp = readl(&power_regs->hw_power_vdddctrl); + if (tmp & POWER_VDDDCTRL_DISABLE_FET) { + if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == + POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { + return 1; + } + } + + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { + if (!(readl(&power_regs->hw_power_5vctrl) & + POWER_5VCTRL_ENABLE_DCDC)) { + return 1; + } + } + + if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) { + if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == + POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) { + return 1; + } + } + + return 0; +} + +struct mxs_vddx_cfg { + uint32_t *reg; + uint8_t step_mV; + uint16_t lowest_mV; + int (*powered_by_linreg)(void); + uint32_t trg_mask; + uint32_t bo_irq; + uint32_t bo_enirq; + uint32_t bo_offset_mask; + uint32_t bo_offset_offset; +}; + +static const struct mxs_vddx_cfg mxs_vddio_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vddioctrl), +#if defined(CONFIG_MX23) + .step_mV = 25, +#else + .step_mV = 50, +#endif + .lowest_mV = 2800, + .powered_by_linreg = mxs_get_vddio_power_source_off, + .trg_mask = POWER_VDDIOCTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDIO_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO, + .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET, +}; + +static const struct mxs_vddx_cfg mxs_vddd_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vdddctrl), + .step_mV = 25, + .lowest_mV = 800, + .powered_by_linreg = mxs_get_vddd_power_source_off, + .trg_mask = POWER_VDDDCTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDD_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO, + .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET, +}; + +#ifdef CONFIG_MX23 +static const struct mxs_vddx_cfg mxs_vddmem_cfg = { + .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> + hw_power_vddmemctrl), + .step_mV = 50, + .lowest_mV = 1700, + .powered_by_linreg = NULL, + .trg_mask = POWER_VDDMEMCTRL_TRG_MASK, + .bo_irq = 0, + .bo_enirq = 0, + .bo_offset_mask = 0, + .bo_offset_offset = 0, +}; +#endif + +/** + * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail + * @cfg: Configuration data of the DC-DC converter rail + * @new_target: New target voltage of the DC-DC converter rail + * @new_brownout: New brownout trigger voltage + * + * This function configures the output voltage on the DC-DC converter rail. + * The rail is selected by the @cfg argument. The new voltage target is + * selected by the @new_target and the voltage is specified in mV. The + * new brownout value is selected by the @new_brownout argument and the + * value is also in mV. + */ +static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, + uint32_t new_target, uint32_t new_brownout) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + uint32_t cur_target, diff, bo_int = 0; + uint32_t powered_by_linreg = 0; + int adjust_up, tmp; + + new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout, + cfg->step_mV); + + cur_target = readl(cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; + + adjust_up = new_target > cur_target; + if (cfg->powered_by_linreg) + powered_by_linreg = cfg->powered_by_linreg(); + + if (adjust_up && cfg->bo_irq) { + if (powered_by_linreg) { + bo_int = readl(cfg->reg); + clrbits_le32(cfg->reg, cfg->bo_enirq); + } + setbits_le32(cfg->reg, cfg->bo_offset_mask); + } + + do { + if (abs(new_target - cur_target) > 100) { + if (adjust_up) + diff = cur_target + 100; + else + diff = cur_target - 100; + } else { + diff = new_target; + } + + diff -= cfg->lowest_mV; + diff /= cfg->step_mV; + + clrsetbits_le32(cfg->reg, cfg->trg_mask, diff); + + if (powered_by_linreg || + (readl(&power_regs->hw_power_sts) & + POWER_STS_VDD5V_GT_VDDIO)) + early_delay(500); + else { + for (;;) { + tmp = readl(&power_regs->hw_power_sts); + if (tmp & POWER_STS_DC_OK) + break; + } + } + + cur_target = readl(cfg->reg); + cur_target &= cfg->trg_mask; + cur_target *= cfg->step_mV; + cur_target += cfg->lowest_mV; + } while (new_target > cur_target); + + if (cfg->bo_irq) { + if (adjust_up && powered_by_linreg) { + writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr); + if (bo_int & cfg->bo_enirq) + setbits_le32(cfg->reg, cfg->bo_enirq); + } + + clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, + new_brownout << cfg->bo_offset_offset); + } +} + +/** + * mxs_setup_batt_detect() - Start the battery voltage measurement logic + * + * This function starts and configures the LRADC block. This allows the + * power initialization code to measure battery voltage and based on this + * knowledge, decide whether to boot at all, boot from battery or boot + * from 5V input. + */ +static void mxs_setup_batt_detect(void) +{ + debug("SPL: Starting battery voltage measurement logic\n"); + + mxs_lradc_init(); + mxs_lradc_enable_batt_measurement(); + early_delay(10); +} + +/** + * mxs_ungate_power() - Ungate the POWER block + * + * This function ungates clock to the power block. In case the power block + * was still gated at this point, it will not be possible to configure the + * block and therefore the power initialization would fail. This function + * is only needed on i.MX233, on i.MX28 the power block is always ungated. + */ +static void mxs_ungate_power(void) +{ +#ifdef CONFIG_MX23 + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr); +#endif +} + +/** + * mxs_power_init() - The power block init main function + * + * This function calls all the power block initialization functions in + * proper sequence to start the power block. + */ +void mxs_power_init(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Initialising Power Block\n"); + + mxs_ungate_power(); + + mxs_power_clock2xtal(); + mxs_power_set_auto_restart(); + mxs_power_set_linreg(); + mxs_power_setup_5v_detect(); + + mxs_setup_batt_detect(); + + mxs_power_configure_power_source(); + mxs_enable_output_rail_protection(); + + debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n"); + mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); + + debug("SPL: Setting VDDD to 1V5 (brownout @ 1v0)\n"); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); +#ifdef CONFIG_MX23 + debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n"); + mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); +#endif + writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | + POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | + POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ | + POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); + + writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); + + early_delay(1000); +} + +#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT +/** + * mxs_power_wait_pswitch() - Wait for power switch to be pressed + * + * This function waits until the power-switch was pressed to start booting + * the board. + */ +void mxs_power_wait_pswitch(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)MXS_POWER_BASE; + + debug("SPL: Waiting for power switch input\n"); + while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK)) + ; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/start.S b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/start.S new file mode 100644 index 0000000..48abcd5 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/start.S
@@ -0,0 +1,96 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ + * + * Copyright (c) 2001 Marius Groger <mag@sysgo.de> + * Copyright (c) 2002 Alex Zupke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> + * + * Change to support call back into iMX28 bootrom + * Copyright (c) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <common.h> + +/* + ************************************************************************* + * + * 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 + * + ************************************************************************* + */ + + .globl reset +reset: + /* + * If the CPU is configured in "Wait JTAG connection mode", the stack + * pointer is not configured and is zero. This will cause crash when + * trying to push data onto stack right below here. Load the SP and make + * it point to the end of OCRAM if the SP is zero. + */ + cmp sp, #0x00000000 + ldreq sp, =CONFIG_SYS_INIT_SP_ADDR + + /* + * Store all registers on old stack pointer, this will allow us later to + * return to the BootROM and let the BootROM load U-Boot into RAM. + * + * WARNING: Register r0 and r1 are used by the BootROM to pass data + * to the called code. Register r0 will contain arbitrary + * data that are set in the BootStream. In case this code + * was started with CALL instruction, register r1 will contain + * pointer to the return value this function can then set. + * The code below MUST NOT CHANGE register r0 and r1 ! + */ + push {r0-r12,r14} + + /* Save control register c1 */ + mrc p15, 0, r2, c1, c0, 0 + push {r2} + + /* Set the cpu to SVC32 mode and store old CPSR register content. */ + mrs r2, cpsr + push {r2} + bic r2, r2, #0x1f + orr r2, r2, #0xd3 + msr cpsr, r2 + + bl board_init_ll + + /* Restore BootROM's CPU mode (especially FIQ). */ + pop {r2} + msr cpsr,r2 + + /* + * Restore c1 register. Especially set exception vector location + * back to BootROM space which is required by bootrom for USB boot. + */ + pop {r2} + mcr p15, 0, r2, c1, c0, 0 + + pop {r0-r12,r14} + + /* + * In case this code was started by the CALL instruction, the register + * r0 is examined by the BootROM after this code returns. The value in + * r0 must be set to 0 to indicate successful return. + */ + mov r0, #0 + + bx lr
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/timer.c new file mode 100644 index 0000000..f2e7225 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/timer.c
@@ -0,0 +1,161 @@ +/* + * Freescale i.MX28 timer driver + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * Based on code from LTIB: + * (C) Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> + +/* Maximum fixed count */ +#if defined(CONFIG_MX23) +#define TIMER_LOAD_VAL 0xffff +#elif defined(CONFIG_MX28) +#define TIMER_LOAD_VAL 0xffffffff +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp (gd->arch.tbl) +#define lastdec (gd->arch.lastinc) + +/* + * This driver uses 1kHz clock source. + */ +#define MXS_INCREMENTER_HZ 1000 + +static inline unsigned long tick_to_time(unsigned long tick) +{ + return tick / (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ); +} + +static inline unsigned long time_to_tick(unsigned long time) +{ + return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ); +} + +/* Calculate how many ticks happen in "us" microseconds */ +static inline unsigned long us_to_tick(unsigned long us) +{ + return (us * MXS_INCREMENTER_HZ) / 1000000; +} + +int timer_init(void) +{ + struct mxs_timrot_regs *timrot_regs = + (struct mxs_timrot_regs *)MXS_TIMROT_BASE; + + /* Reset Timers and Rotary Encoder module */ + mxs_reset_block(&timrot_regs->hw_timrot_rotctrl_reg); + + /* Set fixed_count to 0 */ +#if defined(CONFIG_MX23) + writel(0, &timrot_regs->hw_timrot_timcount0); +#elif defined(CONFIG_MX28) + writel(0, &timrot_regs->hw_timrot_fixed_count0); +#endif + + /* Set UPDATE bit and 1Khz frequency */ + writel(TIMROT_TIMCTRLn_UPDATE | TIMROT_TIMCTRLn_RELOAD | + TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL, + &timrot_regs->hw_timrot_timctrl0); + + /* Set fixed_count to maximal value */ +#if defined(CONFIG_MX23) + writel(TIMER_LOAD_VAL - 1, &timrot_regs->hw_timrot_timcount0); +#elif defined(CONFIG_MX28) + writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0); +#endif + + return 0; +} + +unsigned long long get_ticks(void) +{ + struct mxs_timrot_regs *timrot_regs = + (struct mxs_timrot_regs *)MXS_TIMROT_BASE; + uint32_t now; + + /* Current tick value */ +#if defined(CONFIG_MX23) + /* Upper bits are the valid ones. */ + now = readl(&timrot_regs->hw_timrot_timcount0) >> + TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET; +#elif defined(CONFIG_MX28) + now = readl(&timrot_regs->hw_timrot_running_count0); +#else +#error "Don't know how to read timrot_regs" +#endif + + if (lastdec >= now) { + /* + * normal mode (non roll) + * move stamp forward with absolut diff ticks + */ + timestamp += (lastdec - now); + } else { + /* we have rollover of decrementer */ + timestamp += (TIMER_LOAD_VAL - now) + lastdec; + + } + lastdec = now; + + return timestamp; +} + +ulong get_timer_masked(void) +{ + return tick_to_time(get_ticks()); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */ +#define MXS_HW_DIGCTL_MICROSECONDS 0x8001c0c0 + +void __udelay(unsigned long usec) +{ + uint32_t old, new, incr; + uint32_t counter = 0; + + old = readl(MXS_HW_DIGCTL_MICROSECONDS); + + while (counter < usec) { + new = readl(MXS_HW_DIGCTL_MICROSECONDS); + + /* Check if the timer wrapped. */ + if (new < old) { + incr = 0xffffffff - old; + incr += new; + } else { + incr = new - old; + } + + /* + * Check if we are close to the maximum time and the counter + * would wrap if incremented. If that's the case, break out + * from the loop as the requested delay time passed. + */ + if (counter + incr < counter) + break; + + counter += incr; + old = new; + } +} + +ulong get_tbclk(void) +{ + return MXS_INCREMENTER_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd new file mode 100644 index 0000000..3a51879 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx23.bd
@@ -0,0 +1,18 @@ +options { + driveTag = 0x00; + flags = 0x01; +} + +sources { + u_boot_spl="spl/u-boot-spl.bin"; + u_boot="u-boot.bin"; +} + +section (0) { + load u_boot_spl > 0x0000; + load ivt (entry = 0x0014) > 0x8000; + call 0x8000; + + load u_boot > 0x40000100; + call 0x40000100; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd new file mode 100644 index 0000000..c60615a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
@@ -0,0 +1,14 @@ +sources { + u_boot_spl="spl/u-boot-spl.bin"; + u_boot="u-boot.bin"; +} + +section (0) { + load u_boot_spl > 0x0000; + load ivt (entry = 0x0014) > 0x8000; + hab call 0x8000; + + load u_boot > 0x40000100; + load ivt (entry = 0x40000100) > 0x8000; + hab call 0x8000; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds new file mode 100644 index 0000000..bf2ac13 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
@@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = CONFIG_SPL_TEXT_BASE; + + . = ALIGN(4); + .text : + { + *(.vectors) + arch/arm/cpu/arm926ejs/mxs/start.o (.text*) + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } + + .end : + { + *(.__end) + } + + _image_binary_end = .; + + .dynsym _image_binary_end : { *(.dynsym) } + .dynbss : { *(.dynbss) } + .dynstr : { *(.dynstr*) } + .dynamic : { *(.dynamic*) } + .hash : { *(.hash*) } + .plt : { *(.plt*) } + .interp : { *(.interp*) } + .gnu : { *(.gnu*) } + .ARM.exidx : { *(.ARM.exidx*) } +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/omap/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/Makefile new file mode 100644 index 0000000..add9232 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/Makefile
@@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = timer.o +obj-$(CONFIG_DISPLAY_CPUINFO) += cpuinfo.o +obj-y += reset.o
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/omap/cpuinfo.c b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/cpuinfo.c new file mode 100644 index 0000000..587d99a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/cpuinfo.c
@@ -0,0 +1,242 @@ +/* + * OMAP1 CPU identification code + * + * Copyright (C) 2004 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.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. + */ + +#include <common.h> +#include <command.h> +#include <linux/compiler.h> + +#if defined(CONFIG_OMAP) + +#define omap_readw(x) *(volatile unsigned short *)(x) +#define omap_readl(x) *(volatile unsigned long *)(x) + +#define OMAP_DIE_ID_0 0xfffe1800 +#define OMAP_DIE_ID_1 0xfffe1804 +#define OMAP_PRODUCTION_ID_0 0xfffe2000 +#define OMAP_PRODUCTION_ID_1 0xfffe2004 +#define OMAP32_ID_0 0xfffed400 +#define OMAP32_ID_1 0xfffed404 + +struct omap_id { + u16 jtag_id; /* Used to determine OMAP type */ + u8 die_rev; /* Processor revision */ + u32 omap_id; /* OMAP revision */ + u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */ +}; + +/* Register values to detect the OMAP version */ +static struct omap_id omap_ids[] = { + { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000}, + { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100}, + { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300}, + { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000}, + { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00}, + { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00}, + { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000}, + { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00}, + { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00}, + { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300}, + { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300}, + { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000}, + { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000}, +}; + +/* + * Get OMAP type from PROD_ID. + * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM. + * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense. + * Undocumented register in TEST BLOCK is used as fallback; This seems to + * work on 1510, 1610 & 1710. The official way hopefully will work in future + * processors. + */ +static u16 omap_get_jtag_id(void) +{ + u32 prod_id, omap_id; + + prod_id = omap_readl(OMAP_PRODUCTION_ID_1); + omap_id = omap_readl(OMAP32_ID_1); + + /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */ + if (((prod_id >> 20) == 0) || (prod_id == omap_id)) + prod_id = 0; + else + prod_id &= 0xffff; + + if (prod_id) + return prod_id; + + /* Use OMAP32_ID_1 as fallback */ + prod_id = ((omap_id >> 12) & 0xffff); + + return prod_id; +} + +/* + * Get OMAP revision from DIE_REV. + * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID. + * Undocumented register in the TEST BLOCK is used as fallback. + * REVISIT: This does not seem to work on 1510 + */ +static u8 omap_get_die_rev(void) +{ + u32 die_rev; + + die_rev = omap_readl(OMAP_DIE_ID_1); + + /* Check for broken OMAP_DIE_ID on early 1710 */ + if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id()) + die_rev = 0; + + die_rev = (die_rev >> 17) & 0xf; + if (die_rev) + return die_rev; + + die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf; + + return die_rev; +} + +static unsigned long dpll1(void) +{ + unsigned short pll_ctl_val = omap_readw(DPLL_CTL_REG); + unsigned long rate; + + rate = CONFIG_SYS_CLK_FREQ; /* Base xtal rate */ + if (pll_ctl_val & 0x10) { + /* PLL enabled, apply multiplier and divisor */ + if (pll_ctl_val & 0xf80) + rate *= (pll_ctl_val & 0xf80) >> 7; + rate /= ((pll_ctl_val & 0x60) >> 5) + 1; + } else { + /* PLL disabled, apply bypass divisor */ + switch (pll_ctl_val & 0xc) { + case 0: + break; + case 0x4: + rate /= 2; + break; + default: + rate /= 4; + break; + } + } + + return rate; +} + +static unsigned long armcore(void) +{ + unsigned short arm_ckctl = omap_readw(ARM_CKCTL); + + return (dpll1() >> ((arm_ckctl & 0x0030) >> 4)); +} + +int print_cpuinfo (void) +{ + int i; + u16 jtag_id; + u8 die_rev; + u32 omap_id; + u8 cpu_type; + __maybe_unused u32 system_serial_high; + __maybe_unused u32 system_serial_low; + u32 system_rev = 0; + + jtag_id = omap_get_jtag_id(); + die_rev = omap_get_die_rev(); + omap_id = omap_readl(OMAP32_ID_0); + +#ifdef DEBUG + printf("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0)); + printf("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n", + omap_readl(OMAP_DIE_ID_1), + (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf); + printf("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0)); + printf("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n", + omap_readl(OMAP_PRODUCTION_ID_1), + omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff); + printf("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0)); + printf("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1)); + printf("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev); +#endif + + system_serial_high = omap_readl(OMAP_DIE_ID_0); + system_serial_low = omap_readl(OMAP_DIE_ID_1); + + /* First check only the major version in a safe way */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == (omap_ids[i].jtag_id)) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Check if we can find the die revision */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Finally check also the omap_id */ + for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { + if (jtag_id == omap_ids[i].jtag_id + && die_rev == omap_ids[i].die_rev + && omap_id == omap_ids[i].omap_id) { + system_rev = omap_ids[i].type; + break; + } + } + + /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */ + cpu_type = system_rev >> 24; + + switch (cpu_type) { + case 0x07: + system_rev |= 0x07; + break; + case 0x03: + case 0x15: + system_rev |= 0x15; + break; + case 0x16: + case 0x17: + system_rev |= 0x16; + break; + case 0x24: + system_rev |= 0x24; + break; + default: + printf("Unknown OMAP cpu type: 0x%02x\n", cpu_type); + } + + printf("CPU: OMAP%04x", system_rev >> 16); + if ((system_rev >> 8) & 0xff) + printf("%x", (system_rev >> 8) & 0xff); +#ifdef DEBUG + printf(" revision %i handled as %02xxx id: %08x%08x", + die_rev, system_rev & 0xff, system_serial_low, system_serial_high); +#endif + printf(" at %ld.%01ld MHz (DPLL1=%ld.%01ld MHz)\n", + armcore() / 1000000, (armcore() / 100000) % 10, + dpll1() / 1000000, (dpll1() / 100000) % 10); + + return 0; +} + +#endif /* #if defined(CONFIG_OMAP) */
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/omap/reset.S b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/reset.S new file mode 100644 index 0000000..1c557b0 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/reset.S
@@ -0,0 +1,29 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 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 <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + .align 5 +.globl reset_cpu +reset_cpu: + ldr r1, rstctl1 /* get clkm1 reset ctl */ + mov r3, #0x0 + strh r3, [r1] /* clear it */ + mov r3, #0x8 + strh r3, [r1] /* force dsp+arm reset */ +_loop_forever: + b _loop_forever + +rstctl1: + .word 0xfffece10
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/omap/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/timer.c new file mode 100644 index 0000000..b971565 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/omap/timer.c
@@ -0,0 +1,152 @@ +/* + * (C) Copyright 2003 + * Texas Instruments <www.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-2004 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV)) +#define TIMER_LOAD_VAL 0xffffffff + +/* macro to read the 32 bit timer */ +#define READ_TIMER readl(CONFIG_SYS_TIMERBASE+8) \ + / (TIMER_CLOCK / CONFIG_SYS_HZ) + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +int timer_init (void) +{ + int32_t val; + + /* Start the decrementer ticking down from 0xffffffff */ + *((int32_t *) (CONFIG_SYS_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL; + val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CONFIG_SYS_PTV << MPUTIM_PTV_BIT); + *((int32_t *) (CONFIG_SYS_TIMERBASE + CNTL_TIMER)) = val; + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +/* delay x useconds AND preserve advance timestamp 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 *= CONFIG_SYS_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 * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + tmp = get_timer (0); /* get current timestamp */ + if( (tmo + tmp + 1) < 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*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; /* capure current decrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +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 / (TIMER_CLOCK / + CONFIG_SYS_HZ)) - now; + } + lastdec = now; + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + tmo *= CONFIG_SYS_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 * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/orion5x/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/arm926ejs/orion5x/u-boot-spl.lds new file mode 100644 index 0000000..6f7fca0 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/orion5x/u-boot-spl.lds
@@ -0,0 +1,61 @@ +/* + * (C) Copyright 2014 Albert ARIBAUD <albert.u.boot@aribaud.net> + * + * Based on: + * + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * Tom Cubie <tangliang@allwinnertech.com> + * + * Based on omap-common/u-boot-spl.lds: + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +MEMORY { .nor : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .bss : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + CPUDIR/start.o (.text) + *(.text*) + } > .nor + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.nor + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.nor + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } > .nor + + . = ALIGN(4); + __image_copy_end = .; + _end = .; + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } > .bss +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/Makefile b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/Makefile new file mode 100644 index 0000000..3f190bc --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/Makefile
@@ -0,0 +1,21 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := cpu.o \ + reset.o \ + timer.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o spl_boot.o +obj-$(CONFIG_SPEAR600) += spear600.o +obj-$(CONFIG_DDR_MT47H64M16) += spr600_mt47h64m16_3_333_cl5_psync.o +obj-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_333_cl5_psync.o +obj-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_37e_166_cl4_sync.o +obj-$(CONFIG_DDR_MT47H128M8) += spr600_mt47h128m8_3_266_cl5_async.o +endif + +extra-$(CONFIG_SPL_BUILD) := start.o
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/cpu.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/cpu.c new file mode 100644 index 0000000..697e094 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/cpu.c
@@ -0,0 +1,71 @@ +/* + * (C) Copyright 2010 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/spr_misc.h> + +int arch_cpu_init(void) +{ + struct misc_regs *const misc_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 periph1_clken, periph_clk_cfg; + + periph1_clken = readl(&misc_p->periph1_clken); + +#if defined(CONFIG_SPEAR3XX) + periph1_clken |= MISC_GPT2ENB; +#elif defined(CONFIG_SPEAR600) + periph1_clken |= MISC_GPT3ENB; +#endif + +#if defined(CONFIG_PL011_SERIAL) + periph1_clken |= MISC_UART0ENB; + + periph_clk_cfg = readl(&misc_p->periph_clk_cfg); + periph_clk_cfg &= ~CONFIG_SPEAR_UARTCLKMSK; + periph_clk_cfg |= CONFIG_SPEAR_UART48M; + writel(periph_clk_cfg, &misc_p->periph_clk_cfg); +#endif +#if defined(CONFIG_DESIGNWARE_ETH) + periph1_clken |= MISC_ETHENB; +#endif +#if defined(CONFIG_DW_UDC) + periph1_clken |= MISC_USBDENB; +#endif +#if defined(CONFIG_SYS_I2C_DW) + periph1_clken |= MISC_I2CENB; +#endif +#if defined(CONFIG_ST_SMI) + periph1_clken |= MISC_SMIENB; +#endif +#if defined(CONFIG_NAND_FSMC) + periph1_clken |= MISC_FSMCENB; +#endif + + writel(periph1_clken, &misc_p->periph1_clken); + return 0; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ +#ifdef CONFIG_SPEAR300 + printf("CPU: SPEAr300\n"); +#elif defined(CONFIG_SPEAR310) + printf("CPU: SPEAr310\n"); +#elif defined(CONFIG_SPEAR320) + printf("CPU: SPEAr320\n"); +#elif defined(CONFIG_SPEAR600) + printf("CPU: SPEAr600\n"); +#else +#error CPU not supported in spear platform +#endif + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/reset.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/reset.c new file mode 100644 index 0000000..9546e80 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/reset.c
@@ -0,0 +1,38 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/spr_syscntl.h> + +void reset_cpu(ulong ignored) +{ + struct syscntl_regs *syscntl_regs_p = + (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE; + + printf("System is going to reboot ...\n"); + + /* + * This 1 second delay will allow the above message + * to be printed before reset + */ + udelay((1000 * 1000)); + + /* Going into slow mode before resetting SOC */ + writel(0x02, &syscntl_regs_p->scctrl); + + /* + * Writing any value to the system status register will + * reset the SoC + */ + writel(0x00, &syscntl_regs_p->scsysstat); + + /* system will restart */ + while (1) + ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spear600.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spear600.c new file mode 100644 index 0000000..6474e9d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spear600.c
@@ -0,0 +1,217 @@ +/* + * (C) Copyright 2000-2009 + * Viresh Kumar, ST Microelectronics, viresh.kumar@st.com + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/arch/spr_misc.h> +#include <asm/arch/spr_defs.h> + +static void sel_1v8(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddr1v8, ddr2v5; + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000003; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000010; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + while (!(readl(&misc_p->ddr_1v8_compensation) & DDR_COMP_ACCURATE)) + ; +} + +static void sel_2v5(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddr1v8, ddr2v5; + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000003; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000010; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + while (!(readl(&misc_p->ddr_2v5_compensation) & DDR_COMP_ACCURATE)) + ; +} + +/* + * plat_ddr_init: + */ +void plat_ddr_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 ddrpad; + u32 core3v3, ddr1v8, ddr2v5; + + /* DDR pad register configurations */ + ddrpad = readl(&misc_p->ddr_pad); + ddrpad &= ~DDR_PAD_CNF_MSK; + +#if (CONFIG_DDR_HCLK) + ddrpad |= 0xEAAB; +#elif (CONFIG_DDR_2HCLK) + ddrpad |= 0xEAAD; +#elif (CONFIG_DDR_PLL2) + ddrpad |= 0xEAAD; +#endif + writel(ddrpad, &misc_p->ddr_pad); + + /* Compensation register configurations */ + core3v3 = readl(&misc_p->core_3v3_compensation); + core3v3 &= 0x8080ffe0; + core3v3 |= 0x78000002; + writel(core3v3, &misc_p->core_3v3_compensation); + + ddr1v8 = readl(&misc_p->ddr_1v8_compensation); + ddr1v8 &= 0x8080ffc0; + ddr1v8 |= 0x78000004; + writel(ddr1v8, &misc_p->ddr_1v8_compensation); + + ddr2v5 = readl(&misc_p->ddr_2v5_compensation); + ddr2v5 &= 0x8080ffc0; + ddr2v5 |= 0x78000004; + writel(ddr2v5, &misc_p->ddr_2v5_compensation); + + if ((readl(&misc_p->ddr_pad) & DDR_PAD_SW_CONF) == DDR_PAD_SW_CONF) { + /* Software memory configuration */ + if (readl(&misc_p->ddr_pad) & DDR_PAD_SSTL_SEL) + sel_1v8(); + else + sel_2v5(); + } else { + /* Hardware memory configuration */ + if (readl(&misc_p->ddr_pad) & DDR_PAD_DRAM_TYPE) + sel_1v8(); + else + sel_2v5(); + } +} + +/* + * soc_init: + */ +void soc_init(void) +{ + /* Nothing to be done for SPEAr600 */ +} + +/* + * xxx_boot_selected: + * + * return true if the particular booting option is selected + * return false otherwise + */ +static u32 read_bootstrap(void) +{ + return (readl(CONFIG_SPEAR_BOOTSTRAPCFG) >> CONFIG_SPEAR_BOOTSTRAPSHFT) + & CONFIG_SPEAR_BOOTSTRAPMASK; +} + +int snor_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (SNOR_BOOT_SUPPORTED) { + /* Check whether SNOR boot is selected */ + if ((bootstrap & CONFIG_SPEAR_ONLYSNORBOOT) == + CONFIG_SPEAR_ONLYSNORBOOT) + return true; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND8BOOT) + return true; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND16BOOT) + return true; + } + + return false; +} + +int nand_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (NAND_BOOT_SUPPORTED) { + /* Check whether NAND boot is selected */ + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND8BOOT) + return true; + + if ((bootstrap & CONFIG_SPEAR_NORNANDBOOT) == + CONFIG_SPEAR_NORNAND16BOOT) + return true; + } + + return false; +} + +int pnor_boot_selected(void) +{ + /* Parallel NOR boot is not selected in any SPEAr600 revision */ + return false; +} + +int usb_boot_selected(void) +{ + u32 bootstrap = read_bootstrap(); + + if (USB_BOOT_SUPPORTED) { + /* Check whether USB boot is selected */ + if (!(bootstrap & CONFIG_SPEAR_USBBOOT)) + return true; + } + + return false; +} + +int tftp_boot_selected(void) +{ + /* TFTP boot is not selected in any SPEAr600 revision */ + return false; +} + +int uart_boot_selected(void) +{ + /* UART boot is not selected in any SPEAr600 revision */ + return false; +} + +int spi_boot_selected(void) +{ + /* SPI boot is not selected in any SPEAr600 revision */ + return false; +} + +int i2c_boot_selected(void) +{ + /* I2C boot is not selected in any SPEAr600 revision */ + return false; +} + +int mmc_boot_selected(void) +{ + return false; +} + +void plat_late_init(void) +{ + spear_late_init(); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl.c new file mode 100644 index 0000000..b550404 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -0,0 +1,259 @@ +/* + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * Copyright (C) 2012 Stefan Roese <sr@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <version.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/spr_defs.h> +#include <asm/arch/spr_misc.h> +#include <asm/arch/spr_syscntl.h> + +static void ddr_clock_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 clkenb, ddrpll; + + clkenb = readl(&misc_p->periph1_clken); + clkenb &= ~PERIPH_MPMCMSK; + clkenb |= PERIPH_MPMC_WE; + + /* Intentionally done twice */ + writel(clkenb, &misc_p->periph1_clken); + writel(clkenb, &misc_p->periph1_clken); + + ddrpll = readl(&misc_p->pll_ctr_reg); + ddrpll &= ~MEM_CLK_SEL_MSK; +#if (CONFIG_DDR_HCLK) + ddrpll |= MEM_CLK_HCLK; +#elif (CONFIG_DDR_2HCLK) + ddrpll |= MEM_CLK_2HCLK; +#elif (CONFIG_DDR_PLL2) + ddrpll |= MEM_CLK_PLL2; +#else +#error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)" +#endif + writel(ddrpll, &misc_p->pll_ctr_reg); + + writel(readl(&misc_p->periph1_clken) | PERIPH_MPMC_EN, + &misc_p->periph1_clken); +} + +static void mpmc_init_values(void) +{ + u32 i; + u32 *mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE; + u32 *mpmc_val_p = &mpmc_conf_vals[0]; + + for (i = 0; i < CONFIG_SPEAR_MPMCREGS; i++, mpmc_reg_p++, mpmc_val_p++) + writel(*mpmc_val_p, mpmc_reg_p); + + mpmc_reg_p = (u32 *)CONFIG_SPEAR_MPMCBASE; + + /* + * MPMC controller start + * MPMC waiting for DLLLOCKREG high + */ + writel(0x01000100, &mpmc_reg_p[7]); + + while (!(readl(&mpmc_reg_p[3]) & 0x10000)) + ; +} + +static void mpmc_init(void) +{ + /* Clock related settings for DDR */ + ddr_clock_init(); + + /* + * DDR pad register bits are different for different SoCs + * Compensation values are also handled separately + */ + plat_ddr_init(); + + /* Initialize mpmc register values */ + mpmc_init_values(); +} + +static void pll_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + /* Initialize PLLs */ + writel(FREQ_332, &misc_p->pll1_frq); + writel(0x1C0A, &misc_p->pll1_cntl); + writel(0x1C0E, &misc_p->pll1_cntl); + writel(0x1C06, &misc_p->pll1_cntl); + writel(0x1C0E, &misc_p->pll1_cntl); + + writel(FREQ_332, &misc_p->pll2_frq); + writel(0x1C0A, &misc_p->pll2_cntl); + writel(0x1C0E, &misc_p->pll2_cntl); + writel(0x1C06, &misc_p->pll2_cntl); + writel(0x1C0E, &misc_p->pll2_cntl); + + /* wait for pll locks */ + while (!(readl(&misc_p->pll1_cntl) & 0x1)) + ; + while (!(readl(&misc_p->pll2_cntl) & 0x1)) + ; +} + +static void mac_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + writel(readl(&misc_p->periph1_clken) & (~PERIPH_GMAC), + &misc_p->periph1_clken); + + writel(SYNTH23, &misc_p->gmac_synth_clk); + + switch (get_socrev()) { + case SOC_SPEAR600_AA: + case SOC_SPEAR600_AB: + case SOC_SPEAR600_BA: + case SOC_SPEAR600_BB: + case SOC_SPEAR600_BC: + case SOC_SPEAR600_BD: + writel(0x0, &misc_p->gmac_ctr_reg); + break; + + case SOC_SPEAR300: + case SOC_SPEAR310: + case SOC_SPEAR320: + writel(0x4, &misc_p->gmac_ctr_reg); + break; + } + + writel(readl(&misc_p->periph1_clken) | PERIPH_GMAC, + &misc_p->periph1_clken); + + writel(readl(&misc_p->periph1_rst) | PERIPH_GMAC, + &misc_p->periph1_rst); + writel(readl(&misc_p->periph1_rst) & (~PERIPH_GMAC), + &misc_p->periph1_rst); +} + +static void sys_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + struct syscntl_regs *syscntl_p = + (struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE; + + /* Set system state to SLOW */ + writel(SLOW, &syscntl_p->scctrl); + writel(PLL_TIM << 3, &syscntl_p->scpllctrl); + + /* Initialize PLLs */ + pll_init(); + + /* + * Ethernet configuration + * To be done only if the tftp boot is not selected already + * Boot code ensures the correct configuration in tftp booting + */ + if (!tftp_boot_selected()) + mac_init(); + + writel(RTC_DISABLE | PLLTIMEEN, &misc_p->periph_clk_cfg); + writel(0x555, &misc_p->amba_clk_cfg); + + writel(NORMAL, &syscntl_p->scctrl); + + /* Wait for system to switch to normal mode */ + while (((readl(&syscntl_p->scctrl) >> MODE_SHIFT) & MODE_MASK) + != NORMAL) + ; +} + +/* + * get_socrev + * + * Get SoC Revision. + * @return SOC_SPEARXXX + */ +int get_socrev(void) +{ +#if defined(CONFIG_SPEAR600) + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + u32 soc_id = readl(&misc_p->soc_core_id); + u32 pri_socid = (soc_id >> SOC_PRI_SHFT) & 0xFF; + u32 sec_socid = (soc_id >> SOC_SEC_SHFT) & 0xFF; + + if ((pri_socid == 'B') && (sec_socid == 'B')) + return SOC_SPEAR600_BB; + else if ((pri_socid == 'B') && (sec_socid == 'C')) + return SOC_SPEAR600_BC; + else if ((pri_socid == 'B') && (sec_socid == 'D')) + return SOC_SPEAR600_BD; + else if (soc_id == 0) + return SOC_SPEAR600_BA; + else + return SOC_SPEAR_NA; +#elif defined(CONFIG_SPEAR300) + return SOC_SPEAR300; +#elif defined(CONFIG_SPEAR310) + return SOC_SPEAR310; +#elif defined(CONFIG_SPEAR320) + return SOC_SPEAR320; +#endif +} + +void lowlevel_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + const char *u_boot_rev = U_BOOT_VERSION; + + /* Initialize PLLs */ + sys_init(); + + /* Initialize UART */ + serial_init(); + + /* Print U-Boot SPL version string */ + serial_puts("\nU-Boot SPL "); + /* Avoid a second "U-Boot" coming from this string */ + u_boot_rev = &u_boot_rev[7]; + serial_puts(u_boot_rev); + serial_puts(" ("); + serial_puts(U_BOOT_DATE); + serial_puts(" - "); + serial_puts(U_BOOT_TIME); + serial_puts(")\n"); + +#if defined(CONFIG_OS_BOOT) + writel(readl(&misc_p->periph1_clken) | PERIPH_UART1, + &misc_p->periph1_clken); +#endif + + /* Enable IPs (release reset) */ + writel(PERIPH_RST_ALL, &misc_p->periph1_rst); + + /* Initialize MPMC */ + serial_puts("Configure DDR\n"); + mpmc_init(); + + /* SoC specific initialization */ + soc_init(); +} + +void spear_late_init(void) +{ + struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + writel(0x80000007, &misc_p->arb_icm_ml1); + writel(0x80000007, &misc_p->arb_icm_ml2); + writel(0x80000007, &misc_p->arb_icm_ml3); + writel(0x80000007, &misc_p->arb_icm_ml4); + writel(0x80000007, &misc_p->arb_icm_ml5); + writel(0x80000007, &misc_p->arb_icm_ml6); + writel(0x80000007, &misc_p->arb_icm_ml7); + writel(0x80000007, &misc_p->arb_icm_ml8); + writel(0x80000007, &misc_p->arb_icm_ml9); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl_boot.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl_boot.c new file mode 100644 index 0000000..c846d75 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spl_boot.c
@@ -0,0 +1,181 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * Copyright (C) 2012 Stefan Roese <sr@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <image.h> +#include <linux/compiler.h> +#include <asm/io.h> +#include <asm/arch/spr_defs.h> +#include <linux/mtd/st_smi.h> + +static const char kernel_name[] = "Linux"; +static const char loader_name[] = "U-Boot"; + +int image_check_header(image_header_t *hdr, const char *name) +{ + if (image_check_magic(hdr) && + (!strncmp(image_get_name(hdr), name, strlen(name))) && + image_check_hcrc(hdr)) { + return 1; + } + return 0; +} + +int image_check_data(image_header_t *hdr) +{ + if (image_check_dcrc(hdr)) + return 1; + + return 0; +} + +/* + * SNOR (Serial NOR flash) related functions + */ +void snor_init(void) +{ + struct smi_regs *const smicntl = + (struct smi_regs * const)CONFIG_SYS_SMI_BASE; + + /* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */ + writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4, + &smicntl->smi_cr1); +} + +static int snor_image_load(u8 *load_addr, void (**image_p)(void), + const char *image_name) +{ + image_header_t *header; + + /* + * Since calculating the crc in the SNOR flash does not + * work, we copy the image to the destination address + * minus the header size. And point the header to this + * new destination. This will not work for address 0 + * of course. + */ + header = (image_header_t *)load_addr; + memcpy((ulong *)(image_get_load(header) - sizeof(image_header_t)), + (const ulong *)load_addr, + image_get_data_size(header) + sizeof(image_header_t)); + header = (image_header_t *)(image_get_load(header) - + sizeof(image_header_t)); + + if (image_check_header(header, image_name)) { + if (image_check_data(header)) { + /* Jump to boot image */ + *image_p = (void *)image_get_load(header); + return 1; + } + } + + return 0; +} + +static void boot_image(void (*image)(void)) +{ + void (*funcp)(void) __noreturn = (void *)image; + + (*funcp)(); +} + +/* + * spl_boot: + * + * All supported booting types of all supported SoCs are listed here. + * Generic readback APIs are provided for each supported booting type + * eg. nand_read_skip_bad + */ +u32 spl_boot(void) +{ + void (*image)(void); + +#ifdef CONFIG_SPEAR_USBTTY + plat_late_init(); + return 1; +#endif + + /* + * All the supported booting devices are listed here. Each of + * the booting type supported by the platform would define the + * macro xxx_BOOT_SUPPORTED to true. + */ + + if (SNOR_BOOT_SUPPORTED && snor_boot_selected()) { + /* SNOR-SMI initialization */ + snor_init(); + + serial_puts("Booting via SNOR\n"); + /* Serial NOR booting */ + if (1 == snor_image_load((u8 *)CONFIG_SYS_UBOOT_BASE, + &image, loader_name)) { + /* Platform related late initialasations */ + plat_late_init(); + + /* Jump to boot image */ + serial_puts("Jumping to U-Boot\n"); + boot_image(image); + return 1; + } + } + + if (NAND_BOOT_SUPPORTED && nand_boot_selected()) { + /* NAND booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (PNOR_BOOT_SUPPORTED && pnor_boot_selected()) { + /* PNOR booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (MMC_BOOT_SUPPORTED && mmc_boot_selected()) { + /* MMC booting */ + /* Not ported from XLoader to SPL yet */ + return 0; + } + + if (SPI_BOOT_SUPPORTED && spi_boot_selected()) { + /* SPI booting */ + /* Not supported for any platform as of now */ + return 0; + } + + if (I2C_BOOT_SUPPORTED && i2c_boot_selected()) { + /* I2C booting */ + /* Not supported for any platform as of now */ + return 0; + } + + /* + * All booting types without memory are listed as below + * Control has to be returned to BootROM in case of all + * the following booting scenarios + */ + + if (USB_BOOT_SUPPORTED && usb_boot_selected()) { + plat_late_init(); + return 1; + } + + if (TFTP_BOOT_SUPPORTED && tftp_boot_selected()) { + plat_late_init(); + return 1; + } + + if (UART_BOOT_SUPPORTED && uart_boot_selected()) { + plat_late_init(); + return 1; + } + + /* Ideally, the control should not reach here. */ + hang(); +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c new file mode 100644 index 0000000..3d6ad04 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c
@@ -0,0 +1,114 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#if (CONFIG_DDR_PLL2) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { + 0x00000001, + 0x00000000, + 0x01000000, + 0x00000101, + 0x00000001, + 0x01000000, + 0x00010001, + 0x00000100, + 0x00010001, + 0x00000003, + 0x01000201, + 0x06000202, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000404, + 0x02030202, + 0x03000204, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x08080a01, + 0x0000023f, + 0x00040800, + 0x00000000, + 0x00000f02, + 0x00001b1b, + 0x7f000000, + 0x005f0000, + 0x1c040b6a, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x000007ff, + 0x00000000, + 0x47ec00c8, + 0x00c8001f, + 0x00000000, + 0x0000cd98, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00270000, + 0x00250027, + 0x00300000, + 0x008900b7, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c new file mode 100644 index 0000000..105b305 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c
@@ -0,0 +1,119 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { +#if (CONFIG_DDR_PLL2) + 0x00000001, + 0x00000000, +#elif (CONFIG_DDR_2HCLK) + 0x02020201, + 0x02020202, +#endif + 0x01000000, + 0x00000101, + 0x00000101, + 0x01000000, + 0x00010001, + 0x00000100, + 0x01010001, + 0x00000201, + 0x01000101, + 0x06000002, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000405, + 0x03040202, + 0x04000305, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x0a0a0a01, + 0x0000023f, + 0x00050a00, + 0x11000000, + 0x00001302, + 0x00000A0A, + 0x72000000, + 0x00550000, + 0x2b050e86, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00000a24, + 0x43C20000, + 0x5b1c00c8, + 0x00c8002e, + 0x00000000, + 0x0001046b, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00210000, + 0x00010021, + 0x00200000, + 0x006c0090, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c new file mode 100644 index 0000000..00b6b29 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c
@@ -0,0 +1,114 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#if (CONFIG_DDR_HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { + 0x03030301, + 0x03030303, + 0x01000000, + 0x00000101, + 0x00000001, + 0x01000000, + 0x00010001, + 0x00000100, + 0x00010001, + 0x00000003, + 0x01000201, + 0x06000202, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, + 0x02010106, + 0x03000404, + 0x02020202, + 0x03000203, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x08080a01, + 0x0000023f, + 0x00030600, + 0x00000000, + 0x00000a02, + 0x00001c1c, + 0x7f000000, + 0x005f0000, + 0x12030743, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x0000050e, + 0x00000000, + 0x2d8900c8, + 0x00c80014, + 0x00000000, + 0x00008236, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00400000, + 0x003a0040, + 0x00680000, + 0x00d80120, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c new file mode 100644 index 0000000..a406c3e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c
@@ -0,0 +1,128 @@ +/* + * (C) Copyright 2000-2009 + * Vipin Kumar, ST Microelectronics, vipin.kumar@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK) + +const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = { +#if (CONFIG_DDR_PLL2) + 0x00000001, + 0x00000000, +#elif (CONFIG_DDR_2HCLK) + 0x02020201, + 0x02020202, +#endif + 0x01000000, + 0x00000101, + 0x00000101, + 0x01000000, + 0x00010001, + 0x00000100, + 0x01010001, + 0x00000201, + 0x01000101, + 0x06000002, + 0x06060106, + 0x03050502, + 0x03040404, + 0x02020503, +#ifdef CONFIG_X600 + 0x02030206, +#else + 0x02010106, +#endif + 0x03000405, + 0x03040202, + 0x04000305, + 0x0707073f, + 0x07070707, + 0x06060607, + 0x06060606, + 0x05050506, + 0x05050505, + 0x04040405, + 0x04040404, + 0x03030304, + 0x03030303, + 0x02020203, + 0x02020202, + 0x01010102, + 0x01010101, + 0x0a0a0a01, + 0x0000023f, + 0x00050a00, + 0x11000000, + 0x00001302, + 0x00000A0A, +#ifdef CONFIG_X600 + 0x7f000000, + 0x005c0000, +#else + 0x72000000, + 0x00550000, +#endif + 0x2b050e86, + 0x00640064, + 0x00640064, + 0x00640064, + 0x00000064, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00200020, + 0x00000a24, + 0x43C20000, + 0x5b1c00c8, + 0x00c8002e, + 0x00000000, + 0x0001046b, + 0x00000000, + 0x03030100, + 0x03030303, + 0x03030303, + 0x03030303, + 0x00210000, + 0x00010021, + 0x00200000, + 0x006c0090, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x003fffff, + 0x003fffff, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; +#endif
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/start.S b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/start.S new file mode 100644 index 0000000..290ac2e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/start.S
@@ -0,0 +1,81 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 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 <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <config.h> + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * Below are the critical initializations already taken place in BootROM. + * So, these are not taken care in Xloader + * 1. Relocation to RAM + * 2. Initializing stacks + * + ************************************************************************* + */ + + .globl reset + +reset: +/* + * Xloader has to return back to BootROM in a few cases. + * eg. Ethernet boot, UART boot, USB boot + * Saving registers for returning back + */ + stmdb sp!, {r0-r12,r14} + bl cpu_init_crit +/* + * Clearing bss area is not done in Xloader. + * BSS area lies in the DDR location which is not yet initialized + * bss is assumed to be uninitialized. + */ + bl spl_boot + ldmia sp!, {r0-r12,pc} + +/* + ************************************************************************* + * + * 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 */ + + /* + * enable instruction cache + */ + mrc p15, 0, r0, c1, c0, 0 + 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. + */ + stmdb sp!, {lr} + bl lowlevel_init /* go setup pll,mux,memory */ + ldmia sp!, {pc}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/timer.c b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/timer.c new file mode 100644 index 0000000..c88e962 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/timer.c
@@ -0,0 +1,123 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/spr_gpt.h> +#include <asm/arch/spr_misc.h> + +#define GPT_RESOLUTION (CONFIG_SPEAR_HZ_CLOCK / CONFIG_SPEAR_HZ) +#define READ_TIMER() (readl(&gpt_regs_p->count) & GPT_FREE_RUNNING) + +static struct gpt_regs *const gpt_regs_p = + (struct gpt_regs *)CONFIG_SPEAR_TIMERBASE; + +static struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +int timer_init(void) +{ + u32 synth; + + /* Prescaler setting */ +#if defined(CONFIG_SPEAR3XX) + writel(MISC_PRSC_CFG, &misc_regs_p->prsc2_clk_cfg); + synth = MISC_GPT4SYNTH; +#elif defined(CONFIG_SPEAR600) + writel(MISC_PRSC_CFG, &misc_regs_p->prsc1_clk_cfg); + synth = MISC_GPT3SYNTH; +#else +# error Incorrect config. Can only be spear{600|300|310|320} +#endif + + writel(readl(&misc_regs_p->periph_clk_cfg) | synth, + &misc_regs_p->periph_clk_cfg); + + /* disable timers */ + writel(GPT_PRESCALER_1 | GPT_MODE_AUTO_RELOAD, &gpt_regs_p->control); + + /* load value for free running */ + writel(GPT_FREE_RUNNING, &gpt_regs_p->compare); + + /* auto reload, start timer */ + writel(readl(&gpt_regs_p->control) | GPT_ENABLE, &gpt_regs_p->control); + + /* Reset the timer */ + lastdec = READ_TIMER(); + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return (get_timer_masked() / GPT_RESOLUTION) - base; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong start = get_timer_masked(); + ulong tenudelcnt = CONFIG_SPEAR_HZ_CLOCK / (1000 * 100); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; + + /* tenudelcnt timer tick gives 10 microsecconds delay */ + tmo = ((usec / 10) + rndoff) * tenudelcnt; + + while ((ulong) (get_timer_masked() - start) < tmo) + ; +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER(); + + if (now >= lastdec) { + /* normal mode */ + timestamp += now - lastdec; + } else { + /* we have an overflow ... */ + timestamp += now + GPT_FREE_RUNNING - lastdec; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked(unsigned long usec) +{ + return udelay(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SPEAR_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds new file mode 100644 index 0000000..c7ee199 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
@@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * January 2004 - Changed to support H4 device + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.vectors) + arch/arm/cpu/arm926ejs/spear/start.o (.text*) + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + + .rel.dyn : { + __rel_dyn_start = .; + *(.rel*) + __rel_dyn_end = .; + } + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } + + .end : + { + *(.__end) + } + + _image_binary_end = .; + + .dynsym _image_binary_end : { *(.dynsym) } + .dynbss : { *(.dynbss) } + .dynstr : { *(.dynstr*) } + .dynamic : { *(.dynamic*) } + .hash : { *(.hash*) } + .plt : { *(.plt*) } + .interp : { *(.interp*) } + .gnu : { *(.gnu*) } + .ARM.exidx : { *(.ARM.exidx*) } +}
diff --git a/u-boot-imx/arch/arm/cpu/arm926ejs/start.S b/u-boot-imx/arch/arm/cpu/arm926ejs/start.S new file mode 100644 index 0000000..82cc1c9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm926ejs/start.S
@@ -0,0 +1,111 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 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 <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <common.h> + +/* + ************************************************************************* + * + * 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 + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + bx lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush D cache before disabling it + */ + mov r0, #0 +flush_dcache: + mrc p15, 0, r15, c7, c10, 3 + bne flush_dcache + + mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */ + mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */ + + /* + * disable MMU and D cache + * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ +#ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH + orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */ +#else + bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */ +#endif + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ +#ifndef CONFIG_SYS_ICACHE_OFF + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ +#endif + 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 lowlevel_init /* go setup pll,mux,memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/u-boot-imx/arch/arm/cpu/arm946es/Makefile b/u-boot-imx/arch/arm/cpu/arm946es/Makefile new file mode 100644 index 0000000..a44bddc --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm946es/Makefile
@@ -0,0 +1,10 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o + +obj-y = cpu.o
diff --git a/u-boot-imx/arch/arm/cpu/arm946es/cpu.c b/u-boot-imx/arch/arm/cpu/arm946es/cpu.c new file mode 100644 index 0000000..e20e5a8 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm946es/cpu.c
@@ -0,0 +1,66 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <asm/io.h> + +static void cache_flush(void); + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + disable_interrupts (); + + /* ARM926E-S needs the protection unit enabled for the icache to have + * been enabled - left for possible later use + * should turn off the protection unit as well.... + */ + /* turn off I/D-cache */ + icache_disable(); + dcache_disable(); + /* flush I/D-cache */ + cache_flush(); + + return 0; +} + +/* flush I/D-cache */ +static void cache_flush (void) +{ + unsigned long i = 0; + + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (i)); +} + +#ifndef CONFIG_INTEGRATOR + +__attribute__((noreturn)) void reset_cpu(ulong addr __attribute__((unused))) +{ + writew(0x0, 0xfffece10); + writew(0x8, 0xfffece10); + for (;;) + ; +} + +#endif /* #ifdef CONFIG_INTEGRATOR */
diff --git a/u-boot-imx/arch/arm/cpu/arm946es/start.S b/u-boot-imx/arch/arm/cpu/arm946es/start.S new file mode 100644 index 0000000..b55395a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/arm946es/start.S
@@ -0,0 +1,100 @@ +/* + * armboot - Startup Code for ARM926EJS CPU-core + * + * Copyright (c) 2003 Texas Instruments + * + * ----- Adapted for OMAP1610 OMAP730 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 <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> + +/* + ************************************************************************* + * + * 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 + * + ************************************************************************* + */ + + .globl reset + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x1f + orr r0,r0,#0xd3 + msr cpsr,r0 + + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + + .globl c_runtime_cpu_setup +c_runtime_cpu_setup: + + mov pc, lr + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +cpu_init_crit: + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 /* flush v4 I-cache */ + mcr p15, 0, r0, c7, c6, 0 /* flush v4 D-cache */ + + /* + * 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 lowlevel_init /* go setup memory */ + mov lr, ip /* restore link */ + mov pc, lr /* back to my caller */ +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/Kconfig new file mode 100644 index 0000000..61e7c82 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/Kconfig
@@ -0,0 +1,34 @@ +if CPU_V7 + +config CPU_V7_HAS_NONSEC + bool + +config CPU_V7_HAS_VIRT + bool + +config ARMV7_NONSEC + boolean "Enable support for booting in non-secure mode" if EXPERT + depends on CPU_V7_HAS_NONSEC + default y + ---help--- + Say Y here to enable support for booting in non-secure / SVC mode. + +config ARMV7_BOOT_SEC_DEFAULT + boolean "Boot in secure mode by default" if EXPERT + depends on ARMV7_NONSEC + default n + ---help--- + Say Y here to boot in secure mode by default even if non-secure mode + is supported. This option is useful to boot kernels which do not + suppport booting in non-secure mode. Only set this if you need it. + This can be overriden at run-time by setting the bootm_boot_mode env. + variable to "sec" or "nonsec". + +config ARMV7_VIRT + boolean "Enable support for hardware virtualization" if EXPERT + depends on CPU_V7_HAS_VIRT && ARMV7_NONSEC + default y + ---help--- + Say Y here to boot in hypervisor (HYP) mode when booting non-secure. + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/Makefile b/u-boot-imx/arch/arm/cpu/armv7/Makefile new file mode 100644 index 0000000..828f366 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/Makefile
@@ -0,0 +1,60 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y := start.o + +obj-y += cache_v7.o + +obj-y += cpu.o cp15.o +obj-y += syslib.o + +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_MX7)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),) +ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) +obj-y += lowlevel_init.o +endif +endif + +ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),) +obj-y += nonsec_virt.o +obj-y += virt-v7.o +obj-y += virt-dt.o +endif + +ifneq ($(CONFIG_ARMV7_PSCI),) +obj-y += psci.o +endif + +obj-$(CONFIG_IPROC) += iproc-common/ +obj-$(CONFIG_KONA) += kona-common/ +obj-$(CONFIG_OMAP_COMMON) += omap-common/ +obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o + +ifneq (,$(filter s5pc1xx exynos,$(SOC))) +obj-y += s5p-common/ +endif + +obj-$(if $(filter am33xx,$(SOC)),y) += am33xx/ +obj-$(if $(filter armada-xp,$(SOC)),y) += armada-xp/ +obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ +obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ +obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ +obj-$(CONFIG_ARCH_EXYNOS) += exynos/ +obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/ +obj-$(if $(filter mx5,$(SOC)),y) += mx5/ +obj-$(CONFIG_MX6) += mx6/ +obj-$(CONFIG_MX7) += mx7/ +obj-$(CONFIG_OMAP34XX) += omap3/ +obj-$(CONFIG_OMAP44XX) += omap4/ +obj-$(CONFIG_OMAP54XX) += omap5/ +obj-$(CONFIG_RMOBILE) += rmobile/ +obj-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx/ +obj-$(CONFIG_SOCFPGA) += socfpga/ +obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ +obj-$(CONFIG_ARCH_SUNXI) += sunxi/ +obj-$(CONFIG_U8500) += u8500/ +obj-$(CONFIG_VF610) += vf610/ +obj-$(CONFIG_ZYNQ) += zynq/
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/Makefile b/u-boot-imx/arch/arm/cpu/armv7/am33xx/Makefile new file mode 100644 index 0000000..aae3f09 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/Makefile
@@ -0,0 +1,20 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_AM33XX) += clock_am33xx.o +obj-$(CONFIG_TI814X) += clock_ti814x.o +obj-$(CONFIG_AM43XX) += clock_am43xx.o + +ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX),) +obj-y += clock.o +endif + +obj-$(CONFIG_TI816X) += clock_ti816x.o +obj-y += sys_info.o +obj-y += ddr.o +obj-y += emif4.o +obj-y += board.o +obj-y += mux.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/board.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/board.c new file mode 100644 index 0000000..67bef23 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/board.c
@@ -0,0 +1,311 @@ +/* + * board.c + * + * Common board functions for AM33XX based boards + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <ns16550.h> +#include <spl.h> +#include <asm/arch/cpu.h> +#include <asm/arch/hardware.h> +#include <asm/arch/omap.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/arch/mem.h> +#include <asm/arch/mmc_host_def.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/emif.h> +#include <asm/gpio.h> +#include <i2c.h> +#include <miiphy.h> +#include <cpsw.h> +#include <asm/errno.h> +#include <linux/compiler.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb/musb.h> +#include <asm/omap_musb.h> +#include <asm/davinci_rtc.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_DM_GPIO +static const struct omap_gpio_platdata am33xx_gpio[] = { + { 0, AM33XX_GPIO0_BASE, METHOD_GPIO_24XX }, + { 1, AM33XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { 2, AM33XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { 3, AM33XX_GPIO3_BASE, METHOD_GPIO_24XX }, +#ifdef CONFIG_AM43XX + { 4, AM33XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { 5, AM33XX_GPIO5_BASE, METHOD_GPIO_24XX }, +#endif +}; + +U_BOOT_DEVICES(am33xx_gpios) = { + { "gpio_omap", &am33xx_gpio[0] }, + { "gpio_omap", &am33xx_gpio[1] }, + { "gpio_omap", &am33xx_gpio[2] }, + { "gpio_omap", &am33xx_gpio[3] }, +#ifdef CONFIG_AM43XX + { "gpio_omap", &am33xx_gpio[4] }, + { "gpio_omap", &am33xx_gpio[5] }, +#endif +}; + +# ifndef CONFIG_OF_CONTROL +/* + * TODO(sjg@chromium.org): When we can move SPL serial to DM, we can remove + * the CONFIGs. At the same time, we should move this to the board files. + */ +static const struct ns16550_platdata am33xx_serial[] = { + { CONFIG_SYS_NS16550_COM1, 2, CONFIG_SYS_NS16550_CLK }, +# ifdef CONFIG_SYS_NS16550_COM2 + { CONFIG_SYS_NS16550_COM2, 2, CONFIG_SYS_NS16550_CLK }, +# ifdef CONFIG_SYS_NS16550_COM3 + { CONFIG_SYS_NS16550_COM3, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM4, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM5, 2, CONFIG_SYS_NS16550_CLK }, + { CONFIG_SYS_NS16550_COM6, 2, CONFIG_SYS_NS16550_CLK }, +# endif +# endif +}; + +U_BOOT_DEVICES(am33xx_uarts) = { + { "serial_omap", &am33xx_serial[0] }, +# ifdef CONFIG_SYS_NS16550_COM2 + { "serial_omap", &am33xx_serial[1] }, +# ifdef CONFIG_SYS_NS16550_COM3 + { "serial_omap", &am33xx_serial[2] }, + { "serial_omap", &am33xx_serial[3] }, + { "serial_omap", &am33xx_serial[4] }, + { "serial_omap", &am33xx_serial[5] }, +# endif +# endif +}; +# endif + +#else + +static const struct gpio_bank gpio_bank_am33xx[] = { + { (void *)AM33XX_GPIO0_BASE, METHOD_GPIO_24XX }, + { (void *)AM33XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { (void *)AM33XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { (void *)AM33XX_GPIO3_BASE, METHOD_GPIO_24XX }, +#ifdef CONFIG_AM43XX + { (void *)AM33XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { (void *)AM33XX_GPIO5_BASE, METHOD_GPIO_24XX }, +#endif +}; + +const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx; + +#endif + +#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD) +int cpu_mmc_init(bd_t *bis) +{ + int ret; + + ret = omap_mmc_init(0, 0, 0, -1, -1); + if (ret) + return ret; + + return omap_mmc_init(1, 0, 0, -1, -1); +} +#endif + +/* AM33XX has two MUSB controllers which can be host or gadget */ +#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \ + (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; + +/* USB 2.0 PHY Control */ +#define CM_PHY_PWRDN (1 << 0) +#define CM_PHY_OTG_PWRDN (1 << 1) +#define OTGVDET_EN (1 << 19) +#define OTGSESSENDEN (1 << 20) + +static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr) +{ + if (on) { + clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, + OTGVDET_EN | OTGSESSENDEN); + } else { + clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); + } +} + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +#ifdef CONFIG_AM335X_USB0 +static void am33xx_otg0_set_phy_power(u8 on) +{ + am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0); +} + +struct omap_musb_board_data otg0_board_data = { + .set_phy_power = am33xx_otg0_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg0_plat = { + .mode = CONFIG_AM335X_USB0_MODE, + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + .board_data = &otg0_board_data, +}; +#endif + +#ifdef CONFIG_AM335X_USB1 +static void am33xx_otg1_set_phy_power(u8 on) +{ + am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1); +} + +struct omap_musb_board_data otg1_board_data = { + .set_phy_power = am33xx_otg1_set_phy_power, +}; + +static struct musb_hdrc_platform_data otg1_plat = { + .mode = CONFIG_AM335X_USB1_MODE, + .config = &musb_config, + .power = 50, + .platform_ops = &musb_dsps_ops, + .board_data = &otg1_board_data, +}; +#endif +#endif + +int arch_misc_init(void) +{ +#ifdef CONFIG_AM335X_USB0 + musb_register(&otg0_plat, &otg0_board_data, + (void *)USB0_OTG_BASE); +#endif +#ifdef CONFIG_AM335X_USB1 + musb_register(&otg1_plat, &otg1_board_data, + (void *)USB1_OTG_BASE); +#endif + return 0; +} + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +/* + * In the case of non-SPL based booting we'll want to call these + * functions a tiny bit later as it will require gd to be set and cleared + * and that's not true in s_init in this case so we cannot do it there. + */ +int board_early_init_f(void) +{ + prcm_init(); + set_mux_conf_regs(); + + return 0; +} + +/* + * This function is the place to do per-board things such as ramp up the + * MPU clock frequency. + */ +__weak void am33xx_spl_board_init(void) +{ + do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); + do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); +} + +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) +static void rtc32k_enable(void) +{ + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; + + /* + * Unlock the RTC's registers. For more details please see the + * RTC_SS section of the TRM. In order to unlock we need to + * write these specific values (keys) in this order. + */ + writel(RTC_KICK0R_WE, &rtc->kick0r); + writel(RTC_KICK1R_WE, &rtc->kick1r); + + /* Enable the RTC 32K OSC by setting bits 3 and 6. */ + writel((1 << 3) | (1 << 6), &rtc->osc); +} +#endif + +static void uart_soft_reset(void) +{ + struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; + u32 regval; + + regval = readl(&uart_base->uartsyscfg); + regval |= UART_RESET; + writel(regval, &uart_base->uartsyscfg); + while ((readl(&uart_base->uartsyssts) & + UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) + ; + + /* Disable smart idle */ + regval = readl(&uart_base->uartsyscfg); + regval |= UART_SMART_IDLE_EN; + writel(regval, &uart_base->uartsyscfg); +} + +static void watchdog_disable(void) +{ + struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + + writel(0xAAAA, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; + writel(0x5555, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + board_early_init_f(); + sdram_init(); +} +#endif + +void s_init(void) +{ + /* + * The ROM will only have set up sufficient pinmux to allow for the + * first 4KiB NOR to be read, we must finish doing what we know of + * the NOR mux in this space in order to continue. + */ +#ifdef CONFIG_NOR_BOOT + enable_norboot_pin_mux(); +#endif + watchdog_disable(); + set_uart_mux_conf(); + setup_clocks_for_console(); + uart_soft_reset(); +#if defined(CONFIG_NOR_BOOT) || defined(CONFIG_QSPI_BOOT) + /* TODO: This does not work, gd is not available yet */ + gd->baudrate = CONFIG_BAUDRATE; + serial_init(); + gd->have_console = 1; +#endif +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) + /* Enable RTC32K clock */ + rtc32k_enable(); +#endif +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock.c new file mode 100644 index 0000000..ec7d468 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock.c
@@ -0,0 +1,188 @@ +/* + * clock.c + * + * Clock initialization for AM33XX boards. + * Derived from OMAP4 boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +static void setup_post_dividers(const struct dpll_regs *dpll_regs, + const struct dpll_params *params) +{ + /* Setup post-dividers */ + if (params->m2 >= 0) + writel(params->m2, dpll_regs->cm_div_m2_dpll); + if (params->m3 >= 0) + writel(params->m3, dpll_regs->cm_div_m3_dpll); + if (params->m4 >= 0) + writel(params->m4, dpll_regs->cm_div_m4_dpll); + if (params->m5 >= 0) + writel(params->m5, dpll_regs->cm_div_m5_dpll); + if (params->m6 >= 0) + writel(params->m6, dpll_regs->cm_div_m6_dpll); +} + +static inline void do_lock_dpll(const struct dpll_regs *dpll_regs) +{ + clrsetbits_le32(dpll_regs->cm_clkmode_dpll, + CM_CLKMODE_DPLL_DPLL_EN_MASK, + DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_lock(const struct dpll_regs *dpll_regs) +{ + if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK, + (void *)dpll_regs->cm_idlest_dpll, LDELAY)) { + printf("DPLL locking failed for 0x%x\n", + dpll_regs->cm_clkmode_dpll); + hang(); + } +} + +static inline void do_bypass_dpll(const struct dpll_regs *dpll_regs) +{ + clrsetbits_le32(dpll_regs->cm_clkmode_dpll, + CM_CLKMODE_DPLL_DPLL_EN_MASK, + DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_bypass(const struct dpll_regs *dpll_regs) +{ + if (!wait_on_value(ST_DPLL_CLK_MASK, 0, + (void *)dpll_regs->cm_idlest_dpll, LDELAY)) { + printf("Bypassing DPLL failed 0x%x\n", + dpll_regs->cm_clkmode_dpll); + } +} + +static void bypass_dpll(const struct dpll_regs *dpll_regs) +{ + do_bypass_dpll(dpll_regs); + wait_for_bypass(dpll_regs); +} + +void do_setup_dpll(const struct dpll_regs *dpll_regs, + const struct dpll_params *params) +{ + u32 temp; + + if (!params) + return; + + temp = readl(dpll_regs->cm_clksel_dpll); + + bypass_dpll(dpll_regs); + + /* Set M & N */ + temp &= ~CM_CLKSEL_DPLL_M_MASK; + temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK; + + temp &= ~CM_CLKSEL_DPLL_N_MASK; + temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK; + + writel(temp, dpll_regs->cm_clksel_dpll); + + setup_post_dividers(dpll_regs, params); + + /* Wait till the DPLL locks */ + do_lock_dpll(dpll_regs); + wait_for_lock(dpll_regs); +} + +static void setup_dplls(void) +{ + const struct dpll_params *params; + + params = get_dpll_core_params(); + do_setup_dpll(&dpll_core_regs, params); + + params = get_dpll_mpu_params(); + do_setup_dpll(&dpll_mpu_regs, params); + + params = get_dpll_per_params(); + do_setup_dpll(&dpll_per_regs, params); + writel(0x300, &cmwkup->clkdcoldodpllper); + + params = get_dpll_ddr_params(); + do_setup_dpll(&dpll_ddr_regs, params); +} + +static inline void wait_for_clk_enable(u32 *clkctrl_addr) +{ + u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; + u32 bound = LDELAY; + + while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || + (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { + clkctrl = readl(clkctrl_addr); + idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> + MODULE_CLKCTRL_IDLEST_SHIFT; + if (--bound == 0) { + printf("Clock enable failed for 0x%p idlest 0x%x\n", + clkctrl_addr, clkctrl); + return; + } + } +} + +static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode, + u32 wait_for_enable) +{ + clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK, + enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT); + debug("Enable clock module - %p\n", clkctrl_addr); + if (wait_for_enable) + wait_for_clk_enable(clkctrl_addr); +} + +static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode) +{ + clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK, + enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT); + debug("Enable clock domain - %p\n", clkctrl_reg); +} + +void do_enable_clocks(u32 *const *clk_domains, + u32 *const *clk_modules_explicit_en, u8 wait_for_enable) +{ + u32 i, max = 100; + + /* Put the clock domains in SW_WKUP mode */ + for (i = 0; (i < max) && clk_domains[i]; i++) { + enable_clock_domain(clk_domains[i], + CD_CLKCTRL_CLKTRCTRL_SW_WKUP); + } + + /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ + for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) { + enable_clock_module(clk_modules_explicit_en[i], + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, + wait_for_enable); + }; +} + +/* + * Before scaling up the clocks we need to have the PMIC scale up the + * voltages first. This will be dependent on which PMIC is in use + * and in some cases we may not be scaling things up at all and thus not + * need to do anything here. + */ +__weak void scale_vcores(void) +{ +} + +void prcm_init() +{ + enable_basic_clocks(); + scale_vcores(); + setup_dplls(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am33xx.c new file mode 100644 index 0000000..92142c8 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
@@ -0,0 +1,161 @@ +/* + * clock_am33xx.c + * + * clocks for AM33XX based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +#define OSC (V_OSCK/1000000) + +struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; +struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; +struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; +struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC; + +const struct dpll_regs dpll_mpu_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x88, + .cm_idlest_dpll = CM_WKUP + 0x20, + .cm_clksel_dpll = CM_WKUP + 0x2C, + .cm_div_m2_dpll = CM_WKUP + 0xA8, +}; + +const struct dpll_regs dpll_core_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x90, + .cm_idlest_dpll = CM_WKUP + 0x5C, + .cm_clksel_dpll = CM_WKUP + 0x68, + .cm_div_m4_dpll = CM_WKUP + 0x80, + .cm_div_m5_dpll = CM_WKUP + 0x84, + .cm_div_m6_dpll = CM_WKUP + 0xD8, +}; + +const struct dpll_regs dpll_per_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x8C, + .cm_idlest_dpll = CM_WKUP + 0x70, + .cm_clksel_dpll = CM_WKUP + 0x9C, + .cm_div_m2_dpll = CM_WKUP + 0xAC, +}; + +const struct dpll_regs dpll_ddr_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x94, + .cm_idlest_dpll = CM_WKUP + 0x34, + .cm_clksel_dpll = CM_WKUP + 0x40, + .cm_div_m2_dpll = CM_WKUP + 0xA0, +}; + +struct dpll_params dpll_mpu_opp100 = { + CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1}; +const struct dpll_params dpll_core_opp100 = { + 1000, OSC-1, -1, -1, 10, 8, 4}; +const struct dpll_params dpll_mpu = { + MPUPLL_M_300, OSC-1, 1, -1, -1, -1, -1}; +const struct dpll_params dpll_core = { + 50, OSC-1, -1, -1, 1, 1, 1}; +const struct dpll_params dpll_per = { + 960, OSC-1, 5, -1, -1, -1, -1}; + +const struct dpll_params *get_dpll_mpu_params(void) +{ + return &dpll_mpu; +} + +const struct dpll_params *get_dpll_core_params(void) +{ + return &dpll_core; +} + +const struct dpll_params *get_dpll_per_params(void) +{ + return &dpll_per; +} + +void setup_clocks_for_console(void) +{ + clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_SW_WKUP << + CD_CLKCTRL_CLKTRCTRL_SHIFT); + + clrsetbits_le32(&cmper->l4hsclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_SW_WKUP << + CD_CLKCTRL_CLKTRCTRL_SHIFT); + + clrsetbits_le32(&cmwkup->wkup_uart0ctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + clrsetbits_le32(&cmper->uart1clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + clrsetbits_le32(&cmper->uart2clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + clrsetbits_le32(&cmper->uart3clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + clrsetbits_le32(&cmper->uart4clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + clrsetbits_le32(&cmper->uart5clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); +} + +void enable_basic_clocks(void) +{ + u32 *const clk_domains[] = { + &cmper->l3clkstctrl, + &cmper->l4fwclkstctrl, + &cmper->l3sclkstctrl, + &cmper->l4lsclkstctrl, + &cmwkup->wkclkstctrl, + &cmper->emiffwclkctrl, + &cmrtc->clkstctrl, + 0 + }; + + u32 *const clk_modules_explicit_en[] = { + &cmper->l3clkctrl, + &cmper->l4lsclkctrl, + &cmper->l4fwclkctrl, + &cmwkup->wkl4wkclkctrl, + &cmper->l3instrclkctrl, + &cmper->l4hsclkctrl, + &cmwkup->wkgpio0clkctrl, + &cmwkup->wkctrlclkctrl, + &cmper->timer2clkctrl, + &cmper->gpmcclkctrl, + &cmper->elmclkctrl, + &cmper->mmc0clkctrl, + &cmper->mmc1clkctrl, + &cmwkup->wkup_i2c0ctrl, + &cmper->gpio1clkctrl, + &cmper->gpio2clkctrl, + &cmper->gpio3clkctrl, + &cmper->i2c1clkctrl, + &cmper->cpgmac0clkctrl, + &cmper->spi0clkctrl, + &cmrtc->rtcclkctrl, + &cmper->usb0clkctrl, + &cmper->emiffwclkctrl, + &cmper->emifclkctrl, + 0 + }; + + do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); + + /* Select the Master osc 24 MHZ as Timer2 clock source */ + writel(0x1, &cmdpll->clktimer2clk); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am43xx.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am43xx.c new file mode 100644 index 0000000..529a119 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_am43xx.c
@@ -0,0 +1,124 @@ +/* + * clock_am43xx.c + * + * clocks for AM43XX based boards + * Derived from AM33XX based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> + +struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; +struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; +struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; + +const struct dpll_regs dpll_mpu_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x560, + .cm_idlest_dpll = CM_WKUP + 0x564, + .cm_clksel_dpll = CM_WKUP + 0x56c, + .cm_div_m2_dpll = CM_WKUP + 0x570, +}; + +const struct dpll_regs dpll_core_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x520, + .cm_idlest_dpll = CM_WKUP + 0x524, + .cm_clksel_dpll = CM_WKUP + 0x52C, + .cm_div_m4_dpll = CM_WKUP + 0x538, + .cm_div_m5_dpll = CM_WKUP + 0x53C, + .cm_div_m6_dpll = CM_WKUP + 0x540, +}; + +const struct dpll_regs dpll_per_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x5E0, + .cm_idlest_dpll = CM_WKUP + 0x5E4, + .cm_clksel_dpll = CM_WKUP + 0x5EC, + .cm_div_m2_dpll = CM_WKUP + 0x5F0, +}; + +const struct dpll_regs dpll_ddr_regs = { + .cm_clkmode_dpll = CM_WKUP + 0x5A0, + .cm_idlest_dpll = CM_WKUP + 0x5A4, + .cm_clksel_dpll = CM_WKUP + 0x5AC, + .cm_div_m2_dpll = CM_WKUP + 0x5B0, + .cm_div_m4_dpll = CM_WKUP + 0x5B8, +}; + +void setup_clocks_for_console(void) +{ + u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; + + /* Do not add any spl_debug prints in this function */ + clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_SW_WKUP << + CD_CLKCTRL_CLKTRCTRL_SHIFT); + + /* Enable UART0 */ + clrsetbits_le32(&cmwkup->wkup_uart0ctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + + while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || + (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { + clkctrl = readl(&cmwkup->wkup_uart0ctrl); + idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> + MODULE_CLKCTRL_IDLEST_SHIFT; + } +} + +void enable_basic_clocks(void) +{ + u32 *const clk_domains[] = { + &cmper->l3clkstctrl, + &cmper->l3sclkstctrl, + &cmper->l4lsclkstctrl, + &cmwkup->wkclkstctrl, + &cmper->emifclkstctrl, + 0 + }; + + u32 *const clk_modules_explicit_en[] = { + &cmper->l3clkctrl, + &cmper->l4lsclkctrl, + &cmper->l4fwclkctrl, + &cmwkup->wkl4wkclkctrl, + &cmper->l3instrclkctrl, + &cmper->l4hsclkctrl, + &cmwkup->wkgpio0clkctrl, + &cmwkup->wkctrlclkctrl, + &cmper->timer2clkctrl, + &cmper->gpmcclkctrl, + &cmper->elmclkctrl, + &cmper->mmc0clkctrl, + &cmper->mmc1clkctrl, + &cmwkup->wkup_i2c0ctrl, + &cmper->gpio1clkctrl, + &cmper->gpio2clkctrl, + &cmper->gpio3clkctrl, + &cmper->gpio4clkctrl, + &cmper->gpio5clkctrl, + &cmper->i2c1clkctrl, + &cmper->cpgmac0clkctrl, + &cmper->emiffwclkctrl, + &cmper->emifclkctrl, + &cmper->otfaemifclkctrl, + &cmper->qspiclkctrl, + 0 + }; + + do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); + + /* Select the Master osc clk as Timer2 clock source */ + writel(0x1, &cmdpll->clktimer2clk); + + /* For OPP100 the mac clock should be /5. */ + writel(0x4, &cmdpll->clkselmacclk); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti814x.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti814x.c new file mode 100644 index 0000000..9b5a47b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti814x.c
@@ -0,0 +1,404 @@ +/* + * clock_ti814x.c + * + * Clocks for TI814X based boards + * + * Copyright (C) 2013, Texas Instruments, Incorporated + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* PRCM */ +#define PRCM_MOD_EN 0x2 + +/* CLK_SRC */ +#define OSC_SRC0 0 +#define OSC_SRC1 1 + +#define L3_OSC_SRC OSC_SRC0 + +#define OSC_0_FREQ 20 + +#define DCO_HS2_MIN 500 +#define DCO_HS2_MAX 1000 +#define DCO_HS1_MIN 1000 +#define DCO_HS1_MAX 2000 + +#define SELFREQDCO_HS2 0x00000801 +#define SELFREQDCO_HS1 0x00001001 + +#define MPU_N 0x1 +#define MPU_M 0x3C +#define MPU_M2 1 +#define MPU_CLKCTRL 0x1 + +#define L3_N 19 +#define L3_M 880 +#define L3_M2 4 +#define L3_CLKCTRL 0x801 + +#define DDR_N 19 +#define DDR_M 666 +#define DDR_M2 2 +#define DDR_CLKCTRL 0x801 + +/* ADPLLJ register values */ +#define ADPLLJ_CLKCTRL_HS2 0x00000801 /* HS2 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_HS1 0x00001001 /* HS1 mode, TINT2 = 1 */ +#define ADPLLJ_CLKCTRL_CLKDCOLDOEN (1 << 29) +#define ADPLLJ_CLKCTRL_IDLE (1 << 23) +#define ADPLLJ_CLKCTRL_CLKOUTEN (1 << 20) +#define ADPLLJ_CLKCTRL_CLKOUTLDOEN (1 << 19) +#define ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ (1 << 17) +#define ADPLLJ_CLKCTRL_LPMODE (1 << 12) +#define ADPLLJ_CLKCTRL_DRIFTGUARDIAN (1 << 11) +#define ADPLLJ_CLKCTRL_REGM4XEN (1 << 10) +#define ADPLLJ_CLKCTRL_TINITZ (1 << 0) +#define ADPLLJ_CLKCTRL_CLKDCO (ADPLLJ_CLKCTRL_CLKDCOLDOEN | \ + ADPLLJ_CLKCTRL_CLKOUTEN | \ + ADPLLJ_CLKCTRL_CLKOUTLDOEN | \ + ADPLLJ_CLKCTRL_CLKDCOLDOPWDNZ) + +#define ADPLLJ_STATUS_PHASELOCK (1 << 10) +#define ADPLLJ_STATUS_FREQLOCK (1 << 9) +#define ADPLLJ_STATUS_PHSFRQLOCK (ADPLLJ_STATUS_PHASELOCK | \ + ADPLLJ_STATUS_FREQLOCK) +#define ADPLLJ_STATUS_BYPASSACK (1 << 8) +#define ADPLLJ_STATUS_BYPASS (1 << 0) +#define ADPLLJ_STATUS_BYPASSANDACK (ADPLLJ_STATUS_BYPASSACK | \ + ADPLLJ_STATUS_BYPASS) + +#define ADPLLJ_TENABLE_ENB (1 << 0) +#define ADPLLJ_TENABLEDIV_ENB (1 << 0) + +#define ADPLLJ_M2NDIV_M2SHIFT 16 + +#define MPU_PLL_BASE (PLL_SUBSYS_BASE + 0x048) +#define L3_PLL_BASE (PLL_SUBSYS_BASE + 0x110) +#define DDR_PLL_BASE (PLL_SUBSYS_BASE + 0x290) + +struct ad_pll { + unsigned int pwrctrl; + unsigned int clkctrl; + unsigned int tenable; + unsigned int tenablediv; + unsigned int m2ndiv; + unsigned int mn2div; + unsigned int fracdiv; + unsigned int bwctrl; + unsigned int fracctrl; + unsigned int status; + unsigned int m3div; + unsigned int rampctrl; +}; + +#define OSC_SRC_CTRL (PLL_SUBSYS_BASE + 0x2C0) + +#define ENET_CLKCTRL_CMPL 0x30000 + +#define SATA_PLL_BASE (CTRL_BASE + 0x0720) + +struct sata_pll { + unsigned int pllcfg0; + unsigned int pllcfg1; + unsigned int pllcfg2; + unsigned int pllcfg3; + unsigned int pllcfg4; + unsigned int pllstatus; + unsigned int rxstatus; + unsigned int txstatus; + unsigned int testcfg; +}; + +#define SEL_IN_FREQ (0x1 << 31) +#define DIGCLRZ (0x1 << 30) +#define ENDIGLDO (0x1 << 4) +#define APLL_CP_CURR (0x1 << 3) +#define ENBGSC_REF (0x1 << 2) +#define ENPLLLDO (0x1 << 1) +#define ENPLL (0x1 << 0) + +#define SATA_PLLCFG0_1 (SEL_IN_FREQ | ENBGSC_REF) +#define SATA_PLLCFG0_2 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF) +#define SATA_PLLCFG0_3 (SEL_IN_FREQ | ENDIGLDO | ENBGSC_REF | ENPLLLDO) +#define SATA_PLLCFG0_4 (SEL_IN_FREQ | DIGCLRZ | ENDIGLDO | ENBGSC_REF | \ + ENPLLLDO | ENPLL) + +#define PLL_LOCK (0x1 << 0) + +#define ENSATAMODE (0x1 << 31) +#define PLLREFSEL (0x1 << 30) +#define MDIVINT (0x4b << 18) +#define EN_CLKAUX (0x1 << 5) +#define EN_CLK125M (0x1 << 4) +#define EN_CLK100M (0x1 << 3) +#define EN_CLK50M (0x1 << 2) + +#define SATA_PLLCFG1 (ENSATAMODE | \ + PLLREFSEL | \ + MDIVINT | \ + EN_CLKAUX | \ + EN_CLK125M | \ + EN_CLK100M | \ + EN_CLK50M) + +#define DIGLDO_EN_CAPLESSMODE (0x1 << 22) +#define PLLDO_EN_LDO_STABLE (0x1 << 11) +#define PLLDO_EN_BUF_CUR (0x1 << 7) +#define PLLDO_EN_LP (0x1 << 6) +#define PLLDO_CTRL_TRIM_1_4V (0x10 << 1) + +#define SATA_PLLCFG3 (DIGLDO_EN_CAPLESSMODE | \ + PLLDO_EN_LDO_STABLE | \ + PLLDO_EN_BUF_CUR | \ + PLLDO_EN_LP | \ + PLLDO_CTRL_TRIM_1_4V) + +const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; +const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; +const struct sata_pll *spll = (struct sata_pll *)SATA_PLL_BASE; + +/* + * Enable the peripheral clock for required peripherals + */ +static void enable_per_clocks(void) +{ + /* HSMMC1 */ + writel(PRCM_MOD_EN, &cmalwon->mmchs1clkctrl); + while (readl(&cmalwon->mmchs1clkctrl) != PRCM_MOD_EN) + ; + + /* Ethernet */ + writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl); + writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl); + while ((readl(&cmalwon->ethernet0clkctrl) & ENET_CLKCTRL_CMPL) != 0) + ; + writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl); + while ((readl(&cmalwon->ethernet1clkctrl) & ENET_CLKCTRL_CMPL) != 0) + ; + + /* RTC clocks */ + writel(PRCM_MOD_EN, &cmalwon->rtcclkstctrl); + writel(PRCM_MOD_EN, &cmalwon->rtcclkctrl); + while (readl(&cmalwon->rtcclkctrl) != PRCM_MOD_EN) + ; +} + +/* + * select the HS1 or HS2 for DCO Freq + * return : CLKCTRL + */ +static u32 pll_dco_freq_sel(u32 clkout_dco) +{ + if (clkout_dco >= DCO_HS2_MIN && clkout_dco < DCO_HS2_MAX) + return SELFREQDCO_HS2; + else if (clkout_dco >= DCO_HS1_MIN && clkout_dco < DCO_HS1_MAX) + return SELFREQDCO_HS1; + else + return -1; +} + +/* + * select the sigma delta config + * return: sigma delta val + */ +static u32 pll_sigma_delta_val(u32 clkout_dco) +{ + u32 sig_val = 0; + + sig_val = (clkout_dco + 225) / 250; + sig_val = sig_val << 24; + + return sig_val; +} + +/* + * configure individual ADPLLJ + */ +static void pll_config(u32 base, u32 n, u32 m, u32 m2, + u32 clkctrl_val, int adpllj) +{ + const struct ad_pll *adpll = (struct ad_pll *)base; + u32 m2nval, mn2val, read_clkctrl = 0, clkout_dco = 0; + u32 sig_val = 0, hs_mod = 0; + + m2nval = (m2 << ADPLLJ_M2NDIV_M2SHIFT) | n; + mn2val = m; + + /* calculate clkout_dco */ + clkout_dco = ((OSC_0_FREQ / (n+1)) * m); + + /* sigma delta & Hs mode selection skip for ADPLLS*/ + if (adpllj) { + sig_val = pll_sigma_delta_val(clkout_dco); + hs_mod = pll_dco_freq_sel(clkout_dco); + } + + /* by-pass pll */ + read_clkctrl = readl(&adpll->clkctrl); + writel((read_clkctrl | ADPLLJ_CLKCTRL_IDLE), &adpll->clkctrl); + while ((readl(&adpll->status) & ADPLLJ_STATUS_BYPASSANDACK) + != ADPLLJ_STATUS_BYPASSANDACK) + ; + + /* clear TINITZ */ + read_clkctrl = readl(&adpll->clkctrl); + writel((read_clkctrl & ~ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + + /* + * ref_clk = 20/(n + 1); + * clkout_dco = ref_clk * m; + * clk_out = clkout_dco/m2; + */ + read_clkctrl = readl(&adpll->clkctrl) & + ~(ADPLLJ_CLKCTRL_LPMODE | + ADPLLJ_CLKCTRL_DRIFTGUARDIAN | + ADPLLJ_CLKCTRL_REGM4XEN); + writel(m2nval, &adpll->m2ndiv); + writel(mn2val, &adpll->mn2div); + + /* Skip for modena(ADPLLS) */ + if (adpllj) { + writel(sig_val, &adpll->fracdiv); + writel((read_clkctrl | hs_mod), &adpll->clkctrl); + } + + /* Load M2, N2 dividers of ADPLL */ + writel(ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); + writel(~ADPLLJ_TENABLEDIV_ENB, &adpll->tenablediv); + + /* Load M, N dividers of ADPLL */ + writel(ADPLLJ_TENABLE_ENB, &adpll->tenable); + writel(~ADPLLJ_TENABLE_ENB, &adpll->tenable); + + /* Configure CLKDCOLDOEN,CLKOUTLDOEN,CLKOUT Enable BITS */ + read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_CLKDCO; + if (adpllj) + writel((read_clkctrl | ADPLLJ_CLKCTRL_CLKDCO), + &adpll->clkctrl); + + /* Enable TINTZ and disable IDLE(PLL in Active & Locked Mode */ + read_clkctrl = readl(&adpll->clkctrl) & ~ADPLLJ_CLKCTRL_IDLE; + writel((read_clkctrl | ADPLLJ_CLKCTRL_TINITZ), &adpll->clkctrl); + + /* Wait for phase and freq lock */ + while ((readl(&adpll->status) & ADPLLJ_STATUS_PHSFRQLOCK) != + ADPLLJ_STATUS_PHSFRQLOCK) + ; +} + +static void unlock_pll_control_mmr(void) +{ + /* TRM 2.10.1.4 and 3.2.7-3.2.11 */ + writel(0x1EDA4C3D, 0x481C5040); + writel(0x2FF1AC2B, 0x48140060); + writel(0xF757FDC0, 0x48140064); + writel(0xE2BC3A6D, 0x48140068); + writel(0x1EBF131D, 0x4814006c); + writel(0x6F361E05, 0x48140070); +} + +static void mpu_pll_config(void) +{ + pll_config(MPU_PLL_BASE, MPU_N, MPU_M, MPU_M2, MPU_CLKCTRL, 0); +} + +static void l3_pll_config(void) +{ + u32 l3_osc_src, rd_osc_src = 0; + + l3_osc_src = L3_OSC_SRC; + rd_osc_src = readl(OSC_SRC_CTRL); + + if (OSC_SRC0 == l3_osc_src) + writel((rd_osc_src & 0xfffffffe)|0x0, OSC_SRC_CTRL); + else + writel((rd_osc_src & 0xfffffffe)|0x1, OSC_SRC_CTRL); + + pll_config(L3_PLL_BASE, L3_N, L3_M, L3_M2, L3_CLKCTRL, 1); +} + +void ddr_pll_config(unsigned int ddrpll_m) +{ + pll_config(DDR_PLL_BASE, DDR_N, DDR_M, DDR_M2, DDR_CLKCTRL, 1); +} + +void sata_pll_config(void) +{ + /* + * This sequence for configuring the SATA PLL + * resident in the control module is documented + * in TI8148 TRM section 21.3.1 + */ + writel(SATA_PLLCFG1, &spll->pllcfg1); + udelay(50); + + writel(SATA_PLLCFG3, &spll->pllcfg3); + udelay(50); + + writel(SATA_PLLCFG0_1, &spll->pllcfg0); + udelay(50); + + writel(SATA_PLLCFG0_2, &spll->pllcfg0); + udelay(50); + + writel(SATA_PLLCFG0_3, &spll->pllcfg0); + udelay(50); + + writel(SATA_PLLCFG0_4, &spll->pllcfg0); + udelay(50); + + while (((readl(&spll->pllstatus) & PLL_LOCK) == 0)) + ; +} + +void enable_dmm_clocks(void) +{ + writel(PRCM_MOD_EN, &cmdef->fwclkctrl); + writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); + writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); + while ((readl(&cmdef->emif0clkctrl)) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); + while ((readl(&cmdef->emif1clkctrl)) != PRCM_MOD_EN) + ; + while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) + ; + writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); + while ((readl(&cmdef->dmmclkctrl)) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); + while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) + ; +} + +void setup_clocks_for_console(void) +{ + unlock_pll_control_mmr(); + /* UART0 */ + writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); + while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) + ; +} +/* + * Configure the PLL/PRCM for necessary peripherals + */ +void prcm_init(void) +{ + /* Enable the control module */ + writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); + + /* Configure PLLs */ + mpu_pll_config(); + l3_pll_config(); + sata_pll_config(); + + /* Enable the required peripherals */ + enable_per_clocks(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti816x.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti816x.c new file mode 100644 index 0000000..ace4a5a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/clock_ti816x.c
@@ -0,0 +1,445 @@ +/* + * clock_ti816x.c + * + * Clocks for TI816X based boards + * + * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com> + * Antoine Tenart, <atenart@adeneo-embedded.com> + * + * Based on TI-PSP-04.00.02.14 : + * + * Copyright (C) 2009, Texas Instruments, Incorporated + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +#include <asm/emif.h> + +#define CM_PLL_BASE (CTRL_BASE + 0x0400) + +/* Main PLL */ +#define MAIN_N 64 +#define MAIN_P 0x1 +#define MAIN_INTFREQ1 0x8 +#define MAIN_FRACFREQ1 0x800000 +#define MAIN_MDIV1 0x2 +#define MAIN_INTFREQ2 0xE +#define MAIN_FRACFREQ2 0x0 +#define MAIN_MDIV2 0x1 +#define MAIN_INTFREQ3 0x8 +#define MAIN_FRACFREQ3 0xAAAAB0 +#define MAIN_MDIV3 0x3 +#define MAIN_INTFREQ4 0x9 +#define MAIN_FRACFREQ4 0x55554F +#define MAIN_MDIV4 0x3 +#define MAIN_INTFREQ5 0x9 +#define MAIN_FRACFREQ5 0x374BC6 +#define MAIN_MDIV5 0xC +#define MAIN_MDIV6 0x48 +#define MAIN_MDIV7 0x4 + +/* DDR PLL */ +#if defined(CONFIG_TI816X_DDR_PLL_400) /* 400 MHz */ +#define DDR_N 59 +#define DDR_P 0x1 +#define DDR_MDIV1 0x4 +#define DDR_INTFREQ2 0x8 +#define DDR_FRACFREQ2 0xD99999 +#define DDR_MDIV2 0x1E +#define DDR_INTFREQ3 0x8 +#define DDR_FRACFREQ3 0x0 +#define DDR_MDIV3 0x4 +#define DDR_INTFREQ4 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4 0x0 +#define DDR_MDIV4 0x4 +#define DDR_INTFREQ5 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5 0x0 +#define DDR_MDIV5 0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_531) /* 531 MHz */ +#define DDR_N 59 +#define DDR_P 0x1 +#define DDR_MDIV1 0x3 +#define DDR_INTFREQ2 0x8 +#define DDR_FRACFREQ2 0xD99999 +#define DDR_MDIV2 0x1E +#define DDR_INTFREQ3 0x8 +#define DDR_FRACFREQ3 0x0 +#define DDR_MDIV3 0x4 +#define DDR_INTFREQ4 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4 0x0 +#define DDR_MDIV4 0x4 +#define DDR_INTFREQ5 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5 0x0 +#define DDR_MDIV5 0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_675) /* 675 MHz */ +#define DDR_N 50 +#define DDR_P 0x1 +#define DDR_MDIV1 0x2 +#define DDR_INTFREQ2 0x9 +#define DDR_FRACFREQ2 0x0 +#define DDR_MDIV2 0x19 +#define DDR_INTFREQ3 0x13 +#define DDR_FRACFREQ3 0x800000 +#define DDR_MDIV3 0x2 +#define DDR_INTFREQ4 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4 0x0 +#define DDR_MDIV4 0x4 +#define DDR_INTFREQ5 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5 0x0 +#define DDR_MDIV5 0x4 +#elif defined(CONFIG_TI816X_DDR_PLL_796) /* 796 MHz */ +#define DDR_N 59 +#define DDR_P 0x1 +#define DDR_MDIV1 0x2 +#define DDR_INTFREQ2 0x8 +#define DDR_FRACFREQ2 0xD99999 +#define DDR_MDIV2 0x1E +#define DDR_INTFREQ3 0x8 +#define DDR_FRACFREQ3 0x0 +#define DDR_MDIV3 0x4 +#define DDR_INTFREQ4 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ4 0x0 +#define DDR_MDIV4 0x4 +#define DDR_INTFREQ5 0xE /* Expansion DDR clk */ +#define DDR_FRACFREQ5 0x0 +#define DDR_MDIV5 0x4 +#endif + +#define CONTROL_STATUS (CTRL_BASE + 0x40) +#define DDR_RCD (CTRL_BASE + 0x070C) +#define CM_TIMER1_CLKSEL (PRCM_BASE + 0x390) +#define DMM_PAT_BASE_ADDR (DMM_BASE + 0x420) +#define CM_ALWON_CUST_EFUSE_CLKCTRL (PRCM_BASE + 0x1628) + +#define INTCPS_SYSCONFIG 0x48200010 +#define CM_SYSCLK10_CLKSEL 0x48180324 + +struct cm_pll { + unsigned int mainpll_ctrl; /* offset 0x400 */ + unsigned int mainpll_pwd; + unsigned int mainpll_freq1; + unsigned int mainpll_div1; + unsigned int mainpll_freq2; + unsigned int mainpll_div2; + unsigned int mainpll_freq3; + unsigned int mainpll_div3; + unsigned int mainpll_freq4; + unsigned int mainpll_div4; + unsigned int mainpll_freq5; + unsigned int mainpll_div5; + unsigned int resv0[1]; + unsigned int mainpll_div6; + unsigned int resv1[1]; + unsigned int mainpll_div7; + unsigned int ddrpll_ctrl; /* offset 0x440 */ + unsigned int ddrpll_pwd; + unsigned int resv2[1]; + unsigned int ddrpll_div1; + unsigned int ddrpll_freq2; + unsigned int ddrpll_div2; + unsigned int ddrpll_freq3; + unsigned int ddrpll_div3; + unsigned int ddrpll_freq4; + unsigned int ddrpll_div4; + unsigned int ddrpll_freq5; + unsigned int ddrpll_div5; + unsigned int videopll_ctrl; /* offset 0x470 */ + unsigned int videopll_pwd; + unsigned int videopll_freq1; + unsigned int videopll_div1; + unsigned int videopll_freq2; + unsigned int videopll_div2; + unsigned int videopll_freq3; + unsigned int videopll_div3; + unsigned int resv3[4]; + unsigned int audiopll_ctrl; /* offset 0x4A0 */ + unsigned int audiopll_pwd; + unsigned int resv4[2]; + unsigned int audiopll_freq2; + unsigned int audiopll_div2; + unsigned int audiopll_freq3; + unsigned int audiopll_div3; + unsigned int audiopll_freq4; + unsigned int audiopll_div4; + unsigned int audiopll_freq5; + unsigned int audiopll_div5; +}; + +const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; +const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; +const struct cm_pll *cmpll = (struct cm_pll *)CM_PLL_BASE; +const struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + +void enable_dmm_clocks(void) +{ + writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); + writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); + writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); + + /* Wait for clocks to be active */ + while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) + ; + /* Wait for emif0 to be fully functional, including OCP */ + while (((readl(&cmdef->emif0clkctrl) >> 17) & 0x3) != 0) + ; + /* Wait for emif1 to be fully functional, including OCP */ + while (((readl(&cmdef->emif1clkctrl) >> 17) & 0x3) != 0) + ; + + writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); + /* Wait for dmm to be fully functional, including OCP */ + while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0) + ; + + /* Enable Tiled Access */ + writel(0x80000000, DMM_PAT_BASE_ADDR); +} + +/* assume delay is aprox at least 1us */ +static void ddr_delay(int d) +{ + int i; + + /* + * read a control register. + * this is a bit more delay and cannot be optimized by the compiler + * assuming one read takes 200 cycles and A8 is runing 1 GHz + * somewhat conservative setting + */ + for (i = 0; i < 50*d; i++) + readl(CONTROL_STATUS); +} + +static void main_pll_init_ti816x(void) +{ + u32 main_pll_ctrl = 0; + + /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ + main_pll_ctrl = readl(&cmpll->mainpll_ctrl); + main_pll_ctrl &= 0xFFFFFFFB; + main_pll_ctrl |= BIT(2); + writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + + /* Enable PLL by setting BIT3 in its ctrl reg */ + main_pll_ctrl = readl(&cmpll->mainpll_ctrl); + main_pll_ctrl &= 0xFFFFFFF7; + main_pll_ctrl |= BIT(3); + writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + + /* Write the values of N,P in the CTRL reg */ + main_pll_ctrl = readl(&cmpll->mainpll_ctrl); + main_pll_ctrl &= 0xFF; + main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8); + writel(main_pll_ctrl, &cmpll->mainpll_ctrl); + + /* Power up clock1-7 */ + writel(0x0, &cmpll->mainpll_pwd); + + /* Program the freq and divider values for clock1-7 */ + writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1), + &cmpll->mainpll_freq1); + writel(((1<<8) | MAIN_MDIV1), &cmpll->mainpll_div1); + + writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2), + &cmpll->mainpll_freq2); + writel(((1<<8) | MAIN_MDIV2), &cmpll->mainpll_div2); + + writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3), + &cmpll->mainpll_freq3); + writel(((1<<8) | MAIN_MDIV3), &cmpll->mainpll_div3); + + writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4), + &cmpll->mainpll_freq4); + writel(((1<<8) | MAIN_MDIV4), &cmpll->mainpll_div4); + + writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5), + &cmpll->mainpll_freq5); + writel(((1<<8) | MAIN_MDIV5), &cmpll->mainpll_div5); + + writel((1<<8 | MAIN_MDIV6), &cmpll->mainpll_div6); + + writel((1<<8 | MAIN_MDIV7), &cmpll->mainpll_div7); + + /* Wait for PLL to lock */ + while ((readl(&cmpll->mainpll_ctrl) & BIT(7)) != BIT(7)) + ; + + /* Put the PLL in normal mode, disable bypass */ + main_pll_ctrl = readl(&cmpll->mainpll_ctrl); + main_pll_ctrl &= 0xFFFFFFFB; + writel(main_pll_ctrl, &cmpll->mainpll_ctrl); +} + +static void ddr_pll_bypass_ti816x(void) +{ + u32 ddr_pll_ctrl = 0; + + /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ + ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); + ddr_pll_ctrl &= 0xFFFFFFFB; + ddr_pll_ctrl |= BIT(2); + writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); +} + +static void ddr_pll_init_ti816x(void) +{ + u32 ddr_pll_ctrl = 0; + /* Enable PLL by setting BIT3 in its ctrl reg */ + ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); + ddr_pll_ctrl &= 0xFFFFFFF7; + ddr_pll_ctrl |= BIT(3); + writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); + + /* Write the values of N,P in the CTRL reg */ + ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); + ddr_pll_ctrl &= 0xFF; + ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8); + writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); + + ddr_delay(10); + + /* Power up clock1-5 */ + writel(0x0, &cmpll->ddrpll_pwd); + + /* Program the freq and divider values for clock1-3 */ + writel(((0<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); + ddr_delay(1); + writel(((1<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); + writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2), + &cmpll->ddrpll_freq2); + writel(((1<<8) | DDR_MDIV2), &cmpll->ddrpll_div2); + writel(((0<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); + ddr_delay(1); + writel(((1<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); + ddr_delay(1); + writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), + &cmpll->ddrpll_freq3); + ddr_delay(1); + writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), + &cmpll->ddrpll_freq3); + + ddr_delay(5); + + /* Wait for PLL to lock */ + while ((readl(&cmpll->ddrpll_ctrl) & BIT(7)) != BIT(7)) + ; + + /* Power up RCD */ + writel(BIT(0), DDR_RCD); +} + +static void peripheral_enable(void) +{ + /* Wake-up the l3_slow clock */ + writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); + + /* + * Note on Timers: + * There are 8 timers(0-7) out of which timer 0 is a secure timer. + * Timer 0 mux should not be changed + * + * To access the timer registers we need the to be + * enabled which is what we do in the first step + */ + + /* Enable timer1 */ + writel(PRCM_MOD_EN, &cmalwon->timer1clkctrl); + /* Select timer1 clock to be CLKIN (27MHz) */ + writel(BIT(1), CM_TIMER1_CLKSEL); + + /* Wait for timer1 to be ON-ACTIVE */ + while (((readl(&cmalwon->l3slowclkstctrl) + & (0x80000<<1))>>20) != 1) + ; + /* Wait for timer1 to be enabled */ + while (((readl(&cmalwon->timer1clkctrl) & 0x30000)>>16) != 0) + ; + /* Active posted mode */ + writel(PRCM_MOD_EN, (DM_TIMER1_BASE + 0x54)); + while (readl(DM_TIMER1_BASE + 0x10) & BIT(0)) + ; + /* Start timer1 */ + writel(BIT(0), (DM_TIMER1_BASE + 0x38)); + + /* eFuse */ + writel(PRCM_MOD_EN, CM_ALWON_CUST_EFUSE_CLKCTRL); + while (readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != PRCM_MOD_EN) + ; + + /* Enable gpio0 */ + writel(PRCM_MOD_EN, &cmalwon->gpio0clkctrl); + while (readl(&cmalwon->gpio0clkctrl) != PRCM_MOD_EN) + ; + writel((BIT(8)), &cmalwon->gpio0clkctrl); + + /* Enable spi */ + writel(PRCM_MOD_EN, &cmalwon->spiclkctrl); + while (readl(&cmalwon->spiclkctrl) != PRCM_MOD_EN) + ; + + /* Enable i2c0 */ + writel(PRCM_MOD_EN, &cmalwon->i2c0clkctrl); + while (readl(&cmalwon->i2c0clkctrl) != PRCM_MOD_EN) + ; + + /* Enable ethernet0 */ + writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl); + writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl); + writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl); + + /* Enable hsmmc */ + writel(PRCM_MOD_EN, &cmalwon->sdioclkctrl); + while (readl(&cmalwon->sdioclkctrl) != PRCM_MOD_EN) + ; +} + +void setup_clocks_for_console(void) +{ + /* Fix ROM code bug - from TI-PSP-04.00.02.14 */ + writel(0x0, CM_SYSCLK10_CLKSEL); + + ddr_pll_bypass_ti816x(); + + /* Enable uart0-2 */ + writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); + while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmalwon->uart1clkctrl); + while (readl(&cmalwon->uart1clkctrl) != PRCM_MOD_EN) + ; + writel(PRCM_MOD_EN, &cmalwon->uart2clkctrl); + while (readl(&cmalwon->uart2clkctrl) != PRCM_MOD_EN) + ; + while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) + ; +} + +void prcm_init(void) +{ + /* Enable the control */ + writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); + + main_pll_init_ti816x(); + ddr_pll_init_ti816x(); + + /* + * With clk freqs setup to desired values, + * enable the required peripherals + */ + peripheral_enable(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/config.mk b/u-boot-imx/arch/arm/cpu/armv7/am33xx/config.mk new file mode 100644 index 0000000..5294d16 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/config.mk
@@ -0,0 +1,11 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +ALL-y += MLO +ALL-$(CONFIG_SPL_SPI_SUPPORT) += MLO.byteswap +else +ALL-y += u-boot.img +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/ddr.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/ddr.c new file mode 100644 index 0000000..f5b16b4 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -0,0 +1,323 @@ +/* + * DDR Configuration for AM33xx devices. + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/cpu.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/emif.h> + +/** + * Base address for EMIF instances + */ +static struct emif_reg_struct *emif_reg[2] = { + (struct emif_reg_struct *)EMIF4_0_CFG_BASE, + (struct emif_reg_struct *)EMIF4_1_CFG_BASE}; + +/** + * Base addresses for DDR PHY cmd/data regs + */ +static struct ddr_cmd_regs *ddr_cmd_reg[2] = { + (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR, + (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2}; + +static struct ddr_data_regs *ddr_data_reg[2] = { + (struct ddr_data_regs *)DDR_PHY_DATA_ADDR, + (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2}; + +/** + * Base address for ddr io control instances + */ +static struct ddr_cmdtctrl *ioctrl_reg = { + (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR}; + +static inline u32 get_mr(int nr, u32 cs, u32 mr_addr) +{ + u32 mr; + + mr_addr |= cs << EMIF_REG_CS_SHIFT; + writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg); + + mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data); + debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr); + if (((mr & 0x0000ff00) >> 8) == (mr & 0xff) && + ((mr & 0x00ff0000) >> 16) == (mr & 0xff) && + ((mr & 0xff000000) >> 24) == (mr & 0xff)) + return mr & 0xff; + else + return mr; +} + +static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val) +{ + mr_addr |= cs << EMIF_REG_CS_SHIFT; + writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg); + writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data); +} + +static void configure_mr(int nr, u32 cs) +{ + u32 mr_addr; + + while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK) + ; + set_mr(nr, cs, LPDDR2_MR10, 0x56); + + set_mr(nr, cs, LPDDR2_MR1, 0x43); + set_mr(nr, cs, LPDDR2_MR2, 0x2); + + mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK; + set_mr(nr, cs, mr_addr, 0x2); +} + +/* + * Configure EMIF4D5 registers and MR registers For details about these magic + * values please see the EMIF registers section of the TRM. + */ +void config_sdram_emif4d5(const struct emif_regs *regs, int nr) +{ + writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl); + writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw); + writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); + + writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config); + writel(regs->emif_rd_wr_lvl_rmp_win, + &emif_reg[nr]->emif_rd_wr_lvl_rmp_win); + writel(regs->emif_rd_wr_lvl_rmp_ctl, + &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); + writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl); + writel(regs->emif_rd_wr_exec_thresh, + &emif_reg[nr]->emif_rd_wr_exec_thresh); + + /* + * for most SOCs these registers won't need to be changed so only + * write to these registers if someone explicitly has set the + * register's value. + */ + if(regs->emif_cos_config) { + writel(regs->emif_prio_class_serv_map, &emif_reg[nr]->emif_prio_class_serv_map); + writel(regs->emif_connect_id_serv_1_map, &emif_reg[nr]->emif_connect_id_serv_1_map); + writel(regs->emif_connect_id_serv_2_map, &emif_reg[nr]->emif_connect_id_serv_2_map); + writel(regs->emif_cos_config, &emif_reg[nr]->emif_cos_config); + } + + /* + * Sequence to ensure that the PHY is in a known state prior to + * startting hardware leveling. Also acts as to latch some state from + * the EMIF into the PHY. + */ + writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc); + writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc); + writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc); + + clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl, + EMIF_REG_INITREF_DIS_MASK); + + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); + writel(regs->sdram_config, &cstat->secure_emif_sdram_config); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); + + /* Perform hardware leveling. */ + udelay(1000); + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); + writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) | + 0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); + + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl); + + /* Enable read leveling */ + writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl); + + /* + * Enable full read and write leveling. Wait for read and write + * leveling bit to clear RDWRLVLFULL_START bit 31 + */ + while((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000) != 0) + ; + + /* Check the timeout register to see if leveling is complete */ + if((readl(&emif_reg[nr]->emif_status) & 0x70) != 0) + puts("DDR3 H/W leveling incomplete with errors\n"); + + if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) { + configure_mr(nr, 0); + configure_mr(nr, 1); + } +} + +/** + * Configure SDRAM + */ +void config_sdram(const struct emif_regs *regs, int nr) +{ + if (regs->zq_config) { + writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); + writel(regs->sdram_config, &cstat->secure_emif_sdram_config); + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); + } + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw); + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); +} + +/** + * Set SDRAM timings + */ +void set_sdram_timings(const struct emif_regs *regs, int nr) +{ + writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1); + writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw); + writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2); + writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw); + writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3); + writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw); +} + +/* + * Configure EXT PHY registers for hardware leveling + */ +static void ext_phy_settings(const struct emif_regs *regs, int nr) +{ + /* + * Enable hardware leveling on the EMIF. For details about these + * magic values please see the EMIF registers section of the TRM. + */ + writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1); + writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22_shdw); + writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23); + writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23_shdw); + writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24); + writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24_shdw); + writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25); + writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25_shdw); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26_shdw); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27_shdw); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28_shdw); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29_shdw); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30); + writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34_shdw); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35); + writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35_shdw); + writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36); + writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw); + + /* + * Sequence to ensure that the PHY is again in a known state after + * hardware leveling. + */ + writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc); + writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc); + writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc); +} + +/** + * Configure DDR PHY + */ +void config_ddr_phy(const struct emif_regs *regs, int nr) +{ + /* + * Disable initialization and refreshes for now until we + * finish programming EMIF regs. + * Also set time between rising edge of DDR_RESET to rising + * edge of DDR_CKE to > 500us per memory spec. + */ +#ifndef CONFIG_AM43XX + setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl, + EMIF_REG_INITREF_DIS_MASK); +#endif + if (regs->zq_config) + writel(0x80003100, &emif_reg[nr]->emif_sdram_ref_ctrl); + + writel(regs->emif_ddr_phy_ctlr_1, + &emif_reg[nr]->emif_ddr_phy_ctrl_1); + writel(regs->emif_ddr_phy_ctlr_1, + &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw); + + if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) + ext_phy_settings(regs, nr); +} + +/** + * Configure DDR CMD control registers + */ +void config_cmd_ctrl(const struct cmd_control *cmd, int nr) +{ + if (!cmd) + return; + + writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio); + writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout); + + writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio); + writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout); + + writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio); + writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout); +} + +/** + * Configure DDR DATA registers + */ +void config_ddr_data(const struct ddr_data *data, int nr) +{ + int i; + + if (!data) + return; + + for (i = 0; i < DDR_DATA_REGS_NR; i++) { + writel(data->datardsratio0, + &(ddr_data_reg[nr]+i)->dt0rdsratio0); + writel(data->datawdsratio0, + &(ddr_data_reg[nr]+i)->dt0wdsratio0); + writel(data->datawiratio0, + &(ddr_data_reg[nr]+i)->dt0wiratio0); + writel(data->datagiratio0, + &(ddr_data_reg[nr]+i)->dt0giratio0); + writel(data->datafwsratio0, + &(ddr_data_reg[nr]+i)->dt0fwsratio0); + writel(data->datawrsratio0, + &(ddr_data_reg[nr]+i)->dt0wrsratio0); + } +} + +void config_io_ctrl(const struct ctrl_ioregs *ioregs) +{ + if (!ioregs) + return; + + writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl); + writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl); + writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl); + writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl); + writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl); +#ifdef CONFIG_AM43XX + writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl); + writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl); + writel(ioregs->emif_sdram_config_ext, + &ioctrl_reg->emif_sdram_config_ext); +#endif +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/emif4.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/emif4.c new file mode 100644 index 0000000..9cf816c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/emif4.c
@@ -0,0 +1,139 @@ +/* + * emif4.c + * + * AM33XX emif4 configuration file + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/ddr_defs.h> +#include <asm/arch/hardware.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/emif.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + sdram_init(); +#endif + + /* dram_init must store complete ramsize in gd->ram_size */ + gd->ram_size = get_ram_size( + (void *)CONFIG_SYS_SDRAM_BASE, + CONFIG_MAX_RAM_BANK_SIZE); + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} + + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +#ifdef CONFIG_TI81XX +static struct dmm_lisa_map_regs *hw_lisa_map_regs = + (struct dmm_lisa_map_regs *)DMM_BASE; +#endif +#ifndef CONFIG_TI816X +static struct vtp_reg *vtpreg[2] = { + (struct vtp_reg *)VTP0_CTRL_ADDR, + (struct vtp_reg *)VTP1_CTRL_ADDR}; +#endif +#ifdef CONFIG_AM33XX +static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; +#endif +#ifdef CONFIG_AM43XX +static struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR; +static struct cm_device_inst *cm_device = + (struct cm_device_inst *)CM_DEVICE_INST; +#endif + +#ifdef CONFIG_TI81XX +void config_dmm(const struct dmm_lisa_map_regs *regs) +{ + enable_dmm_clocks(); + + writel(0, &hw_lisa_map_regs->dmm_lisa_map_3); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_2); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_1); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_0); + + writel(regs->dmm_lisa_map_3, &hw_lisa_map_regs->dmm_lisa_map_3); + writel(regs->dmm_lisa_map_2, &hw_lisa_map_regs->dmm_lisa_map_2); + writel(regs->dmm_lisa_map_1, &hw_lisa_map_regs->dmm_lisa_map_1); + writel(regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0); +} +#endif + +#ifndef CONFIG_TI816X +static void config_vtp(int nr) +{ + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE, + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN), + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN, + &vtpreg[nr]->vtp0ctrlreg); + + /* Poll for READY */ + while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) != + VTP_CTRL_READY) + ; +} +#endif + +void __weak ddr_pll_config(unsigned int ddrpll_m) +{ +} + +void config_ddr(unsigned int pll, const struct ctrl_ioregs *ioregs, + const struct ddr_data *data, const struct cmd_control *ctrl, + const struct emif_regs *regs, int nr) +{ + ddr_pll_config(pll); +#ifndef CONFIG_TI816X + config_vtp(nr); +#endif + config_cmd_ctrl(ctrl, nr); + + config_ddr_data(data, nr); +#ifdef CONFIG_AM33XX + config_io_ctrl(ioregs); + + /* Set CKE to be controlled by EMIF/DDR PHY */ + writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); + +#endif +#ifdef CONFIG_AM43XX + writel(readl(&cm_device->cm_dll_ctrl) & ~0x1, &cm_device->cm_dll_ctrl); + while ((readl(&cm_device->cm_dll_ctrl) & CM_DLL_READYST) == 0) + ; + + config_io_ctrl(ioregs); + + /* Set CKE to be controlled by EMIF/DDR PHY */ + writel(DDR_CKE_CTRL_NORMAL, &ddrctrl->ddrckectrl); + + /* Allow EMIF to control DDR_RESET */ + writel(0x00000000, &ddrctrl->ddrioctrl); +#endif + + /* Program EMIF instance */ + config_ddr_phy(regs, nr); + set_sdram_timings(regs, nr); + if (get_emif_rev(EMIF1_BASE) == EMIF_4D5) + config_sdram_emif4d5(regs, nr); + else + config_sdram(regs, nr); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/mux.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/mux.c new file mode 100644 index 0000000..2ded472 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/mux.c
@@ -0,0 +1,33 @@ +/* + * mux.c + * + * 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> +#include <asm/arch/mux.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> + +/* + * Configure the pin mux for the module + */ +void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux) +{ + int i; + + if (!mod_pin_mux) + return; + + for (i = 0; mod_pin_mux[i].reg_offset != -1; i++) + MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/sys_info.c b/u-boot-imx/arch/arm/cpu/armv7/am33xx/sys_info.c new file mode 100644 index 0000000..781d83f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/sys_info.c
@@ -0,0 +1,184 @@ +/* + * sys_info.c + * + * System information functions + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> +#include <power/tps65910.h> +#include <linux/compiler.h> + +struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE; + +/** + * get_cpu_rev(void) - extract rev info + */ +u32 get_cpu_rev(void) +{ + u32 id; + u32 rev; + + id = readl(DEVICE_ID); + rev = (id >> 28) & 0xff; + + return rev; +} + +/** + * get_cpu_type(void) - extract cpu info + */ +u32 get_cpu_type(void) +{ + u32 id = 0; + u32 partnum; + + id = readl(DEVICE_ID); + partnum = (id >> 12) & 0xffff; + + return partnum; +} + +/** + * get_board_rev() - setup to pass kernel board revision information + * returns: 0 for the ATAG REVISION tag value. + */ +u32 __weak get_board_rev(void) +{ + return 0; +} + +/** + * get_device_type(): tell if GP/HS/EMU/TST + */ +u32 get_device_type(void) +{ + int mode; + mode = readl(&cstat->statusreg) & (DEVICE_MASK); + return mode >>= 8; +} + +/** + * get_sysboot_value(void) - return SYS_BOOT[4:0] + */ +u32 get_sysboot_value(void) +{ + int mode; + mode = readl(&cstat->statusreg) & (SYSBOOT_MASK); + return mode; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +static char *cpu_revs[] = { + "1.0", + "2.0", + "2.1"}; + + +static char *dev_types[] = { + "TST", + "EMU", + "HS", + "GP"}; + +/** + * Print CPU information + */ +int print_cpuinfo(void) +{ + char *cpu_s, *sec_s, *rev_s; + + switch (get_cpu_type()) { + case AM335X: + cpu_s = "AM335X"; + break; + case TI81XX: + cpu_s = "TI81XX"; + break; + default: + cpu_s = "Unknown CPU type"; + break; + } + + if (get_cpu_rev() < ARRAY_SIZE(cpu_revs)) + rev_s = cpu_revs[get_cpu_rev()]; + else + rev_s = "?"; + + if (get_device_type() < ARRAY_SIZE(dev_types)) + sec_s = dev_types[get_device_type()]; + else + sec_s = "?"; + + printf("%s-%s rev %s\n", cpu_s, sec_s, rev_s); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +#ifdef CONFIG_AM33XX +int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev) +{ + int sil_rev; + + sil_rev = readl(&cdev->deviceid) >> 28; + + if (sil_rev == 1) + /* PG 2.0, efuse may not be set. */ + return MPUPLL_M_800; + else if (sil_rev >= 2) { + /* Check what the efuse says our max speed is. */ + int efuse_arm_mpu_max_freq; + efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma); + switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) { + case AM335X_ZCZ_1000: + return MPUPLL_M_1000; + case AM335X_ZCZ_800: + return MPUPLL_M_800; + case AM335X_ZCZ_720: + return MPUPLL_M_720; + case AM335X_ZCZ_600: + case AM335X_ZCE_600: + return MPUPLL_M_600; + case AM335X_ZCZ_300: + case AM335X_ZCE_300: + return MPUPLL_M_300; + } + } + + /* PG 1.0 or otherwise unknown, use the PG1.0 max */ + return MPUPLL_M_720; +} + +int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency) +{ + /* For PG2.1 and later, we have one set of values. */ + if (sil_rev >= 2) { + switch (frequency) { + case MPUPLL_M_1000: + return TPS65910_OP_REG_SEL_1_3_2_5; + case MPUPLL_M_800: + return TPS65910_OP_REG_SEL_1_2_6; + case MPUPLL_M_720: + return TPS65910_OP_REG_SEL_1_2_0; + case MPUPLL_M_600: + case MPUPLL_M_300: + return TPS65910_OP_REG_SEL_1_1_3; + } + } + + /* Default to PG1.0/PG2.0 values. */ + return TPS65910_OP_REG_SEL_1_1_3; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds new file mode 100644 index 0000000..07cf267 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/am33xx/u-boot-spl.lds
@@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + arch/arm/cpu/armv7/start.o (.text) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } >.sram + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/arch_timer.c b/u-boot-imx/arch/arm/cpu/armv7/arch_timer.c new file mode 100644 index 0000000..0588e2b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/arch_timer.c
@@ -0,0 +1,58 @@ +/* + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <div64.h> + +DECLARE_GLOBAL_DATA_PTR; + +int timer_init(void) +{ + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ; + + return 0; +} + +unsigned long long get_ticks(void) +{ + ulong nowl, nowu; + + asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu)); + + gd->arch.tbl = nowl; + gd->arch.tbu = nowu; + + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + + +ulong get_timer(ulong base) +{ + return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base; +} + +void __udelay(unsigned long usec) +{ + unsigned long long endtime; + + endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, + 1000UL); + + endtime += get_ticks(); + + while (get_ticks() < endtime) + ; +} + +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/armada-xp/Makefile b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/Makefile new file mode 100644 index 0000000..737159b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/Makefile
@@ -0,0 +1,9 @@ +# +# Copyright (C) 2014 Stefan Roese <sr@denx.de> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o +obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_SPL_BUILD) += lowlevel_spl.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/armada-xp/cpu.c b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/cpu.c new file mode 100644 index 0000000..1cf70a9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/cpu.c
@@ -0,0 +1,193 @@ +/* + * Copyright (C) 2014 Stefan Roese <sr@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/soc.h> + +#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) +#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + +static struct mbus_win windows[] = { + /* PCIE MEM address space */ + { DEFADR_PCI_MEM, 256 << 20, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_MEM }, + + /* PCIE IO address space */ + { DEFADR_PCI_IO, 64 << 10, CPU_TARGET_PCIE13, CPU_ATTR_PCIE_IO }, + + /* SPI */ + { DEFADR_SPIF, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI, + CPU_ATTR_SPIFLASH }, + + /* NOR */ + { DEFADR_BOOTROM, 8 << 20, CPU_TARGET_DEVICEBUS_BOOTROM_SPI, + CPU_ATTR_BOOTROM }, +}; + +void reset_cpu(unsigned long ignored) +{ + struct mvebu_system_registers *reg = + (struct mvebu_system_registers *)MVEBU_SYSTEM_REG_BASE; + + writel(readl(®->rstoutn_mask) | 1, ®->rstoutn_mask); + writel(readl(®->sys_soft_rst) | 1, ®->sys_soft_rst); + while (1) + ; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + u16 devid = (readl(MVEBU_REG_PCIE_DEVID) >> 16) & 0xffff; + u8 revid = readl(MVEBU_REG_PCIE_REVID) & 0xff; + + puts("SoC: "); + + switch (devid) { + case SOC_MV78460_ID: + puts("MV78460-"); + break; + default: + puts("Unknown-"); + break; + } + + switch (revid) { + case 1: + puts("A0\n"); + break; + case 2: + puts("B0\n"); + break; + default: + puts("??\n"); + break; + } + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */ + +/* + * This function initialize Controller DRAM Fastpath windows. + * It takes the CS size information from the 0x1500 scratch registers + * and sets the correct windows sizes and base addresses accordingly. + * + * These values are set in the scratch registers by the Marvell + * DDR3 training code, which is executed by the BootROM before the + * main payload (U-Boot) is executed. This training code is currently + * only available in the Marvell U-Boot version. It needs to be + * ported to mainline U-Boot SPL at some point. + */ +static void update_sdram_window_sizes(void) +{ + u64 base = 0; + u32 size, temp; + int i; + + for (i = 0; i < SDRAM_MAX_CS; i++) { + size = readl((MVEBU_SDRAM_SCRATCH + (i * 8))) & SDRAM_ADDR_MASK; + if (size != 0) { + size |= ~(SDRAM_ADDR_MASK); + + /* Set Base Address */ + temp = (base & 0xFF000000ll) | ((base >> 32) & 0xF); + writel(temp, MVEBU_SDRAM_BASE + DDR_BASE_CS_OFF(i)); + + /* + * Check if out of max window size and resize + * the window + */ + temp = (readl(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)) & + ~(SDRAM_ADDR_MASK)) | 1; + temp |= (size & SDRAM_ADDR_MASK); + writel(temp, MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i)); + + base += ((u64)size + 1); + } else { + /* + * Disable window if not used, otherwise this + * leads to overlapping enabled windows with + * pretty strange results + */ + clrbits_le32(MVEBU_SDRAM_BASE + DDR_SIZE_CS_OFF(i), 1); + } + } +} + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + /* Linux expects the internal registers to be at 0xf1000000 */ + writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG); + + /* + * We need to call mvebu_mbus_probe() before calling + * update_sdram_window_sizes() as it disables all previously + * configured mbus windows and then configures them as + * required for U-Boot. Calling update_sdram_window_sizes() + * without this configuration will not work, as the internal + * registers can't be accessed reliably because of potenial + * double mapping. + * After updating the SDRAM access windows we need to call + * mvebu_mbus_probe() again, as this now correctly configures + * the SDRAM areas that are later used by the MVEBU drivers + * (e.g. USB, NETA). + */ + + /* + * First disable all windows + */ + mvebu_mbus_probe(NULL, 0); + + /* + * Now the SDRAM access windows can be reconfigured using + * the information in the SDRAM scratch pad registers + */ + update_sdram_window_sizes(); + + /* + * Finally the mbus windows can be configured with the + * updated SDRAM sizes + */ + mvebu_mbus_probe(windows, ARRAY_SIZE(windows)); + + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * SOC specific misc init + */ +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + /* Nothing yet, perhaps we need something here later */ + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ + +#ifdef CONFIG_MVNETA +int cpu_eth_init(bd_t *bis) +{ + mvneta_initialize(bis, MVEBU_EGIGA0_BASE, 0, CONFIG_PHY_BASE_ADDR + 0); + mvneta_initialize(bis, MVEBU_EGIGA1_BASE, 1, CONFIG_PHY_BASE_ADDR + 1); + mvneta_initialize(bis, MVEBU_EGIGA2_BASE, 2, CONFIG_PHY_BASE_ADDR + 2); + mvneta_initialize(bis, MVEBU_EGIGA3_BASE, 3, CONFIG_PHY_BASE_ADDR + 3); + + return 0; +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S new file mode 100644 index 0000000..69da7fe --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/lowlevel_spl.S
@@ -0,0 +1,61 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(save_boot_params) + b save_boot_params_ret +ENDPROC(save_boot_params) + +/* + * cache_inv - invalidate Cache line + * r0 - dest + */ + .global cache_inv + .type cache_inv, %function + cache_inv: + + stmfd sp!, {r1-r12} + + mcr p15, 0, r0, c7, c6, 1 + + ldmfd sp!, {r1-r12} + bx lr + + +/* + * flush_l1_v6 - l1 cache clean invalidate + * r0 - dest + */ + .global flush_l1_v6 + .type flush_l1_v6, %function + flush_l1_v6: + + stmfd sp!, {r1-r12} + + mcr p15, 0, r0, c7, c10, 5 /* @ data memory barrier */ + mcr p15, 0, r0, c7, c14, 1 /* @ clean & invalidate D line */ + mcr p15, 0, r0, c7, c10, 4 /* @ data sync barrier */ + + ldmfd sp!, {r1-r12} + bx lr + + +/* + * flush_l1_v7 - l1 cache clean invalidate + * r0 - dest + */ + .global flush_l1_v7 + .type flush_l1_v7, %function + flush_l1_v7: + + stmfd sp!, {r1-r12} + + dmb /* @data memory barrier */ + mcr p15, 0, r0, c7, c14, 1 /* @ clean & invalidate D line */ + dsb /* @data sync barrier */ + + ldmfd sp!, {r1-r12} + bx lr
diff --git a/u-boot-imx/arch/arm/cpu/armv7/armada-xp/spl.c b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/spl.c new file mode 100644 index 0000000..402e520 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/armada-xp/spl.c
@@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Stefan Roese <sr@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/soc.h> + +DECLARE_GLOBAL_DATA_PTR; + +u32 spl_boot_device(void) +{ + /* Right now only booting via SPI NOR flash is supported */ + return BOOT_DEVICE_SPI; +} + +void board_init_f(ulong dummy) +{ + /* Set global data pointer */ + gd = &gdata; + + /* Linux expects the internal registers to be at 0xf1000000 */ + arch_cpu_init(); + + preloader_console_init(); + + /* First init the serdes PHY's */ + serdes_phy_config(); + + /* Setup DDR */ + ddr3_init(); + + board_init_r(NULL, 0); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/Makefile b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/Makefile new file mode 100644 index 0000000..f24aeb3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/Makefile
@@ -0,0 +1,13 @@ +# +# Copyright 2013 Broadcom Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += reset.o +obj-y += clk-core.o +obj-y += clk-bcm281xx.o +obj-y += clk-sdio.o +obj-y += clk-bsc.o +obj-$(CONFIG_BCM_SF2_ETH) += clk-eth.o +obj-y += clk-usb-otg.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c new file mode 100644 index 0000000..7e25255 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c
@@ -0,0 +1,573 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * + * bcm281xx-specific clock tables + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include <asm/kona-common/clk.h> +#include "clk-core.h" + +#define CLOCK_1K 1000 +#define CLOCK_1M (CLOCK_1K * 1000) + +/* declare a reference clock */ +#define DECLARE_REF_CLK(clk_name, clk_parent, clk_rate, clk_div) \ +static struct refclk clk_name = { \ + .clk = { \ + .name = #clk_name, \ + .parent = clk_parent, \ + .rate = clk_rate, \ + .div = clk_div, \ + .ops = &ref_clk_ops, \ + }, \ +} + +/* + * Reference clocks + */ + +/* Declare a list of reference clocks */ +DECLARE_REF_CLK(ref_crystal, 0, 26 * CLOCK_1M, 1); +DECLARE_REF_CLK(var_96m, 0, 96 * CLOCK_1M, 1); +DECLARE_REF_CLK(ref_96m, 0, 96 * CLOCK_1M, 1); +DECLARE_REF_CLK(ref_312m, 0, 312 * CLOCK_1M, 0); +DECLARE_REF_CLK(ref_104m, &ref_312m.clk, 104 * CLOCK_1M, 3); +DECLARE_REF_CLK(ref_52m, &ref_104m.clk, 52 * CLOCK_1M, 2); +DECLARE_REF_CLK(ref_13m, &ref_52m.clk, 13 * CLOCK_1M, 4); +DECLARE_REF_CLK(var_312m, 0, 312 * CLOCK_1M, 0); +DECLARE_REF_CLK(var_104m, &var_312m.clk, 104 * CLOCK_1M, 3); +DECLARE_REF_CLK(var_52m, &var_104m.clk, 52 * CLOCK_1M, 2); +DECLARE_REF_CLK(var_13m, &var_52m.clk, 13 * CLOCK_1M, 4); + +struct refclk_lkup { + struct refclk *procclk; + const char *name; +}; + +/* Lookup table for string to clk tranlation */ +#define MKSTR(x) {&x, #x} +static struct refclk_lkup refclk_str_tbl[] = { + MKSTR(ref_crystal), MKSTR(var_96m), MKSTR(ref_96m), + MKSTR(ref_312m), MKSTR(ref_104m), MKSTR(ref_52m), + MKSTR(ref_13m), MKSTR(var_312m), MKSTR(var_104m), + MKSTR(var_52m), MKSTR(var_13m), +}; + +int refclk_entries = sizeof(refclk_str_tbl)/sizeof(refclk_str_tbl[0]); + +/* convert ref clock string to clock structure pointer */ +struct refclk *refclk_str_to_clk(const char *name) +{ + int i; + struct refclk_lkup *tblp = refclk_str_tbl; + for (i = 0; i < refclk_entries; i++, tblp++) { + if (!(strcmp(name, tblp->name))) + return tblp->procclk; + } + return NULL; +} + +/* frequency tables indexed by freq_id */ +unsigned long master_axi_freq_tbl[8] = { + 26 * CLOCK_1M, + 52 * CLOCK_1M, + 104 * CLOCK_1M, + 156 * CLOCK_1M, + 156 * CLOCK_1M, + 208 * CLOCK_1M, + 312 * CLOCK_1M, + 312 * CLOCK_1M +}; + +unsigned long master_ahb_freq_tbl[8] = { + 26 * CLOCK_1M, + 52 * CLOCK_1M, + 52 * CLOCK_1M, + 52 * CLOCK_1M, + 78 * CLOCK_1M, + 104 * CLOCK_1M, + 104 * CLOCK_1M, + 156 * CLOCK_1M +}; + +unsigned long slave_axi_freq_tbl[8] = { + 26 * CLOCK_1M, + 52 * CLOCK_1M, + 78 * CLOCK_1M, + 104 * CLOCK_1M, + 156 * CLOCK_1M, + 156 * CLOCK_1M +}; + +unsigned long slave_apb_freq_tbl[8] = { + 26 * CLOCK_1M, + 26 * CLOCK_1M, + 39 * CLOCK_1M, + 52 * CLOCK_1M, + 52 * CLOCK_1M, + 78 * CLOCK_1M +}; + +unsigned long esub_freq_tbl[8] = { + 78 * CLOCK_1M, + 156 * CLOCK_1M, + 156 * CLOCK_1M, + 156 * CLOCK_1M, + 208 * CLOCK_1M, + 208 * CLOCK_1M, + 208 * CLOCK_1M +}; + +static struct bus_clk_data bsc1_apb_data = { + .gate = HW_SW_GATE_AUTO(0x0458, 16, 0, 1), +}; + +static struct bus_clk_data bsc2_apb_data = { + .gate = HW_SW_GATE_AUTO(0x045c, 16, 0, 1), +}; + +static struct bus_clk_data bsc3_apb_data = { + .gate = HW_SW_GATE_AUTO(0x0484, 16, 0, 1), +}; + +/* * Master CCU clocks */ +static struct peri_clk_data sdio1_data = { + .gate = HW_SW_GATE(0x0358, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_52m", + "ref_52m", + "var_96m", + "ref_96m"), + .sel = SELECTOR(0x0a28, 0, 3), + .div = DIVIDER(0x0a28, 4, 14), + .trig = TRIGGER(0x0afc, 9), +}; + +static struct peri_clk_data sdio2_data = { + .gate = HW_SW_GATE(0x035c, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_52m", + "ref_52m", + "var_96m", + "ref_96m"), + .sel = SELECTOR(0x0a2c, 0, 3), + .div = DIVIDER(0x0a2c, 4, 14), + .trig = TRIGGER(0x0afc, 10), +}; + +static struct peri_clk_data sdio3_data = { + .gate = HW_SW_GATE(0x0364, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_52m", + "ref_52m", + "var_96m", + "ref_96m"), + .sel = SELECTOR(0x0a34, 0, 3), + .div = DIVIDER(0x0a34, 4, 14), + .trig = TRIGGER(0x0afc, 12), +}; + +static struct peri_clk_data sdio4_data = { + .gate = HW_SW_GATE(0x0360, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_52m", + "ref_52m", + "var_96m", + "ref_96m"), + .sel = SELECTOR(0x0a30, 0, 3), + .div = DIVIDER(0x0a30, 4, 14), + .trig = TRIGGER(0x0afc, 11), +}; + +static struct peri_clk_data sdio1_sleep_data = { + .clocks = CLOCKS("ref_32k"), + .gate = SW_ONLY_GATE(0x0358, 20, 4), +}; + +static struct peri_clk_data sdio2_sleep_data = { + .clocks = CLOCKS("ref_32k"), + .gate = SW_ONLY_GATE(0x035c, 20, 4), +}; + +static struct peri_clk_data sdio3_sleep_data = { + .clocks = CLOCKS("ref_32k"), + .gate = SW_ONLY_GATE(0x0364, 20, 4), +}; + +static struct peri_clk_data sdio4_sleep_data = { + .clocks = CLOCKS("ref_32k"), + .gate = SW_ONLY_GATE(0x0360, 20, 4), +}; + +static struct bus_clk_data usb_otg_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1), +}; + +static struct bus_clk_data sdio1_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1), +}; + +static struct bus_clk_data sdio2_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x035c, 16, 0, 1), +}; + +static struct bus_clk_data sdio3_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x0364, 16, 0, 1), +}; + +static struct bus_clk_data sdio4_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x0360, 16, 0, 1), +}; + +/* * Slave CCU clocks */ +static struct peri_clk_data bsc1_data = { + .gate = HW_SW_GATE(0x0458, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_104m", + "ref_104m", + "var_13m", + "ref_13m"), + .sel = SELECTOR(0x0a64, 0, 3), + .trig = TRIGGER(0x0afc, 23), +}; + +static struct peri_clk_data bsc2_data = { + .gate = HW_SW_GATE(0x045c, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_104m", + "ref_104m", + "var_13m", + "ref_13m"), + .sel = SELECTOR(0x0a68, 0, 3), + .trig = TRIGGER(0x0afc, 24), +}; + +static struct peri_clk_data bsc3_data = { + .gate = HW_SW_GATE(0x0484, 18, 2, 3), + .clocks = CLOCKS("ref_crystal", + "var_104m", + "ref_104m", + "var_13m", + "ref_13m"), + .sel = SELECTOR(0x0a84, 0, 3), + .trig = TRIGGER(0x0b00, 2), +}; + +/* + * CCU clocks + */ + +static struct ccu_clock kpm_ccu_clk = { + .clk = { + .name = "kpm_ccu_clk", + .ops = &ccu_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .num_policy_masks = 1, + .policy_freq_offset = 0x00000008, + .freq_bit_shift = 8, + .policy_ctl_offset = 0x0000000c, + .policy0_mask_offset = 0x00000010, + .policy1_mask_offset = 0x00000014, + .policy2_mask_offset = 0x00000018, + .policy3_mask_offset = 0x0000001c, + .lvm_en_offset = 0x00000034, + .freq_id = 2, + .freq_tbl = master_axi_freq_tbl, +}; + +static struct ccu_clock kps_ccu_clk = { + .clk = { + .name = "kps_ccu_clk", + .ops = &ccu_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .num_policy_masks = 2, + .policy_freq_offset = 0x00000008, + .freq_bit_shift = 8, + .policy_ctl_offset = 0x0000000c, + .policy0_mask_offset = 0x00000010, + .policy1_mask_offset = 0x00000014, + .policy2_mask_offset = 0x00000018, + .policy3_mask_offset = 0x0000001c, + .policy0_mask2_offset = 0x00000048, + .policy1_mask2_offset = 0x0000004c, + .policy2_mask2_offset = 0x00000050, + .policy3_mask2_offset = 0x00000054, + .lvm_en_offset = 0x00000034, + .freq_id = 2, + .freq_tbl = slave_axi_freq_tbl, +}; + +#ifdef CONFIG_BCM_SF2_ETH +static struct ccu_clock esub_ccu_clk = { + .clk = { + .name = "esub_ccu_clk", + .ops = &ccu_clk_ops, + .ccu_clk_mgr_base = ESUB_CLK_BASE_ADDR, + }, + .num_policy_masks = 1, + .policy_freq_offset = 0x00000008, + .freq_bit_shift = 8, + .policy_ctl_offset = 0x0000000c, + .policy0_mask_offset = 0x00000010, + .policy1_mask_offset = 0x00000014, + .policy2_mask_offset = 0x00000018, + .policy3_mask_offset = 0x0000001c, + .lvm_en_offset = 0x00000034, + .freq_id = 2, + .freq_tbl = esub_freq_tbl, +}; +#endif + +/* + * Bus clocks + */ + +/* KPM bus clocks */ +static struct bus_clock usb_otg_ahb_clk = { + .clk = { + .name = "usb_otg_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &usb_otg_ahb_data, +}; + +static struct bus_clock sdio1_ahb_clk = { + .clk = { + .name = "sdio1_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &sdio1_ahb_data, +}; + +static struct bus_clock sdio2_ahb_clk = { + .clk = { + .name = "sdio2_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &sdio2_ahb_data, +}; + +static struct bus_clock sdio3_ahb_clk = { + .clk = { + .name = "sdio3_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &sdio3_ahb_data, +}; + +static struct bus_clock sdio4_ahb_clk = { + .clk = { + .name = "sdio4_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &sdio4_ahb_data, +}; + +static struct bus_clock bsc1_apb_clk = { + .clk = { + .name = "bsc1_apb_clk", + .parent = &kps_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .freq_tbl = slave_apb_freq_tbl, + .data = &bsc1_apb_data, +}; + +static struct bus_clock bsc2_apb_clk = { + .clk = { + .name = "bsc2_apb_clk", + .parent = &kps_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .freq_tbl = slave_apb_freq_tbl, + .data = &bsc2_apb_data, +}; + +static struct bus_clock bsc3_apb_clk = { + .clk = { + .name = "bsc3_apb_clk", + .parent = &kps_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .freq_tbl = slave_apb_freq_tbl, + .data = &bsc3_apb_data, +}; + +/* KPM peripheral */ +static struct peri_clock sdio1_clk = { + .clk = { + .name = "sdio1_clk", + .parent = &ref_52m.clk, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio1_data, +}; + +static struct peri_clock sdio2_clk = { + .clk = { + .name = "sdio2_clk", + .parent = &ref_52m.clk, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio2_data, +}; + +static struct peri_clock sdio3_clk = { + .clk = { + .name = "sdio3_clk", + .parent = &ref_52m.clk, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio3_data, +}; + +static struct peri_clock sdio4_clk = { + .clk = { + .name = "sdio4_clk", + .parent = &ref_52m.clk, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio4_data, +}; + +static struct peri_clock sdio1_sleep_clk = { + .clk = { + .name = "sdio1_sleep_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio1_sleep_data, +}; + +static struct peri_clock sdio2_sleep_clk = { + .clk = { + .name = "sdio2_sleep_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio2_sleep_data, +}; + +static struct peri_clock sdio3_sleep_clk = { + .clk = { + .name = "sdio3_sleep_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio3_sleep_data, +}; + +static struct peri_clock sdio4_sleep_clk = { + .clk = { + .name = "sdio4_sleep_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .data = &sdio4_sleep_data, +}; + +/* KPS peripheral clock */ +static struct peri_clock bsc1_clk = { + .clk = { + .name = "bsc1_clk", + .parent = &ref_13m.clk, + .rate = 13 * CLOCK_1M, + .div = 1, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .data = &bsc1_data, +}; + +static struct peri_clock bsc2_clk = { + .clk = { + .name = "bsc2_clk", + .parent = &ref_13m.clk, + .rate = 13 * CLOCK_1M, + .div = 1, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .data = &bsc2_data, +}; + +static struct peri_clock bsc3_clk = { + .clk = { + .name = "bsc3_clk", + .parent = &ref_13m.clk, + .rate = 13 * CLOCK_1M, + .div = 1, + .ops = &peri_clk_ops, + .ccu_clk_mgr_base = KONA_SLV_CLK_BASE_ADDR, + }, + .data = &bsc3_data, +}; + +/* public table for registering clocks */ +struct clk_lookup arch_clk_tbl[] = { + /* Peripheral clocks */ + CLK_LK(sdio1), + CLK_LK(sdio2), + CLK_LK(sdio3), + CLK_LK(sdio4), + CLK_LK(sdio1_sleep), + CLK_LK(sdio2_sleep), + CLK_LK(sdio3_sleep), + CLK_LK(sdio4_sleep), + CLK_LK(bsc1), + CLK_LK(bsc2), + CLK_LK(bsc3), + /* Bus clocks */ + CLK_LK(usb_otg_ahb), + CLK_LK(sdio1_ahb), + CLK_LK(sdio2_ahb), + CLK_LK(sdio3_ahb), + CLK_LK(sdio4_ahb), + CLK_LK(bsc1_apb), + CLK_LK(bsc2_apb), + CLK_LK(bsc3_apb), +#ifdef CONFIG_BCM_SF2_ETH + CLK_LK(esub_ccu), +#endif +}; + +/* public array size */ +unsigned int arch_clk_tbl_array_size = ARRAY_SIZE(arch_clk_tbl);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c new file mode 100644 index 0000000..ba55d0a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-bsc.c
@@ -0,0 +1,52 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include <asm/kona-common/clk.h> +#include "clk-core.h" + +/* Enable appropriate clocks for a BSC/I2C port */ +int clk_bsc_enable(void *base) +{ + int ret; + char *bscstr, *apbstr; + + switch ((u32) base) { + case PMU_BSC_BASE_ADDR: + /* PMU clock is always enabled */ + return 0; + case BSC1_BASE_ADDR: + bscstr = "bsc1_clk"; + apbstr = "bsc1_apb_clk"; + break; + case BSC2_BASE_ADDR: + bscstr = "bsc2_clk"; + apbstr = "bsc2_apb_clk"; + break; + case BSC3_BASE_ADDR: + bscstr = "bsc3_clk"; + apbstr = "bsc3_apb_clk"; + break; + default: + printf("%s: base 0x%p not found\n", __func__, base); + return -EINVAL; + } + + /* Note that the bus clock must be enabled first */ + + ret = clk_get_and_enable(apbstr); + if (ret) + return ret; + + ret = clk_get_and_enable(bscstr); + if (ret) + return ret; + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.c new file mode 100644 index 0000000..d442583 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.c
@@ -0,0 +1,513 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * + * bcm281xx architecture clock framework + * + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <bitfield.h> +#include <asm/arch/sysmap.h> +#include <asm/kona-common/clk.h> +#include "clk-core.h" + +#define CLK_WR_ACCESS_PASSWORD 0x00a5a501 +#define WR_ACCESS_OFFSET 0 /* common to all clock blocks */ +#define POLICY_CTL_GO 1 /* Load and refresh policy masks */ +#define POLICY_CTL_GO_ATL 4 /* Active Load */ + +/* Helper function */ +int clk_get_and_enable(char *clkstr) +{ + int ret = 0; + struct clk *c; + + debug("%s: %s\n", __func__, clkstr); + + c = clk_get(clkstr); + if (c) { + ret = clk_enable(c); + if (ret) + return ret; + } else { + printf("%s: Couldn't find %s\n", __func__, clkstr); + return -EINVAL; + } + return ret; +} + +/* + * Poll a register in a CCU's address space, returning when the + * specified bit in that register's value is set (or clear). Delay + * a microsecond after each read of the register. Returns true if + * successful, or false if we gave up trying. + * + * Caller must ensure the CCU lock is held. + */ +#define CLK_GATE_DELAY_USEC 2000 +static inline int wait_bit(void *base, u32 offset, u32 bit, bool want) +{ + unsigned int tries; + u32 bit_mask = 1 << bit; + + for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) { + u32 val; + bool bit_val; + + val = readl(base + offset); + bit_val = (val & bit_mask) ? 1 : 0; + if (bit_val == want) + return 0; /* success */ + udelay(1); + } + + debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n", + __func__, base + offset, bit, want); + + return -ETIMEDOUT; +} + +/* Enable a peripheral clock */ +static int peri_clk_enable(struct clk *c, int enable) +{ + int ret = 0; + u32 reg; + struct peri_clock *peri_clk = to_peri_clk(c); + struct peri_clk_data *cd = peri_clk->data; + struct bcm_clk_gate *gate = &cd->gate; + void *base = (void *)c->ccu_clk_mgr_base; + + + debug("%s: %s\n", __func__, c->name); + + clk_get_rate(c); /* Make sure rate and sel are filled in */ + + /* enable access */ + writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET); + + if (enable) { + debug("%s %s set rate %lu div %lu sel %d parent %lu\n", + __func__, c->name, c->rate, c->div, c->sel, + c->parent->rate); + + /* + * clkgate - only software controllable gates are + * supported by u-boot which includes all clocks + * that matter. This avoids bringing in a lot of extra + * complexity as done in the kernel framework. + */ + if (gate_exists(gate)) { + reg = readl(base + cd->gate.offset); + reg |= (1 << cd->gate.en_bit); + writel(reg, base + cd->gate.offset); + } + + /* div and pll select */ + if (divider_exists(&cd->div)) { + reg = readl(base + cd->div.offset); + bitfield_replace(reg, cd->div.shift, cd->div.width, + c->div - 1); + writel(reg, base + cd->div.offset); + } + + /* frequency selector */ + if (selector_exists(&cd->sel)) { + reg = readl(base + cd->sel.offset); + bitfield_replace(reg, cd->sel.shift, cd->sel.width, + c->sel); + writel(reg, base + cd->sel.offset); + } + + /* trigger */ + if (trigger_exists(&cd->trig)) { + writel((1 << cd->trig.bit), base + cd->trig.offset); + + /* wait for trigger status bit to go to 0 */ + ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0); + if (ret) + return ret; + } + + /* wait for running (status_bit = 1) */ + ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1); + if (ret) + return ret; + } else { + debug("%s disable clock %s\n", __func__, c->name); + + /* clkgate */ + reg = readl(base + cd->gate.offset); + reg &= ~(1 << cd->gate.en_bit); + writel(reg, base + cd->gate.offset); + + /* wait for stop (status_bit = 0) */ + ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0); + } + + /* disable access */ + writel(0, base + WR_ACCESS_OFFSET); + + return ret; +} + +/* Set the rate of a peripheral clock */ +static int peri_clk_set_rate(struct clk *c, unsigned long rate) +{ + int ret = 0; + int i; + unsigned long diff; + unsigned long new_rate = 0, div = 1; + struct peri_clock *peri_clk = to_peri_clk(c); + struct peri_clk_data *cd = peri_clk->data; + const char **clock; + + debug("%s: %s\n", __func__, c->name); + diff = rate; + + i = 0; + for (clock = cd->clocks; *clock; clock++, i++) { + struct refclk *ref = refclk_str_to_clk(*clock); + if (!ref) { + printf("%s: Lookup of %s failed\n", __func__, *clock); + return -EINVAL; + } + + /* round to the new rate */ + div = ref->clk.rate / rate; + if (div == 0) + div = 1; + + new_rate = ref->clk.rate / div; + + /* get the min diff */ + if (abs(new_rate - rate) < diff) { + diff = abs(new_rate - rate); + c->sel = i; + c->parent = &ref->clk; + c->rate = new_rate; + c->div = div; + } + } + + debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__, + c->name, c->rate, c->div, c->sel, c->parent->rate); + return ret; +} + +/* Get the rate of a peripheral clock */ +static unsigned long peri_clk_get_rate(struct clk *c) +{ + struct peri_clock *peri_clk = to_peri_clk(c); + struct peri_clk_data *cd = peri_clk->data; + void *base = (void *)c->ccu_clk_mgr_base; + int div = 1; + const char **clock; + struct refclk *ref; + u32 reg; + + debug("%s: %s\n", __func__, c->name); + if (selector_exists(&cd->sel)) { + reg = readl(base + cd->sel.offset); + c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width); + } else { + /* + * For peri clocks that don't have a selector, the single + * reference clock will always exist at index 0. + */ + c->sel = 0; + } + + if (divider_exists(&cd->div)) { + reg = readl(base + cd->div.offset); + div = bitfield_extract(reg, cd->div.shift, cd->div.width); + div += 1; + } + + clock = cd->clocks; + ref = refclk_str_to_clk(clock[c->sel]); + if (!ref) { + printf("%s: Can't lookup %s\n", __func__, clock[c->sel]); + return 0; + } + + c->parent = &ref->clk; + c->div = div; + c->rate = c->parent->rate / c->div; + debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__, + c->parent->rate, div, c->sel, c->rate); + + return c->rate; +} + +/* Peripheral clock operations */ +struct clk_ops peri_clk_ops = { + .enable = peri_clk_enable, + .set_rate = peri_clk_set_rate, + .get_rate = peri_clk_get_rate, +}; + +/* Enable a CCU clock */ +static int ccu_clk_enable(struct clk *c, int enable) +{ + struct ccu_clock *ccu_clk = to_ccu_clk(c); + void *base = (void *)c->ccu_clk_mgr_base; + int ret = 0; + u32 reg; + + debug("%s: %s\n", __func__, c->name); + if (!enable) + return -EINVAL; /* CCU clock cannot shutdown */ + + /* enable access */ + writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET); + + /* config enable for policy engine */ + writel(1, base + ccu_clk->lvm_en_offset); + + /* wait for bit to go to 0 */ + ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0); + if (ret) + return ret; + + /* freq ID */ + if (!ccu_clk->freq_bit_shift) + ccu_clk->freq_bit_shift = 8; + + /* Set frequency id for each of the 4 policies */ + reg = ccu_clk->freq_id | + (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) | + (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) | + (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3)); + writel(reg, base + ccu_clk->policy_freq_offset); + + /* enable all clock mask */ + writel(0x7fffffff, base + ccu_clk->policy0_mask_offset); + writel(0x7fffffff, base + ccu_clk->policy1_mask_offset); + writel(0x7fffffff, base + ccu_clk->policy2_mask_offset); + writel(0x7fffffff, base + ccu_clk->policy3_mask_offset); + + if (ccu_clk->num_policy_masks == 2) { + writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset); + writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset); + writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset); + writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset); + } + + /* start policy engine */ + reg = readl(base + ccu_clk->policy_ctl_offset); + reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL); + writel(reg, base + ccu_clk->policy_ctl_offset); + + /* wait till started */ + ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0); + if (ret) + return ret; + + /* disable access */ + writel(0, base + WR_ACCESS_OFFSET); + + return ret; +} + +/* Get the CCU clock rate */ +static unsigned long ccu_clk_get_rate(struct clk *c) +{ + struct ccu_clock *ccu_clk = to_ccu_clk(c); + debug("%s: %s\n", __func__, c->name); + c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id]; + return c->rate; +} + +/* CCU clock operations */ +struct clk_ops ccu_clk_ops = { + .enable = ccu_clk_enable, + .get_rate = ccu_clk_get_rate, +}; + +/* Enable a bus clock */ +static int bus_clk_enable(struct clk *c, int enable) +{ + struct bus_clock *bus_clk = to_bus_clk(c); + struct bus_clk_data *cd = bus_clk->data; + void *base = (void *)c->ccu_clk_mgr_base; + int ret = 0; + u32 reg; + + debug("%s: %s\n", __func__, c->name); + /* enable access */ + writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET); + + /* enable gating */ + reg = readl(base + cd->gate.offset); + if (!!(reg & (1 << cd->gate.status_bit)) == !!enable) + debug("%s already %s\n", c->name, + enable ? "enabled" : "disabled"); + else { + int want = (enable) ? 1 : 0; + reg |= (1 << cd->gate.hw_sw_sel_bit); + + if (enable) + reg |= (1 << cd->gate.en_bit); + else + reg &= ~(1 << cd->gate.en_bit); + + writel(reg, base + cd->gate.offset); + ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, + want); + if (ret) + return ret; + } + + /* disable access */ + writel(0, base + WR_ACCESS_OFFSET); + + return ret; +} + +/* Get the rate of a bus clock */ +static unsigned long bus_clk_get_rate(struct clk *c) +{ + struct bus_clock *bus_clk = to_bus_clk(c); + struct ccu_clock *ccu_clk; + + debug("%s: %s\n", __func__, c->name); + ccu_clk = to_ccu_clk(c->parent); + + c->rate = bus_clk->freq_tbl[ccu_clk->freq_id]; + c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate; + return c->rate; +} + +/* Bus clock operations */ +struct clk_ops bus_clk_ops = { + .enable = bus_clk_enable, + .get_rate = bus_clk_get_rate, +}; + +/* Enable a reference clock */ +static int ref_clk_enable(struct clk *c, int enable) +{ + debug("%s: %s\n", __func__, c->name); + return 0; +} + +/* Reference clock operations */ +struct clk_ops ref_clk_ops = { + .enable = ref_clk_enable, +}; + +/* + * clk.h implementation follows + */ + +/* Initialize the clock framework */ +int clk_init(void) +{ + debug("%s:\n", __func__); + return 0; +} + +/* Get a clock handle, give a name string */ +struct clk *clk_get(const char *con_id) +{ + int i; + struct clk_lookup *clk_tblp; + + debug("%s: %s\n", __func__, con_id); + + clk_tblp = arch_clk_tbl; + for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) { + if (clk_tblp->con_id) { + if (!con_id || strcmp(clk_tblp->con_id, con_id)) + continue; + return clk_tblp->clk; + } + } + return NULL; +} + +/* Enable a clock */ +int clk_enable(struct clk *c) +{ + int ret = 0; + + debug("%s: %s\n", __func__, c->name); + if (!c->ops || !c->ops->enable) + return -1; + + /* enable parent clock first */ + if (c->parent) + ret = clk_enable(c->parent); + + if (ret) + return ret; + + if (!c->use_cnt) { + c->use_cnt++; + ret = c->ops->enable(c, 1); + } + + return ret; +} + +/* Disable a clock */ +void clk_disable(struct clk *c) +{ + debug("%s: %s\n", __func__, c->name); + if (!c->ops || !c->ops->enable) + return; + + if (c->use_cnt) { + c->use_cnt--; + c->ops->enable(c, 0); + } + + /* disable parent */ + if (c->parent) + clk_disable(c->parent); +} + +/* Get the clock rate */ +unsigned long clk_get_rate(struct clk *c) +{ + unsigned long rate; + + debug("%s: %s\n", __func__, c->name); + if (!c || !c->ops || !c->ops->get_rate) + return 0; + + rate = c->ops->get_rate(c); + debug("%s: rate = %ld\n", __func__, rate); + return rate; +} + +/* Set the clock rate */ +int clk_set_rate(struct clk *c, unsigned long rate) +{ + int ret; + + debug("%s: %s rate=%ld\n", __func__, c->name, rate); + if (!c || !c->ops || !c->ops->set_rate) + return -EINVAL; + + if (c->use_cnt) + return -EINVAL; + + ret = c->ops->set_rate(c, rate); + + return ret; +} + +/* Not required for this arch */ +/* +long clk_round_rate(struct clk *clk, unsigned long rate); +int clk_set_parent(struct clk *clk, struct clk *parent); +struct clk *clk_get_parent(struct clk *clk); +*/
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.h b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.h new file mode 100644 index 0000000..4a694d7 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-core.h
@@ -0,0 +1,491 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/stddef.h> + +#ifdef CONFIG_CLK_DEBUG +#undef writel +#undef readl +static inline void writel(u32 val, void *addr) +{ + printf("Write [0x%p] = 0x%08x\n", addr, val); + *(u32 *)addr = val; +} + +static inline u32 readl(void *addr) +{ + u32 val = *(u32 *)addr; + printf("Read [0x%p] = 0x%08x\n", addr, val); + return val; +} +#endif + +struct clk; + +struct clk_lookup { + const char *dev_id; + const char *con_id; + struct clk *clk; +}; + +extern struct clk_lookup arch_clk_tbl[]; +extern unsigned int arch_clk_tbl_array_size; + +/** + * struct clk_ops - standard clock operations + * @enable: enable/disable clock, see clk_enable() and clk_disable() + * @set_rate: set the clock rate, see clk_set_rate(). + * @get_rate: get the clock rate, see clk_get_rate(). + * @round_rate: round a given clock rate, see clk_round_rate(). + * @set_parent: set the clock's parent, see clk_set_parent(). + * + * Group the common clock implementations together so that we + * don't have to keep setting the same fiels again. We leave + * enable in struct clk. + * + */ +struct clk_ops { + int (*enable) (struct clk *c, int enable); + int (*set_rate) (struct clk *c, unsigned long rate); + unsigned long (*get_rate) (struct clk *c); + unsigned long (*round_rate) (struct clk *c, unsigned long rate); + int (*set_parent) (struct clk *c, struct clk *parent); +}; + +struct clk { + struct clk *parent; + const char *name; + int use_cnt; + unsigned long rate; /* in HZ */ + + /* programmable divider. 0 means fixed ratio to parent clock */ + unsigned long div; + + struct clk_src *src; + struct clk_ops *ops; + + unsigned long ccu_clk_mgr_base; + int sel; +}; + +struct refclk *refclk_str_to_clk(const char *name); + +/* The common clock framework uses u8 to represent a parent index */ +#define PARENT_COUNT_MAX ((u32)U8_MAX) + +#define BAD_CLK_INDEX U8_MAX /* Can't ever be valid */ +#define BAD_CLK_NAME ((const char *)-1) + +#define BAD_SCALED_DIV_VALUE U64_MAX + +/* + * Utility macros for object flag management. If possible, flags + * should be defined such that 0 is the desired default value. + */ +#define FLAG(type, flag) BCM_CLK_ ## type ## _FLAGS_ ## flag +#define FLAG_SET(obj, type, flag) ((obj)->flags |= FLAG(type, flag)) +#define FLAG_CLEAR(obj, type, flag) ((obj)->flags &= ~(FLAG(type, flag))) +#define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) +#define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) + +/* Clock field state tests */ + +#define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) +#define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) +#define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW) +#define gate_is_sw_controllable(gate) FLAG_TEST(gate, GATE, SW) +#define gate_is_sw_managed(gate) FLAG_TEST(gate, GATE, SW_MANAGED) +#define gate_is_no_disable(gate) FLAG_TEST(gate, GATE, NO_DISABLE) + +#define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) + +#define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) +#define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) +#define divider_has_fraction(div) (!divider_is_fixed(div) && \ + (div)->frac_width > 0) + +#define selector_exists(sel) ((sel)->width != 0) +#define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) + +/* Clock type, used to tell common block what it's part of */ +enum bcm_clk_type { + bcm_clk_none, /* undefined clock type */ + bcm_clk_bus, + bcm_clk_core, + bcm_clk_peri +}; + +/* + * Gating control and status is managed by a 32-bit gate register. + * + * There are several types of gating available: + * - (no gate) + * A clock with no gate is assumed to be always enabled. + * - hardware-only gating (auto-gating) + * Enabling or disabling clocks with this type of gate is + * managed automatically by the hardware. Such clocks can be + * considered by the software to be enabled. The current status + * of auto-gated clocks can be read from the gate status bit. + * - software-only gating + * Auto-gating is not available for this type of clock. + * Instead, software manages whether it's enabled by setting or + * clearing the enable bit. The current gate status of a gate + * under software control can be read from the gate status bit. + * To ensure a change to the gating status is complete, the + * status bit can be polled to verify that the gate has entered + * the desired state. + * - selectable hardware or software gating + * Gating for this type of clock can be configured to be either + * under software or hardware control. Which type is in use is + * determined by the hw_sw_sel bit of the gate register. + */ +struct bcm_clk_gate { + u32 offset; /* gate register offset */ + u32 status_bit; /* 0: gate is disabled; 0: gatge is enabled */ + u32 en_bit; /* 0: disable; 1: enable */ + u32 hw_sw_sel_bit; /* 0: hardware gating; 1: software gating */ + u32 flags; /* BCM_CLK_GATE_FLAGS_* below */ +}; + +/* + * Gate flags: + * HW means this gate can be auto-gated + * SW means the state of this gate can be software controlled + * NO_DISABLE means this gate is (only) enabled if under software control + * SW_MANAGED means the status of this gate is under software control + * ENABLED means this software-managed gate is *supposed* to be enabled + */ +#define BCM_CLK_GATE_FLAGS_EXISTS ((u32)1 << 0) /* Gate is valid */ +#define BCM_CLK_GATE_FLAGS_HW ((u32)1 << 1) /* Can auto-gate */ +#define BCM_CLK_GATE_FLAGS_SW ((u32)1 << 2) /* Software control */ +#define BCM_CLK_GATE_FLAGS_NO_DISABLE ((u32)1 << 3) /* HW or enabled */ +#define BCM_CLK_GATE_FLAGS_SW_MANAGED ((u32)1 << 4) /* SW now in control */ +#define BCM_CLK_GATE_FLAGS_ENABLED ((u32)1 << 5) /* If SW_MANAGED */ + +/* + * Gate initialization macros. + * + * Any gate initially under software control will be enabled. + */ + +/* A hardware/software gate initially under software control */ +#define HW_SW_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ + { \ + .offset = (_offset), \ + .status_bit = (_status_bit), \ + .en_bit = (_en_bit), \ + .hw_sw_sel_bit = (_hw_sw_sel_bit), \ + .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ + FLAG(GATE, SW_MANAGED)|FLAG(GATE, ENABLED)| \ + FLAG(GATE, EXISTS), \ + } + +/* A hardware/software gate initially under hardware control */ +#define HW_SW_GATE_AUTO(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ + { \ + .offset = (_offset), \ + .status_bit = (_status_bit), \ + .en_bit = (_en_bit), \ + .hw_sw_sel_bit = (_hw_sw_sel_bit), \ + .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ + FLAG(GATE, EXISTS), \ + } + +/* A hardware-or-enabled gate (enabled if not under hardware control) */ +#define HW_ENABLE_GATE(_offset, _status_bit, _en_bit, _hw_sw_sel_bit) \ + { \ + .offset = (_offset), \ + .status_bit = (_status_bit), \ + .en_bit = (_en_bit), \ + .hw_sw_sel_bit = (_hw_sw_sel_bit), \ + .flags = FLAG(GATE, HW)|FLAG(GATE, SW)| \ + FLAG(GATE, NO_DISABLE)|FLAG(GATE, EXISTS), \ + } + +/* A software-only gate */ +#define SW_ONLY_GATE(_offset, _status_bit, _en_bit) \ + { \ + .offset = (_offset), \ + .status_bit = (_status_bit), \ + .en_bit = (_en_bit), \ + .flags = FLAG(GATE, SW)|FLAG(GATE, SW_MANAGED)| \ + FLAG(GATE, ENABLED)|FLAG(GATE, EXISTS), \ + } + +/* A hardware-only gate */ +#define HW_ONLY_GATE(_offset, _status_bit) \ + { \ + .offset = (_offset), \ + .status_bit = (_status_bit), \ + .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ + } + +/* + * Each clock can have zero, one, or two dividers which change the + * output rate of the clock. Each divider can be either fixed or + * variable. If there are two dividers, they are the "pre-divider" + * and the "regular" or "downstream" divider. If there is only one, + * there is no pre-divider. + * + * A fixed divider is any non-zero (positive) value, and it + * indicates how the input rate is affected by the divider. + * + * The value of a variable divider is maintained in a sub-field of a + * 32-bit divider register. The position of the field in the + * register is defined by its offset and width. The value recorded + * in this field is always 1 less than the value it represents. + * + * In addition, a variable divider can indicate that some subset + * of its bits represent a "fractional" part of the divider. Such + * bits comprise the low-order portion of the divider field, and can + * be viewed as representing the portion of the divider that lies to + * the right of the decimal point. Most variable dividers have zero + * fractional bits. Variable dividers with non-zero fraction width + * still record a value 1 less than the value they represent; the + * added 1 does *not* affect the low-order bit in this case, it + * affects the bits above the fractional part only. (Often in this + * code a divider field value is distinguished from the value it + * represents by referring to the latter as a "divisor".) + * + * In order to avoid dealing with fractions, divider arithmetic is + * performed using "scaled" values. A scaled value is one that's + * been left-shifted by the fractional width of a divider. Dividing + * a scaled value by a scaled divisor produces the desired quotient + * without loss of precision and without any other special handling + * for fractions. + * + * The recorded value of a variable divider can be modified. To + * modify either divider (or both), a clock must be enabled (i.e., + * using its gate). In addition, a trigger register (described + * below) must be used to commit the change, and polled to verify + * the change is complete. + */ +struct bcm_clk_div { + union { + struct { /* variable divider */ + u32 offset; /* divider register offset */ + u32 shift; /* field shift */ + u32 width; /* field width */ + u32 frac_width; /* field fraction width */ + + u64 scaled_div; /* scaled divider value */ + }; + u32 fixed; /* non-zero fixed divider value */ + }; + u32 flags; /* BCM_CLK_DIV_FLAGS_* below */ +}; + +/* + * Divider flags: + * EXISTS means this divider exists + * FIXED means it is a fixed-rate divider + */ +#define BCM_CLK_DIV_FLAGS_EXISTS ((u32)1 << 0) /* Divider is valid */ +#define BCM_CLK_DIV_FLAGS_FIXED ((u32)1 << 1) /* Fixed-value */ + +/* Divider initialization macros */ + +/* A fixed (non-zero) divider */ +#define FIXED_DIVIDER(_value) \ + { \ + .fixed = (_value), \ + .flags = FLAG(DIV, EXISTS)|FLAG(DIV, FIXED), \ + } + +/* A divider with an integral divisor */ +#define DIVIDER(_offset, _shift, _width) \ + { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .scaled_div = BAD_SCALED_DIV_VALUE, \ + .flags = FLAG(DIV, EXISTS), \ + } + +/* A divider whose divisor has an integer and fractional part */ +#define FRAC_DIVIDER(_offset, _shift, _width, _frac_width) \ + { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .frac_width = (_frac_width), \ + .scaled_div = BAD_SCALED_DIV_VALUE, \ + .flags = FLAG(DIV, EXISTS), \ + } + +/* + * Clocks may have multiple "parent" clocks. If there is more than + * one, a selector must be specified to define which of the parent + * clocks is currently in use. The selected clock is indicated in a + * sub-field of a 32-bit selector register. The range of + * representable selector values typically exceeds the number of + * available parent clocks. Occasionally the reset value of a + * selector field is explicitly set to a (specific) value that does + * not correspond to a defined input clock. + * + * We register all known parent clocks with the common clock code + * using a packed array (i.e., no empty slots) of (parent) clock + * names, and refer to them later using indexes into that array. + * We maintain an array of selector values indexed by common clock + * index values in order to map between these common clock indexes + * and the selector values used by the hardware. + * + * Like dividers, a selector can be modified, but to do so a clock + * must be enabled, and a trigger must be used to commit the change. + */ +struct bcm_clk_sel { + u32 offset; /* selector register offset */ + u32 shift; /* field shift */ + u32 width; /* field width */ + + u32 parent_count; /* number of entries in parent_sel[] */ + u32 *parent_sel; /* array of parent selector values */ + u8 clk_index; /* current selected index in parent_sel[] */ +}; + +/* Selector initialization macro */ +#define SELECTOR(_offset, _shift, _width) \ + { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .clk_index = BAD_CLK_INDEX, \ + } + +/* + * Making changes to a variable divider or a selector for a clock + * requires the use of a trigger. A trigger is defined by a single + * bit within a register. To signal a change, a 1 is written into + * that bit. To determine when the change has been completed, that + * trigger bit is polled; the read value will be 1 while the change + * is in progress, and 0 when it is complete. + * + * Occasionally a clock will have more than one trigger. In this + * case, the "pre-trigger" will be used when changing a clock's + * selector and/or its pre-divider. + */ +struct bcm_clk_trig { + u32 offset; /* trigger register offset */ + u32 bit; /* trigger bit */ + u32 flags; /* BCM_CLK_TRIG_FLAGS_* below */ +}; + +/* + * Trigger flags: + * EXISTS means this trigger exists + */ +#define BCM_CLK_TRIG_FLAGS_EXISTS ((u32)1 << 0) /* Trigger is valid */ + +/* Trigger initialization macro */ +#define TRIGGER(_offset, _bit) \ + { \ + .offset = (_offset), \ + .bit = (_bit), \ + .flags = FLAG(TRIG, EXISTS), \ + } + +struct bus_clk_data { + struct bcm_clk_gate gate; +}; + +struct core_clk_data { + struct bcm_clk_gate gate; +}; + +struct peri_clk_data { + struct bcm_clk_gate gate; + struct bcm_clk_trig pre_trig; + struct bcm_clk_div pre_div; + struct bcm_clk_trig trig; + struct bcm_clk_div div; + struct bcm_clk_sel sel; + const char *clocks[]; /* must be last; use CLOCKS() to declare */ +}; +#define CLOCKS(...) { __VA_ARGS__, NULL, } +#define NO_CLOCKS { NULL, } /* Must use of no parent clocks */ + +struct refclk { + struct clk clk; +}; + +struct peri_clock { + struct clk clk; + struct peri_clk_data *data; +}; + +struct ccu_clock { + struct clk clk; + + int num_policy_masks; + unsigned long policy_freq_offset; + int freq_bit_shift; /* 8 for most CCUs */ + unsigned long policy_ctl_offset; + unsigned long policy0_mask_offset; + unsigned long policy1_mask_offset; + unsigned long policy2_mask_offset; + unsigned long policy3_mask_offset; + unsigned long policy0_mask2_offset; + unsigned long policy1_mask2_offset; + unsigned long policy2_mask2_offset; + unsigned long policy3_mask2_offset; + unsigned long lvm_en_offset; + + int freq_id; + unsigned long *freq_tbl; +}; + +struct bus_clock { + struct clk clk; + struct bus_clk_data *data; + unsigned long *freq_tbl; +}; + +struct ref_clock { + struct clk clk; +}; + +static inline int is_same_clock(struct clk *a, struct clk *b) +{ + return (a == b); +} + +#define to_clk(p) (&((p)->clk)) +#define name_to_clk(name) (&((name##_clk).clk)) +/* declare a struct clk_lookup */ +#define CLK_LK(name) \ +{.con_id = __stringify(name##_clk), .clk = name_to_clk(name),} + +static inline struct refclk *to_refclk(struct clk *clock) +{ + return container_of(clock, struct refclk, clk); +} + +static inline struct peri_clock *to_peri_clk(struct clk *clock) +{ + return container_of(clock, struct peri_clock, clk); +} + +static inline struct ccu_clock *to_ccu_clk(struct clk *clock) +{ + return container_of(clock, struct ccu_clock, clk); +} + +static inline struct bus_clock *to_bus_clk(struct clk *clock) +{ + return container_of(clock, struct bus_clock, clk); +} + +static inline struct ref_clock *to_ref_clk(struct clk *clock) +{ + return container_of(clock, struct ref_clock, clk); +} + +extern struct clk_ops peri_clk_ops; +extern struct clk_ops ccu_clk_ops; +extern struct clk_ops bus_clk_ops; +extern struct clk_ops ref_clk_ops; + +extern int clk_get_and_enable(char *clkstr);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-eth.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-eth.c new file mode 100644 index 0000000..b0b92b9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-eth.c
@@ -0,0 +1,143 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include <asm/kona-common/clk.h> +#include "clk-core.h" + +#define WR_ACCESS_ADDR ESUB_CLK_BASE_ADDR +#define WR_ACCESS_PASSWORD 0xA5A500 + +#define PLLE_POST_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C00) + +#define PLLE_RESETB_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C58) +#define PLLE_RESETB_I_PLL_RESETB_PLLE_MASK 0x00010000 +#define PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK 0x00000001 + +#define PLL_LOCK_ADDR (ESUB_CLK_BASE_ADDR + 0x00000C38) +#define PLL_LOCK_PLL_LOCK_PLLE_MASK 0x00000001 + +#define ESW_SYS_DIV_ADDR (ESUB_CLK_BASE_ADDR + 0x00000A04) +#define ESW_SYS_DIV_PLL_SELECT_MASK 0x00000300 +#define ESW_SYS_DIV_DIV_MASK 0x0000001C +#define ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT 0x00000100 +#define ESW_SYS_DIV_DIV_SELECT 0x4 +#define ESW_SYS_DIV_TRIGGER_MASK 0x00000001 + +#define ESUB_AXI_DIV_DEBUG_ADDR (ESUB_CLK_BASE_ADDR + 0x00000E04) +#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK 0x0000001C +#define ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK 0x00000040 +#define ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT 0x0 +#define ESUB_AXI_DIV_DEBUG_TRIGGER_MASK 0x00000001 + +#define PLL_MAX_RETRY 100 + +/* Enable appropriate clocks for Ethernet */ +int clk_eth_enable(void) +{ + int rc = -1; + int retry_count = 0; + rc = clk_get_and_enable("esub_ccu_clk"); + + /* Enable Access to CCU registers */ + writel((1 | WR_ACCESS_PASSWORD), WR_ACCESS_ADDR); + + writel(readl(PLLE_POST_RESETB_ADDR) & + ~PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK, + PLLE_POST_RESETB_ADDR); + + /* Take PLL out of reset and put into normal mode */ + writel(readl(PLLE_RESETB_ADDR) | PLLE_RESETB_I_PLL_RESETB_PLLE_MASK, + PLLE_RESETB_ADDR); + + /* Wait for PLL lock */ + rc = -1; + while (retry_count < PLL_MAX_RETRY) { + udelay(100); + if (readl(PLL_LOCK_ADDR) & PLL_LOCK_PLL_LOCK_PLLE_MASK) { + rc = 0; + break; + } + retry_count++; + } + + if (rc == -1) { + printf("%s: ETH-PLL lock timeout, Ethernet is not enabled!\n", + __func__); + return -1; + } + + writel(readl(PLLE_POST_RESETB_ADDR) | + PLLE_POST_RESETB_I_POST_RESETB_PLLE_MASK, + PLLE_POST_RESETB_ADDR); + + /* Switch esw_sys_clk to use 104MHz(208MHz/2) clock */ + writel((readl(ESW_SYS_DIV_ADDR) & + ~(ESW_SYS_DIV_PLL_SELECT_MASK | ESW_SYS_DIV_DIV_MASK)) | + ESW_SYS_DIV_PLL_VAR_208M_CLK_SELECT | ESW_SYS_DIV_DIV_SELECT, + ESW_SYS_DIV_ADDR); + + writel(readl(ESW_SYS_DIV_ADDR) | ESW_SYS_DIV_TRIGGER_MASK, + ESW_SYS_DIV_ADDR); + + /* Wait for trigger complete */ + rc = -1; + retry_count = 0; + while (retry_count < PLL_MAX_RETRY) { + udelay(100); + if (!(readl(ESW_SYS_DIV_ADDR) & ESW_SYS_DIV_TRIGGER_MASK)) { + rc = 0; + break; + } + retry_count++; + } + + if (rc == -1) { + printf("%s: SYS CLK Trigger timeout, Ethernet is not enabled!\n", + __func__); + return -1; + } + + /* switch Esub AXI clock to 208MHz */ + writel((readl(ESUB_AXI_DIV_DEBUG_ADDR) & + ~(ESUB_AXI_DIV_DEBUG_PLL_SELECT_MASK | + ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK | + ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) | + ESUB_AXI_DIV_DEBUG_PLL_VAR_208M_CLK_SELECT | + ESUB_AXI_DIV_DEBUG_PLL_SELECT_OVERRIDE_MASK, + ESUB_AXI_DIV_DEBUG_ADDR); + + writel(readl(ESUB_AXI_DIV_DEBUG_ADDR) | + ESUB_AXI_DIV_DEBUG_TRIGGER_MASK, + ESUB_AXI_DIV_DEBUG_ADDR); + + /* Wait for trigger complete */ + rc = -1; + retry_count = 0; + while (retry_count < PLL_MAX_RETRY) { + udelay(100); + if (!(readl(ESUB_AXI_DIV_DEBUG_ADDR) & + ESUB_AXI_DIV_DEBUG_TRIGGER_MASK)) { + rc = 0; + break; + } + retry_count++; + } + + if (rc == -1) { + printf("%s: AXI CLK Trigger timeout, Ethernet is not enabled!\n", + __func__); + return -1; + } + + /* Disable Access to CCU registers */ + writel(WR_ACCESS_PASSWORD, WR_ACCESS_ADDR); + + return rc; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c new file mode 100644 index 0000000..49badcb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-sdio.c
@@ -0,0 +1,73 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include <asm/kona-common/clk.h> +#include "clk-core.h" + +/* Enable appropriate clocks for an SDIO port */ +int clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep) +{ + int ret; + struct clk *c; + + char *clkstr; + char *slpstr; + char *ahbstr; + + switch ((u32) base) { + case CONFIG_SYS_SDIO_BASE0: + clkstr = CONFIG_SYS_SDIO0 "_clk"; + ahbstr = CONFIG_SYS_SDIO0 "_ahb_clk"; + slpstr = CONFIG_SYS_SDIO0 "_sleep_clk"; + break; + case CONFIG_SYS_SDIO_BASE1: + clkstr = CONFIG_SYS_SDIO1 "_clk"; + ahbstr = CONFIG_SYS_SDIO1 "_ahb_clk"; + slpstr = CONFIG_SYS_SDIO1 "_sleep_clk"; + break; + case CONFIG_SYS_SDIO_BASE2: + clkstr = CONFIG_SYS_SDIO2 "_clk"; + ahbstr = CONFIG_SYS_SDIO2 "_ahb_clk"; + slpstr = CONFIG_SYS_SDIO2 "_sleep_clk"; + break; + case CONFIG_SYS_SDIO_BASE3: + clkstr = CONFIG_SYS_SDIO3 "_clk"; + ahbstr = CONFIG_SYS_SDIO3 "_ahb_clk"; + slpstr = CONFIG_SYS_SDIO3 "_sleep_clk"; + break; + default: + printf("%s: base 0x%p not found\n", __func__, base); + return -EINVAL; + } + + ret = clk_get_and_enable(ahbstr); + if (ret) + return ret; + + ret = clk_get_and_enable(slpstr); + if (ret) + return ret; + + c = clk_get(clkstr); + if (c) { + ret = clk_set_rate(c, rate); + if (ret) + return ret; + + ret = clk_enable(c); + if (ret) + return ret; + } else { + printf("%s: Couldn't find %s\n", __func__, clkstr); + return -EINVAL; + } + *actual_ratep = rate; + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c new file mode 100644 index 0000000..1d7c5af --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c
@@ -0,0 +1,27 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include "clk-core.h" + +/* Enable appropriate clocks for the USB OTG port */ +int clk_usb_otg_enable(void *base) +{ + char *ahbstr; + + switch ((u32) base) { + case HSOTG_BASE_ADDR: + ahbstr = "usb_otg_ahb_clk"; + break; + default: + printf("%s: base 0x%p not found\n", __func__, base); + return -EINVAL; + } + + return clk_get_and_enable(ahbstr); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/reset.c b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/reset.c new file mode 100644 index 0000000..3beb0ed --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcm281xx/reset.c
@@ -0,0 +1,27 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sysmap.h> + +#define EN_MASK 0x08000000 /* Enable timer */ +#define SRSTEN_MASK 0x04000000 /* Enable soft reset */ +#define CLKS_SHIFT 20 /* Clock period shift */ +#define LD_SHIFT 0 /* Reload value shift */ + +void reset_cpu(ulong ignored) +{ + /* + * Set WD enable, RST enable, + * 3.9 msec clock period (8), reload value (8*3.9ms) + */ + u32 reg = EN_MASK + SRSTEN_MASK + (8 << CLKS_SHIFT) + (8 << LD_SHIFT); + writel(reg, SECWD2_BASE_ADDR); + + while (1) + ; /* loop forever till reset */ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/Makefile b/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/Makefile new file mode 100644 index 0000000..04afcf9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/Makefile
@@ -0,0 +1,7 @@ +# +# Copyright 2014 Broadcom Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += reset.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/reset.c b/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/reset.c new file mode 100644 index 0000000..53ecc0c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcmcygnus/reset.c
@@ -0,0 +1,20 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#define CRMU_MAIL_BOX1 0x03024028 +#define CRMU_SOFT_RESET_CMD 0xFFFFFFFF + +void reset_cpu(ulong ignored) +{ + /* Send soft reset command via Mailbox. */ + writel(CRMU_SOFT_RESET_CMD, CRMU_MAIL_BOX1); + + while (1) + ; /* loop forever till reset */ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/Makefile b/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/Makefile new file mode 100644 index 0000000..04afcf9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/Makefile
@@ -0,0 +1,7 @@ +# +# Copyright 2014 Broadcom Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += reset.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/reset.c b/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/reset.c new file mode 100644 index 0000000..d79d9aa --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/bcmnsp/reset.c
@@ -0,0 +1,19 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#define CRU_RESET_OFFSET 0x1803F184 + +void reset_cpu(ulong ignored) +{ + /* Reset the cpu by setting software reset request bit */ + writel(0x1, CRU_RESET_OFFSET); + + while (1) + ; /* loop forever till reset */ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/cache_v7.c b/u-boot-imx/arch/arm/cpu/armv7/cache_v7.c new file mode 100644 index 0000000..0f9d837 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/cache_v7.c
@@ -0,0 +1,363 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <linux/types.h> +#include <common.h> +#include <asm/armv7.h> +#include <asm/utils.h> + +#define ARMV7_DCACHE_INVAL_ALL 1 +#define ARMV7_DCACHE_CLEAN_INVAL_ALL 2 +#define ARMV7_DCACHE_INVAL_RANGE 3 +#define ARMV7_DCACHE_CLEAN_INVAL_RANGE 4 + +#ifndef CONFIG_SYS_DCACHE_OFF +/* + * Write the level and type you want to Cache Size Selection Register(CSSELR) + * to get size details from Current Cache Size ID Register(CCSIDR) + */ +static void set_csselr(u32 level, u32 type) +{ + u32 csselr = level << 1 | type; + + /* Write to Cache Size Selection Register(CSSELR) */ + asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r" (csselr)); +} + +static u32 get_ccsidr(void) +{ + u32 ccsidr; + + /* Read current CP15 Cache Size ID Register */ + asm volatile ("mrc p15, 1, %0, c0, c0, 0" : "=r" (ccsidr)); + return ccsidr; +} + +static u32 get_clidr(void) +{ + u32 clidr; + + /* Read current CP15 Cache Level ID Register */ + asm volatile ("mrc p15,1,%0,c0,c0,1" : "=r" (clidr)); + return clidr; +} + +static void v7_inval_dcache_level_setway(u32 level, u32 num_sets, + u32 num_ways, u32 way_shift, + u32 log2_line_len) +{ + int way, set; + u32 setway; + + /* + * For optimal assembly code: + * a. count down + * b. have bigger loop inside + */ + for (way = num_ways - 1; way >= 0 ; way--) { + for (set = num_sets - 1; set >= 0; set--) { + setway = (level << 1) | (set << log2_line_len) | + (way << way_shift); + /* Invalidate data/unified cache line by set/way */ + asm volatile (" mcr p15, 0, %0, c7, c6, 2" + : : "r" (setway)); + } + } + /* DSB to make sure the operation is complete */ + CP15DSB; +} + +static void v7_clean_inval_dcache_level_setway(u32 level, u32 num_sets, + u32 num_ways, u32 way_shift, + u32 log2_line_len) +{ + int way, set; + u32 setway; + + /* + * For optimal assembly code: + * a. count down + * b. have bigger loop inside + */ + for (way = num_ways - 1; way >= 0 ; way--) { + for (set = num_sets - 1; set >= 0; set--) { + setway = (level << 1) | (set << log2_line_len) | + (way << way_shift); + /* + * Clean & Invalidate data/unified + * cache line by set/way + */ + asm volatile (" mcr p15, 0, %0, c7, c14, 2" + : : "r" (setway)); + } + } + /* DSB to make sure the operation is complete */ + CP15DSB; +} + +static void v7_maint_dcache_level_setway(u32 level, u32 operation) +{ + u32 ccsidr; + u32 num_sets, num_ways, log2_line_len, log2_num_ways; + u32 way_shift; + + set_csselr(level, ARMV7_CSSELR_IND_DATA_UNIFIED); + + ccsidr = get_ccsidr(); + + log2_line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + log2_line_len += 2; + + num_ways = ((ccsidr & CCSIDR_ASSOCIATIVITY_MASK) >> + CCSIDR_ASSOCIATIVITY_OFFSET) + 1; + num_sets = ((ccsidr & CCSIDR_NUM_SETS_MASK) >> + CCSIDR_NUM_SETS_OFFSET) + 1; + /* + * According to ARMv7 ARM number of sets and number of ways need + * not be a power of 2 + */ + log2_num_ways = log_2_n_round_up(num_ways); + + way_shift = (32 - log2_num_ways); + if (operation == ARMV7_DCACHE_INVAL_ALL) { + v7_inval_dcache_level_setway(level, num_sets, num_ways, + way_shift, log2_line_len); + } else if (operation == ARMV7_DCACHE_CLEAN_INVAL_ALL) { + v7_clean_inval_dcache_level_setway(level, num_sets, num_ways, + way_shift, log2_line_len); + } +} + +static void v7_maint_dcache_all(u32 operation) +{ + u32 level, cache_type, level_start_bit = 0; + u32 clidr = get_clidr(); + + for (level = 0; level < 7; level++) { + cache_type = (clidr >> level_start_bit) & 0x7; + if ((cache_type == ARMV7_CLIDR_CTYPE_DATA_ONLY) || + (cache_type == ARMV7_CLIDR_CTYPE_INSTRUCTION_DATA) || + (cache_type == ARMV7_CLIDR_CTYPE_UNIFIED)) + v7_maint_dcache_level_setway(level, operation); + level_start_bit += 3; + } +} + +static void v7_dcache_clean_inval_range(u32 start, u32 stop, u32 line_len) +{ + u32 mva; + + /* Align start to cache line boundary */ + start &= ~(line_len - 1); + for (mva = start; mva < stop; mva = mva + line_len) { + /* DCCIMVAC - Clean & Invalidate data cache by MVA to PoC */ + asm volatile ("mcr p15, 0, %0, c7, c14, 1" : : "r" (mva)); + } +} + +static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) +{ + u32 mva; + + /* + * If start address is not aligned to cache-line do not + * invalidate the first cache-line + */ + if (start & (line_len - 1)) { + printf("ERROR: %s - start address is not aligned - 0x%08x\n", + __func__, start); + /* move to next cache line */ + start = (start + line_len - 1) & ~(line_len - 1); + } + + /* + * If stop address is not aligned to cache-line do not + * invalidate the last cache-line + */ + if (stop & (line_len - 1)) { + printf("ERROR: %s - stop address is not aligned - 0x%08x\n", + __func__, stop); + /* align to the beginning of this cache line */ + stop &= ~(line_len - 1); + } + + for (mva = start; mva < stop; mva = mva + line_len) { + /* DCIMVAC - Invalidate data cache by MVA to PoC */ + asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (mva)); + } +} + +static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op) +{ + u32 line_len, ccsidr; + + ccsidr = get_ccsidr(); + line_len = ((ccsidr & CCSIDR_LINE_SIZE_MASK) >> + CCSIDR_LINE_SIZE_OFFSET) + 2; + /* Converting from words to bytes */ + line_len += 2; + /* converting from log2(linelen) to linelen */ + line_len = 1 << line_len; + + switch (range_op) { + case ARMV7_DCACHE_CLEAN_INVAL_RANGE: + v7_dcache_clean_inval_range(start, stop, line_len); + break; + case ARMV7_DCACHE_INVAL_RANGE: + v7_dcache_inval_range(start, stop, line_len); + break; + } + + /* DSB to make sure the operation is complete */ + CP15DSB; +} + +/* Invalidate TLB */ +static void v7_inval_tlb(void) +{ + /* Invalidate entire unified TLB */ + asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0)); + /* Invalidate entire data TLB */ + asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0)); + /* Invalidate entire instruction TLB */ + asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0)); + /* Full system DSB - make sure that the invalidation is complete */ + CP15DSB; + /* Full system ISB - make sure the instruction stream sees it */ + CP15ISB; +} + +void invalidate_dcache_all(void) +{ + v7_maint_dcache_all(ARMV7_DCACHE_INVAL_ALL); + + v7_outer_cache_inval_all(); +} + +/* + * Performs a clean & invalidation of the entire data cache + * at all levels + */ +void flush_dcache_all(void) +{ + v7_maint_dcache_all(ARMV7_DCACHE_CLEAN_INVAL_ALL); + + v7_outer_cache_flush_all(); +} + +/* + * Invalidates range in all levels of D-cache/unified cache used: + * Affects the range [start, stop - 1] + */ +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ + v7_dcache_maint_range(start, stop, ARMV7_DCACHE_INVAL_RANGE); + + v7_outer_cache_inval_range(start, stop); +} + +/* + * Flush range(clean & invalidate) from all levels of D-cache/unified + * cache used: + * Affects the range [start, stop - 1] + */ +void flush_dcache_range(unsigned long start, unsigned long stop) +{ + v7_dcache_maint_range(start, stop, ARMV7_DCACHE_CLEAN_INVAL_RANGE); + + v7_outer_cache_flush_range(start, stop); +} + +void arm_init_before_mmu(void) +{ + v7_outer_cache_enable(); + invalidate_dcache_all(); + v7_inval_tlb(); +} + +void mmu_page_table_flush(unsigned long start, unsigned long stop) +{ + flush_dcache_range(start, stop); + v7_inval_tlb(); +} + +/* + * Flush range from all levels of d-cache/unified-cache used: + * Affects the range [start, start + size - 1] + */ +void flush_cache(unsigned long start, unsigned long size) +{ + flush_dcache_range(start, start + size); +} +#else /* #ifndef CONFIG_SYS_DCACHE_OFF */ +void invalidate_dcache_all(void) +{ +} + +void flush_dcache_all(void) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void arm_init_before_mmu(void) +{ +} + +void flush_cache(unsigned long start, unsigned long size) +{ +} + +void mmu_page_table_flush(unsigned long start, unsigned long stop) +{ +} + +void arm_init_domains(void) +{ +} +#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ + +#ifndef CONFIG_SYS_ICACHE_OFF +/* Invalidate entire I-cache and branch predictor array */ +void invalidate_icache_all(void) +{ + /* + * Invalidate all instruction caches to PoU. + * Also flushes branch target cache. + */ + asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); + + /* Invalidate entire branch predictor array */ + asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0)); + + /* Full system DSB - make sure that the invalidation is complete */ + CP15DSB; + + /* ISB - make sure the instruction stream sees it */ + CP15ISB; +} +#else +void invalidate_icache_all(void) +{ +} +#endif + +/* Stub implementations for outer cache operations */ +__weak void v7_outer_cache_enable(void) {} +__weak void v7_outer_cache_disable(void) {} +__weak void v7_outer_cache_flush_all(void) {} +__weak void v7_outer_cache_inval_all(void) {} +__weak void v7_outer_cache_flush_range(u32 start, u32 end) {} +__weak void v7_outer_cache_inval_range(u32 start, u32 end) {}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/config.mk b/u-boot-imx/arch/arm/cpu/armv7/config.mk new file mode 100644 index 0000000..63591d4 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/config.mk
@@ -0,0 +1,13 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# On supported platforms we set the bit which causes us to trap on unaligned +# memory access. This is the opposite of what the compiler expects to be +# the default so we must pass in -mno-unaligned-access so that it is aware +# of our decision. +PF_NO_UNALIGNED := $(call cc-option, -mno-unaligned-access,) +PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/cp15.c b/u-boot-imx/arch/arm/cpu/armv7/cp15.c new file mode 100644 index 0000000..b44c9f9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/cp15.c
@@ -0,0 +1,29 @@ +/* + * (C) Copyright 2015 Texas Insturments + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CP15 specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <asm/cache.h> +#include <asm/armv7.h> +#include <linux/compiler.h> + +void __weak v7_arch_cp15_set_l2aux_ctrl(u32 l2actlr, u32 cpu_midr, + u32 cpu_rev_comb, u32 cpu_variant, + u32 cpu_rev) +{ + asm volatile ("mcr p15, 1, %0, c15, c0, 0\n\t" : : "r"(l2actlr)); +} + +void __weak v7_arch_cp15_set_acr(u32 acr, u32 cpu_midr, u32 cpu_rev_comb, + u32 cpu_variant, u32 cpu_rev) +{ + asm volatile ("mcr p15, 0, %0, c1, c0, 1\n\t" : : "r"(acr)); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/cpu.c b/u-boot-imx/arch/arm/cpu/armv7/cpu.c new file mode 100644 index 0000000..c56417d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/cpu.c
@@ -0,0 +1,70 @@ +/* + * (C) Copyright 2008 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, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <asm/cache.h> +#include <asm/armv7.h> +#include <linux/compiler.h> + +void __weak cpu_cache_initialization(void){} + +int cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ +#ifndef CONFIG_SPL_BUILD + disable_interrupts(); +#endif + + /* + * Turn off I-cache and invalidate it + */ + icache_disable(); + invalidate_icache_all(); + + /* + * turn off D-cache + * dcache_disable() in turn flushes the d-cache and disables MMU + */ + dcache_disable(); + v7_outer_cache_disable(); + + /* + * After D-cache is flushed and before it is disabled there may + * be some new valid entries brought into the cache. We are sure + * that these lines are not dirty and will not affect our execution. + * (because unwinding the call-stack and setting a bit in CP15 SCTLR + * is all we did during this. We have not pushed anything on to the + * stack. Neither have we affected any static data) + * So just invalidate the entire d-cache again to avoid coherency + * problems for kernel + */ + invalidate_dcache_all(); + + /* + * Some CPU need more cache attention before starting the kernel. + */ + cpu_cache_initialization(); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/exynos/Kconfig new file mode 100644 index 0000000..bd7540a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/Kconfig
@@ -0,0 +1,93 @@ +if ARCH_EXYNOS + +choice + prompt "EXYNOS board select" + +config TARGET_SMDKV310 + select SUPPORT_SPL + bool "Exynos4210 SMDKV310 board" + select OF_CONTROL + +config TARGET_TRATS + bool "Exynos4210 Trats board" + +config TARGET_S5PC210_UNIVERSAL + bool "EXYNOS4210 Universal C210 board" + +config TARGET_ORIGEN + bool "Exynos4412 Origen board" + select SUPPORT_SPL + +config TARGET_TRATS2 + bool "Exynos4412 Trat2 board" + +config TARGET_ODROID + bool "Exynos4412 Odroid board" + +config TARGET_ODROID_XU3 + bool "Exynos5422 Odroid board" + select OF_CONTROL + +config TARGET_ARNDALE + bool "Exynos5250 Arndale board" + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select SUPPORT_SPL + select OF_CONTROL + +config TARGET_SMDK5250 + bool "SMDK5250 board" + select SUPPORT_SPL + select OF_CONTROL + +config TARGET_SNOW + bool "Snow board" + select SUPPORT_SPL + select OF_CONTROL + +config TARGET_SMDK5420 + bool "SMDK5420 board" + select SUPPORT_SPL + select OF_CONTROL + +config TARGET_PEACH_PI + bool "Peach Pi board" + select SUPPORT_SPL + select OF_CONTROL + +config TARGET_PEACH_PIT + bool "Peach Pit board" + select SUPPORT_SPL + select OF_CONTROL + +endchoice + +config SYS_SOC + default "exynos" + +config DM + default y + +config DM_SERIAL + default y + +config DM_SPI + default y + +config DM_SPI_FLASH + default y + +config DM_GPIO + default y + +source "board/samsung/smdkv310/Kconfig" +source "board/samsung/trats/Kconfig" +source "board/samsung/universal_c210/Kconfig" +source "board/samsung/origen/Kconfig" +source "board/samsung/trats2/Kconfig" +source "board/samsung/odroid/Kconfig" +source "board/samsung/arndale/Kconfig" +source "board/samsung/smdk5250/Kconfig" +source "board/samsung/smdk5420/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/Makefile b/u-boot-imx/arch/arm/cpu/armv7/exynos/Makefile new file mode 100644 index 0000000..8542f89 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/Makefile
@@ -0,0 +1,18 @@ +# +# Copyright (C) 2009 Samsung Electronics +# Minkyu Kang <mk7.kang@samsung.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += clock.o power.o soc.o system.o pinmux.o tzpc.o + +obj-$(CONFIG_EXYNOS5420) += sec_boot.o + +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_EXYNOS5) += clock_init_exynos5.o +obj-$(CONFIG_EXYNOS5) += dmc_common.o dmc_init_ddr3.o +obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o +obj-y += spl_boot.o +obj-y += lowlevel_init.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/clock.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock.c new file mode 100644 index 0000000..df4d473 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock.c
@@ -0,0 +1,1767 @@ +/* + * Copyright (C) 2010 Samsung Electronics + * Minkyu Kang <mk7.kang@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/clk.h> +#include <asm/arch/periph.h> + +#define PLL_DIV_1024 1024 +#define PLL_DIV_65535 65535 +#define PLL_DIV_65536 65536 +/* * + * This structure is to store the src bit, div bit and prediv bit + * positions of the peripheral clocks of the src and div registers + */ +struct clk_bit_info { + enum periph_id id; + int32_t src_mask; + int32_t div_mask; + int32_t prediv_mask; + int8_t src_bit; + int8_t div_bit; + int8_t prediv_bit; +}; + +static struct clk_bit_info exynos5_bit_info[] = { + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ + {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1}, + {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1}, + {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1}, + {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1}, + {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0}, + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8}, + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24}, + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8}, + {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8}, + {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24}, + {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8}, + {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24}, + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8}, + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1}, + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1}, + + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, +}; + +static struct clk_bit_info exynos542x_bit_info[] = { + /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */ + {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1}, + {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1}, + {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1}, + {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1}, + {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8}, + {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16}, + {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24}, + {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1}, + {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1}, + {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1}, + {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1}, + {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4}, + {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16}, + {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0}, + {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8}, + {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1}, + {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1}, + + {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1}, +}; + +/* Epll Clock division values to achive different frequency output */ +static struct set_epll_con_val exynos5_epll_div[] = { + { 192000000, 0, 48, 3, 1, 0 }, + { 180000000, 0, 45, 3, 1, 0 }, + { 73728000, 1, 73, 3, 3, 47710 }, + { 67737600, 1, 90, 4, 3, 20762 }, + { 49152000, 0, 49, 3, 3, 9961 }, + { 45158400, 0, 45, 3, 3, 10381 }, + { 180633600, 0, 45, 3, 1, 10381 } +}; + +/* exynos: return pll clock frequency */ +static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k) +{ + unsigned long m, p, s = 0, mask, fout; + unsigned int div; + unsigned int freq; + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + * BPLL_CON: MIDV [25:16]: Exynos5 + */ + if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL || + pllreg == SPLL) + mask = 0x3ff; + else + mask = 0x1ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ; + + if (pllreg == EPLL || pllreg == RPLL) { + k = k & 0xffff; + /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ + fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s))); + } else if (pllreg == VPLL) { + k = k & 0xfff; + + /* + * Exynos4210 + * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) + * + * Exynos4412 + * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV) + * + * Exynos5250 + * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) + */ + if (proid_is_exynos4210()) + div = PLL_DIV_1024; + else if (proid_is_exynos4412()) + div = PLL_DIV_65535; + else if (proid_is_exynos5250() || proid_is_exynos5420() + || proid_is_exynos5800()) + div = PLL_DIV_65536; + else + return 0; + + fout = (m + k / div) * (freq / (p * (1 << s))); + } else { + /* + * Exynos4412 / Exynos5250 + * FOUT = MDIV * FIN / (PDIV * 2^SDIV) + * + * Exynos4210 + * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1)) + */ + if (proid_is_exynos4210()) + fout = m * (freq / (p * (1 << (s - 1)))); + else + fout = m * (freq / (p * (1 << s))); + } + return fout; +} + +/* exynos4: return pll clock frequency */ +static unsigned long exynos4_get_pll_clk(int pllreg) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long r, k = 0; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con0); + break; + case MPLL: + r = readl(&clk->mpll_con0); + break; + case EPLL: + r = readl(&clk->epll_con0); + k = readl(&clk->epll_con1); + break; + case VPLL: + r = readl(&clk->vpll_con0); + k = readl(&clk->vpll_con1); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + return exynos_get_pll_clk(pllreg, r, k); +} + +/* exynos4x12: return pll clock frequency */ +static unsigned long exynos4x12_get_pll_clk(int pllreg) +{ + struct exynos4x12_clock *clk = + (struct exynos4x12_clock *)samsung_get_base_clock(); + unsigned long r, k = 0; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con0); + break; + case MPLL: + r = readl(&clk->mpll_con0); + break; + case EPLL: + r = readl(&clk->epll_con0); + k = readl(&clk->epll_con1); + break; + case VPLL: + r = readl(&clk->vpll_con0); + k = readl(&clk->vpll_con1); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + return exynos_get_pll_clk(pllreg, r, k); +} + +/* exynos5: return pll clock frequency */ +static unsigned long exynos5_get_pll_clk(int pllreg) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned long r, k = 0, fout; + unsigned int pll_div2_sel, fout_sel; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con0); + break; + case MPLL: + r = readl(&clk->mpll_con0); + break; + case EPLL: + r = readl(&clk->epll_con0); + k = readl(&clk->epll_con1); + break; + case VPLL: + r = readl(&clk->vpll_con0); + k = readl(&clk->vpll_con1); + break; + case BPLL: + r = readl(&clk->bpll_con0); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + fout = exynos_get_pll_clk(pllreg, r, k); + + /* According to the user manual, in EVT1 MPLL and BPLL always gives + * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/ + if (pllreg == MPLL || pllreg == BPLL) { + pll_div2_sel = readl(&clk->pll_div2_sel); + + switch (pllreg) { + case MPLL: + fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT) + & MPLL_FOUT_SEL_MASK; + break; + case BPLL: + fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT) + & BPLL_FOUT_SEL_MASK; + break; + default: + fout_sel = -1; + break; + } + + if (fout_sel == 0) + fout /= 2; + } + + return fout; +} + +/* exynos542x: return pll clock frequency */ +static unsigned long exynos542x_get_pll_clk(int pllreg) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned long r, k = 0; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con0); + break; + case MPLL: + r = readl(&clk->mpll_con0); + break; + case EPLL: + r = readl(&clk->epll_con0); + k = readl(&clk->epll_con1); + break; + case VPLL: + r = readl(&clk->vpll_con0); + k = readl(&clk->vpll_con1); + break; + case BPLL: + r = readl(&clk->bpll_con0); + break; + case RPLL: + r = readl(&clk->rpll_con0); + k = readl(&clk->rpll_con1); + break; + case SPLL: + r = readl(&clk->spll_con0); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + return exynos_get_pll_clk(pllreg, r, k); +} + +static struct clk_bit_info *get_clk_bit_info(int peripheral) +{ + int i; + struct clk_bit_info *info; + + if (proid_is_exynos5420() || proid_is_exynos5800()) + info = exynos542x_bit_info; + else + info = exynos5_bit_info; + + for (i = 0; info[i].id != PERIPH_ID_NONE; i++) { + if (info[i].id == peripheral) + break; + } + + if (info[i].id == PERIPH_ID_NONE) + debug("ERROR: Peripheral ID %d not found\n", peripheral); + + return &info[i]; +} + +static unsigned long exynos5_get_periph_rate(int peripheral) +{ + struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); + unsigned long sclk = 0; + unsigned int src = 0, div = 0, sub_div = 0; + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + src = readl(&clk->src_peric0); + div = readl(&clk->div_peric0); + break; + case PERIPH_ID_PWM0: + case PERIPH_ID_PWM1: + case PERIPH_ID_PWM2: + case PERIPH_ID_PWM3: + case PERIPH_ID_PWM4: + src = readl(&clk->src_peric0); + div = readl(&clk->div_peric3); + break; + case PERIPH_ID_I2S0: + src = readl(&clk->src_mau); + div = sub_div = readl(&clk->div_mau); + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + src = readl(&clk->src_peric1); + div = sub_div = readl(&clk->div_peric1); + break; + case PERIPH_ID_SPI2: + src = readl(&clk->src_peric1); + div = sub_div = readl(&clk->div_peric2); + break; + case PERIPH_ID_SPI3: + case PERIPH_ID_SPI4: + src = readl(&clk->sclk_src_isp); + div = sub_div = readl(&clk->sclk_div_isp); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + src = readl(&clk->src_fsys); + div = sub_div = readl(&clk->div_fsys1); + break; + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + src = readl(&clk->src_fsys); + div = sub_div = readl(&clk->div_fsys2); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + src = EXYNOS_SRC_MPLL; + div = readl(&clk->div_top1); + sub_div = readl(&clk->div_top0); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + }; + + if (bit_info->src_bit >= 0) + src = (src >> bit_info->src_bit) & bit_info->src_mask; + + switch (src) { + case EXYNOS_SRC_MPLL: + sclk = exynos5_get_pll_clk(MPLL); + break; + case EXYNOS_SRC_EPLL: + sclk = exynos5_get_pll_clk(EPLL); + break; + case EXYNOS_SRC_VPLL: + sclk = exynos5_get_pll_clk(VPLL); + break; + default: + debug("%s: EXYNOS_SRC %d not supported\n", __func__, src); + return 0; + } + + /* Clock divider ratio for this peripheral */ + if (bit_info->div_bit >= 0) + div = (div >> bit_info->div_bit) & bit_info->div_mask; + + /* Clock pre-divider ratio for this peripheral */ + if (bit_info->prediv_bit >= 0) + sub_div = (sub_div >> bit_info->prediv_bit) + & bit_info->prediv_mask; + + /* Calculate and return required clock rate */ + return (sclk / (div + 1)) / (sub_div + 1); +} + +static unsigned long exynos542x_get_periph_rate(int peripheral) +{ + struct clk_bit_info *bit_info = get_clk_bit_info(peripheral); + unsigned long sclk = 0; + unsigned int src = 0, div = 0, sub_div = 0; + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + case PERIPH_ID_PWM0: + case PERIPH_ID_PWM1: + case PERIPH_ID_PWM2: + case PERIPH_ID_PWM3: + case PERIPH_ID_PWM4: + src = readl(&clk->src_peric0); + div = readl(&clk->div_peric0); + break; + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + case PERIPH_ID_SPI2: + src = readl(&clk->src_peric1); + div = readl(&clk->div_peric1); + sub_div = readl(&clk->div_peric4); + break; + case PERIPH_ID_SPI3: + case PERIPH_ID_SPI4: + src = readl(&clk->src_isp); + div = readl(&clk->div_isp1); + sub_div = readl(&clk->div_isp1); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + src = readl(&clk->src_fsys); + div = readl(&clk->div_fsys1); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + case PERIPH_ID_I2C8: + case PERIPH_ID_I2C9: + case PERIPH_ID_I2C10: + src = EXYNOS542X_SRC_MPLL; + div = readl(&clk->div_top1); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + }; + + if (bit_info->src_bit >= 0) + src = (src >> bit_info->src_bit) & bit_info->src_mask; + + switch (src) { + case EXYNOS542X_SRC_MPLL: + sclk = exynos542x_get_pll_clk(MPLL); + break; + case EXYNOS542X_SRC_SPLL: + sclk = exynos542x_get_pll_clk(SPLL); + break; + case EXYNOS542X_SRC_EPLL: + sclk = exynos542x_get_pll_clk(EPLL); + break; + case EXYNOS542X_SRC_RPLL: + sclk = exynos542x_get_pll_clk(RPLL); + break; + default: + debug("%s: EXYNOS542X_SRC %d not supported", __func__, src); + return 0; + } + + /* Clock divider ratio for this peripheral */ + if (bit_info->div_bit >= 0) + div = (div >> bit_info->div_bit) & bit_info->div_mask; + + /* Clock pre-divider ratio for this peripheral */ + if (bit_info->prediv_bit >= 0) + sub_div = (sub_div >> bit_info->prediv_bit) + & bit_info->prediv_mask; + + /* Calculate and return required clock rate */ + return (sclk / (div + 1)) / (sub_div + 1); +} + +unsigned long clock_get_periph_rate(int peripheral) +{ + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + return exynos542x_get_periph_rate(peripheral); + return exynos5_get_periph_rate(peripheral); + } else { + return 0; + } +} + +/* exynos4: return ARM clock frequency */ +static unsigned long exynos4_get_arm_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long div; + unsigned long armclk; + unsigned int core_ratio; + unsigned int core2_ratio; + + div = readl(&clk->div_cpu0); + + /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ + core_ratio = (div >> 0) & 0x7; + core2_ratio = (div >> 28) & 0x7; + + armclk = get_pll_clk(APLL) / (core_ratio + 1); + armclk /= (core2_ratio + 1); + + return armclk; +} + +/* exynos4x12: return ARM clock frequency */ +static unsigned long exynos4x12_get_arm_clk(void) +{ + struct exynos4x12_clock *clk = + (struct exynos4x12_clock *)samsung_get_base_clock(); + unsigned long div; + unsigned long armclk; + unsigned int core_ratio; + unsigned int core2_ratio; + + div = readl(&clk->div_cpu0); + + /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */ + core_ratio = (div >> 0) & 0x7; + core2_ratio = (div >> 28) & 0x7; + + armclk = get_pll_clk(APLL) / (core_ratio + 1); + armclk /= (core2_ratio + 1); + + return armclk; +} + +/* exynos5: return ARM clock frequency */ +static unsigned long exynos5_get_arm_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned long div; + unsigned long armclk; + unsigned int arm_ratio; + unsigned int arm2_ratio; + + div = readl(&clk->div_cpu0); + + /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */ + arm_ratio = (div >> 0) & 0x7; + arm2_ratio = (div >> 28) & 0x7; + + armclk = get_pll_clk(APLL) / (arm_ratio + 1); + armclk /= (arm2_ratio + 1); + + return armclk; +} + +/* exynos4: return pwm clock frequency */ +static unsigned long exynos4_get_pwm_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long pclk, sclk; + unsigned int sel; + unsigned int ratio; + + if (s5p_get_cpu_rev() == 0) { + /* + * CLK_SRC_PERIL0 + * PWM_SEL [27:24] + */ + sel = readl(&clk->src_peril0); + sel = (sel >> 24) & 0xf; + + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_PERIL3 + * PWM_RATIO [3:0] + */ + ratio = readl(&clk->div_peril3); + ratio = ratio & 0xf; + } else if (s5p_get_cpu_rev() == 1) { + sclk = get_pll_clk(MPLL); + ratio = 8; + } else + return 0; + + pclk = sclk / (ratio + 1); + + return pclk; +} + +/* exynos4x12: return pwm clock frequency */ +static unsigned long exynos4x12_get_pwm_clk(void) +{ + unsigned long pclk, sclk; + unsigned int ratio; + + sclk = get_pll_clk(MPLL); + ratio = 8; + + pclk = sclk / (ratio + 1); + + return pclk; +} + +/* exynos4: return uart clock frequency */ +static unsigned long exynos4_get_uart_clk(int dev_index) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long uclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_PERIL0 + * UART0_SEL [3:0] + * UART1_SEL [7:4] + * UART2_SEL [8:11] + * UART3_SEL [12:15] + * UART4_SEL [16:19] + * UART5_SEL [23:20] + */ + sel = readl(&clk->src_peril0); + sel = (sel >> (dev_index << 2)) & 0xf; + + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_PERIL0 + * UART0_RATIO [3:0] + * UART1_RATIO [7:4] + * UART2_RATIO [8:11] + * UART3_RATIO [12:15] + * UART4_RATIO [16:19] + * UART5_RATIO [23:20] + */ + ratio = readl(&clk->div_peril0); + ratio = (ratio >> (dev_index << 2)) & 0xf; + + uclk = sclk / (ratio + 1); + + return uclk; +} + +/* exynos4x12: return uart clock frequency */ +static unsigned long exynos4x12_get_uart_clk(int dev_index) +{ + struct exynos4x12_clock *clk = + (struct exynos4x12_clock *)samsung_get_base_clock(); + unsigned long uclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_PERIL0 + * UART0_SEL [3:0] + * UART1_SEL [7:4] + * UART2_SEL [8:11] + * UART3_SEL [12:15] + * UART4_SEL [16:19] + */ + sel = readl(&clk->src_peril0); + sel = (sel >> (dev_index << 2)) & 0xf; + + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_PERIL0 + * UART0_RATIO [3:0] + * UART1_RATIO [7:4] + * UART2_RATIO [8:11] + * UART3_RATIO [12:15] + * UART4_RATIO [16:19] + */ + ratio = readl(&clk->div_peril0); + ratio = (ratio >> (dev_index << 2)) & 0xf; + + uclk = sclk / (ratio + 1); + + return uclk; +} + +static unsigned long exynos4_get_mmc_clk(int dev_index) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long uclk, sclk; + unsigned int sel, ratio, pre_ratio; + int shift = 0; + + sel = readl(&clk->src_fsys); + sel = (sel >> (dev_index << 2)) & 0xf; + + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + switch (dev_index) { + case 0: + case 1: + ratio = readl(&clk->div_fsys1); + pre_ratio = readl(&clk->div_fsys1); + break; + case 2: + case 3: + ratio = readl(&clk->div_fsys2); + pre_ratio = readl(&clk->div_fsys2); + break; + case 4: + ratio = readl(&clk->div_fsys3); + pre_ratio = readl(&clk->div_fsys3); + break; + default: + return 0; + } + + if (dev_index == 1 || dev_index == 3) + shift = 16; + + ratio = (ratio >> shift) & 0xf; + pre_ratio = (pre_ratio >> (shift + 8)) & 0xff; + uclk = (sclk / (ratio + 1)) / (pre_ratio + 1); + + return uclk; +} + +/* exynos4: set the mmc clock */ +static void exynos4_set_mmc_clk(int dev_index, unsigned int div) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned int addr, clear_bit, set_bit; + + /* + * CLK_DIV_FSYS1 + * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * CLK_DIV_FSYS2 + * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + * CLK_DIV_FSYS3 + * MMC4_RATIO [3:0] + */ + if (dev_index < 2) { + addr = (unsigned int)&clk->div_fsys1; + clear_bit = MASK_PRE_RATIO(dev_index); + set_bit = SET_PRE_RATIO(dev_index, div); + } else if (dev_index == 4) { + addr = (unsigned int)&clk->div_fsys3; + dev_index -= 4; + /* MMC4 is controlled with the MMC4_RATIO value */ + clear_bit = MASK_RATIO(dev_index); + set_bit = SET_RATIO(dev_index, div); + } else { + addr = (unsigned int)&clk->div_fsys2; + dev_index -= 2; + clear_bit = MASK_PRE_RATIO(dev_index); + set_bit = SET_PRE_RATIO(dev_index, div); + } + + clrsetbits_le32(addr, clear_bit, set_bit); +} + +/* exynos5: set the mmc clock */ +static void exynos5_set_mmc_clk(int dev_index, unsigned int div) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int addr; + + /* + * CLK_DIV_FSYS1 + * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24] + * CLK_DIV_FSYS2 + * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24] + */ + if (dev_index < 2) { + addr = (unsigned int)&clk->div_fsys1; + } else { + addr = (unsigned int)&clk->div_fsys2; + dev_index -= 2; + } + + clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8), + (div & 0xff) << ((dev_index << 4) + 8)); +} + +/* exynos5: set the mmc clock */ +static void exynos5420_set_mmc_clk(int dev_index, unsigned int div) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned int addr; + unsigned int shift; + + /* + * CLK_DIV_FSYS1 + * MMC0_RATIO [9:0] + * MMC1_RATIO [19:10] + * MMC2_RATIO [29:20] + */ + addr = (unsigned int)&clk->div_fsys1; + shift = dev_index * 10; + + clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift); +} + +/* get_lcd_clk: return lcd clock frequency */ +static unsigned long exynos4_get_lcd_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long pclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + */ + sel = readl(&clk->src_lcd0); + sel = sel & 0xf; + + /* + * 0x6: SCLK_MPLL + * 0x7: SCLK_EPLL + * 0x8: SCLK_VPLL + */ + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + */ + ratio = readl(&clk->div_lcd0); + ratio = ratio & 0xf; + + pclk = sclk / (ratio + 1); + + return pclk; +} + +/* get_lcd_clk: return lcd clock frequency */ +static unsigned long exynos5_get_lcd_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned long pclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + */ + sel = readl(&clk->src_disp1_0); + sel = sel & 0xf; + + /* + * 0x6: SCLK_MPLL + * 0x7: SCLK_EPLL + * 0x8: SCLK_VPLL + */ + if (sel == 0x6) + sclk = get_pll_clk(MPLL); + else if (sel == 0x7) + sclk = get_pll_clk(EPLL); + else if (sel == 0x8) + sclk = get_pll_clk(VPLL); + else + return 0; + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + */ + ratio = readl(&clk->div_disp1_0); + ratio = ratio & 0xf; + + pclk = sclk / (ratio + 1); + + return pclk; +} + +static unsigned long exynos5420_get_lcd_clk(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned long pclk, sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_DISP10 + * FIMD1_SEL [4] + * 0: SCLK_RPLL + * 1: SCLK_SPLL + */ + sel = readl(&clk->src_disp10); + sel &= (1 << 4); + + if (sel) + sclk = get_pll_clk(SPLL); + else + sclk = get_pll_clk(RPLL); + + /* + * CLK_DIV_DISP10 + * FIMD1_RATIO [3:0] + */ + ratio = readl(&clk->div_disp10); + ratio = ratio & 0xf; + + pclk = sclk / (ratio + 1); + + return pclk; +} + +static unsigned long exynos5800_get_lcd_clk(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned long sclk; + unsigned int sel; + unsigned int ratio; + + /* + * CLK_SRC_DISP10 + * CLKMUX_FIMD1 [6:4] + */ + sel = (readl(&clk->src_disp10) >> 4) & 0x7; + + if (sel) { + /* + * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into + * PLLs. The first element is a placeholder to bypass the + * default settig. + */ + const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL, + RPLL}; + sclk = get_pll_clk(reg_map[sel]); + } else + sclk = CONFIG_SYS_CLK_FREQ; + /* + * CLK_DIV_DISP10 + * FIMD1_RATIO [3:0] + */ + ratio = readl(&clk->div_disp10) & 0xf; + + return sclk / (ratio + 1); +} + +void exynos4_set_lcd_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + + /* + * CLK_GATE_BLOCK + * CLK_CAM [0] + * CLK_TV [1] + * CLK_MFC [2] + * CLK_G3D [3] + * CLK_LCD0 [4] + * CLK_LCD1 [5] + * CLK_GPS [7] + */ + setbits_le32(&clk->gate_block, 1 << 4); + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + * MDNIE0_SEL [7:4] + * MDNIE_PWM0_SEL [8:11] + * MIPI0_SEL [12:15] + * set lcd0 src clock 0x6: SCLK_MPLL + */ + clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6); + + /* + * CLK_GATE_IP_LCD0 + * CLK_FIMD0 [0] + * CLK_MIE0 [1] + * CLK_MDNIE0 [2] + * CLK_DSIM0 [3] + * CLK_SMMUFIMD0 [4] + * CLK_PPMULCD0 [5] + * Gating all clocks for FIMD0 + */ + setbits_le32(&clk->gate_ip_lcd0, 1 << 0); + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + * MDNIE0_RATIO [7:4] + * MDNIE_PWM0_RATIO [11:8] + * MDNIE_PWM_PRE_RATIO [15:12] + * MIPI0_RATIO [19:16] + * MIPI0_PRE_RATIO [23:20] + * set fimd ratio + */ + clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1); +} + +void exynos5_set_lcd_clk(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + /* + * CLK_GATE_BLOCK + * CLK_CAM [0] + * CLK_TV [1] + * CLK_MFC [2] + * CLK_G3D [3] + * CLK_LCD0 [4] + * CLK_LCD1 [5] + * CLK_GPS [7] + */ + setbits_le32(&clk->gate_block, 1 << 4); + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + * MDNIE0_SEL [7:4] + * MDNIE_PWM0_SEL [8:11] + * MIPI0_SEL [12:15] + * set lcd0 src clock 0x6: SCLK_MPLL + */ + clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6); + + /* + * CLK_GATE_IP_LCD0 + * CLK_FIMD0 [0] + * CLK_MIE0 [1] + * CLK_MDNIE0 [2] + * CLK_DSIM0 [3] + * CLK_SMMUFIMD0 [4] + * CLK_PPMULCD0 [5] + * Gating all clocks for FIMD0 + */ + setbits_le32(&clk->gate_ip_disp1, 1 << 0); + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + * MDNIE0_RATIO [7:4] + * MDNIE_PWM0_RATIO [11:8] + * MDNIE_PWM_PRE_RATIO [15:12] + * MIPI0_RATIO [19:16] + * MIPI0_PRE_RATIO [23:20] + * set fimd ratio + */ + clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0); +} + +void exynos5420_set_lcd_clk(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned int cfg; + + /* + * CLK_SRC_DISP10 + * FIMD1_SEL [4] + * 0: SCLK_RPLL + * 1: SCLK_SPLL + */ + cfg = readl(&clk->src_disp10); + cfg &= ~(0x1 << 4); + cfg |= (0 << 4); + writel(cfg, &clk->src_disp10); + + /* + * CLK_DIV_DISP10 + * FIMD1_RATIO [3:0] + */ + cfg = readl(&clk->div_disp10); + cfg &= ~(0xf << 0); + cfg |= (0 << 0); + writel(cfg, &clk->div_disp10); +} + +void exynos5800_set_lcd_clk(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + unsigned int cfg; + + /* + * Use RPLL for pixel clock + * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] + * ================== + * 111: SCLK_RPLL + */ + cfg = readl(&clk->src_disp10) | (0x7 << 4); + writel(cfg, &clk->src_disp10); + + /* + * CLK_DIV_DISP10 + * FIMD1_RATIO [3:0] + */ + clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0); +} + +void exynos4_set_mipi_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + + /* + * CLK_SRC_LCD0 + * FIMD0_SEL [3:0] + * MDNIE0_SEL [7:4] + * MDNIE_PWM0_SEL [8:11] + * MIPI0_SEL [12:15] + * set mipi0 src clock 0x6: SCLK_MPLL + */ + clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12); + + /* + * CLK_SRC_MASK_LCD0 + * FIMD0_MASK [0] + * MDNIE0_MASK [4] + * MDNIE_PWM0_MASK [8] + * MIPI0_MASK [12] + * set src mask mipi0 0x1: Unmask + */ + setbits_le32(&clk->src_mask_lcd0, 0x1 << 12); + + /* + * CLK_GATE_IP_LCD0 + * CLK_FIMD0 [0] + * CLK_MIE0 [1] + * CLK_MDNIE0 [2] + * CLK_DSIM0 [3] + * CLK_SMMUFIMD0 [4] + * CLK_PPMULCD0 [5] + * Gating all clocks for MIPI0 + */ + setbits_le32(&clk->gate_ip_lcd0, 1 << 3); + + /* + * CLK_DIV_LCD0 + * FIMD0_RATIO [3:0] + * MDNIE0_RATIO [7:4] + * MDNIE_PWM0_RATIO [11:8] + * MDNIE_PWM_PRE_RATIO [15:12] + * MIPI0_RATIO [19:16] + * MIPI0_PRE_RATIO [23:20] + * set mipi ratio + */ + clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16); +} + +int exynos5_set_epll_clk(unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + unsigned int lockcnt; + unsigned int start; + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + epll_con = readl(&clk->epll_con0); + epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK << + EPLL_CON0_LOCK_DET_EN_SHIFT) | + EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT | + EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT | + EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) { + if (exynos5_epll_div[i].freq_out == rate) + break; + } + + if (i == ARRAY_SIZE(exynos5_epll_div)) + return -1; + + epll_con_k = exynos5_epll_div[i].k_dsm << 0; + epll_con |= exynos5_epll_div[i].en_lock_det << + EPLL_CON0_LOCK_DET_EN_SHIFT; + epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT; + epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT; + epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT; + + /* + * Required period ( in cycles) to genarate a stable clock output. + * The maximum clock time can be up to 3000 * PDIV cycles of PLLs + * frequency input (as per spec) + */ + lockcnt = 3000 * exynos5_epll_div[i].p_div; + + writel(lockcnt, &clk->epll_lock); + writel(epll_con, &clk->epll_con0); + writel(epll_con_k, &clk->epll_con1); + + start = get_timer(0); + + while (!(readl(&clk->epll_con0) & + (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) { + if (get_timer(start) > TIMEOUT_EPLL_LOCK) { + debug("%s: Timeout waiting for EPLL lock\n", __func__); + return -1; + } + } + return 0; +} + +int exynos5_set_i2s_clk_source(unsigned int i2s_id) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass(); + + if (i2s_id == 0) { + setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL); + clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK, + (CLK_SRC_SCLK_EPLL)); + setbits_le32(audio_ass, AUDIO_CLKMUX_ASS); + } else if (i2s_id == 1) { + clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK, + (CLK_SRC_SCLK_EPLL)); + } else { + return -1; + } + return 0; +} + +int exynos5_set_i2s_clk_prescaler(unsigned int src_frq, + unsigned int dst_frq, + unsigned int i2s_id) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int div; + + if ((dst_frq == 0) || (src_frq == 0)) { + debug("%s: Invalid requency input for prescaler\n", __func__); + debug("src frq = %d des frq = %d ", src_frq, dst_frq); + return -1; + } + + div = (src_frq / dst_frq); + if (i2s_id == 0) { + if (div > AUDIO_0_RATIO_MASK) { + debug("%s: Frequency ratio is out of range\n", + __func__); + debug("src frq = %d des frq = %d ", src_frq, dst_frq); + return -1; + } + clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK, + (div & AUDIO_0_RATIO_MASK)); + } else if(i2s_id == 1) { + if (div > AUDIO_1_RATIO_MASK) { + debug("%s: Frequency ratio is out of range\n", + __func__); + debug("src frq = %d des frq = %d ", src_frq, dst_frq); + return -1; + } + clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK, + (div & AUDIO_1_RATIO_MASK)); + } else { + return -1; + } + return 0; +} + +/** + * Linearly searches for the most accurate main and fine stage clock scalars + * (divisors) for a specified target frequency and scalar bit sizes by checking + * all multiples of main_scalar_bits values. Will always return scalars up to or + * slower than target. + * + * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32 + * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32 + * @param input_freq Clock frequency to be scaled in Hz + * @param target_freq Desired clock frequency in Hz + * @param best_fine_scalar Pointer to store the fine stage divisor + * + * @return best_main_scalar Main scalar for desired frequency or -1 if none + * found + */ +static int clock_calc_best_scalar(unsigned int main_scaler_bits, + unsigned int fine_scalar_bits, unsigned int input_rate, + unsigned int target_rate, unsigned int *best_fine_scalar) +{ + int i; + int best_main_scalar = -1; + unsigned int best_error = target_rate; + const unsigned int cap = (1 << fine_scalar_bits) - 1; + const unsigned int loops = 1 << main_scaler_bits; + + debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate, + target_rate, cap); + + assert(best_fine_scalar != NULL); + assert(main_scaler_bits <= fine_scalar_bits); + + *best_fine_scalar = 1; + + if (input_rate == 0 || target_rate == 0) + return -1; + + if (target_rate >= input_rate) + return 1; + + for (i = 1; i <= loops; i++) { + const unsigned int effective_div = + max(min(input_rate / i / target_rate, cap), 1U); + const unsigned int effective_rate = input_rate / i / + effective_div; + const int error = target_rate - effective_rate; + + debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div, + effective_rate, error); + + if (error >= 0 && error <= best_error) { + best_error = error; + best_main_scalar = i; + *best_fine_scalar = effective_div; + } + } + + return best_main_scalar; +} + +static int exynos5_set_spi_clk(enum periph_id periph_id, + unsigned int rate) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + int main; + unsigned int fine; + unsigned shift, pre_shift; + unsigned mask = 0xff; + u32 *reg; + + main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); + if (main < 0) { + debug("%s: Cannot set clock rate for periph %d", + __func__, periph_id); + return -1; + } + main = main - 1; + fine = fine - 1; + + switch (periph_id) { + case PERIPH_ID_SPI0: + reg = &clk->div_peric1; + shift = 0; + pre_shift = 8; + break; + case PERIPH_ID_SPI1: + reg = &clk->div_peric1; + shift = 16; + pre_shift = 24; + break; + case PERIPH_ID_SPI2: + reg = &clk->div_peric2; + shift = 0; + pre_shift = 8; + break; + case PERIPH_ID_SPI3: + reg = &clk->sclk_div_isp; + shift = 0; + pre_shift = 4; + break; + case PERIPH_ID_SPI4: + reg = &clk->sclk_div_isp; + shift = 12; + pre_shift = 16; + break; + default: + debug("%s: Unsupported peripheral ID %d\n", __func__, + periph_id); + return -1; + } + clrsetbits_le32(reg, mask << shift, (main & mask) << shift); + clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift); + + return 0; +} + +static int exynos5420_set_spi_clk(enum periph_id periph_id, + unsigned int rate) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + int main; + unsigned int fine; + unsigned shift, pre_shift; + unsigned div_mask = 0xf, pre_div_mask = 0xff; + u32 *reg; + u32 *pre_reg; + + main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine); + if (main < 0) { + debug("%s: Cannot set clock rate for periph %d", + __func__, periph_id); + return -1; + } + main = main - 1; + fine = fine - 1; + + switch (periph_id) { + case PERIPH_ID_SPI0: + reg = &clk->div_peric1; + shift = 20; + pre_reg = &clk->div_peric4; + pre_shift = 8; + break; + case PERIPH_ID_SPI1: + reg = &clk->div_peric1; + shift = 24; + pre_reg = &clk->div_peric4; + pre_shift = 16; + break; + case PERIPH_ID_SPI2: + reg = &clk->div_peric1; + shift = 28; + pre_reg = &clk->div_peric4; + pre_shift = 24; + break; + case PERIPH_ID_SPI3: + reg = &clk->div_isp1; + shift = 16; + pre_reg = &clk->div_isp1; + pre_shift = 0; + break; + case PERIPH_ID_SPI4: + reg = &clk->div_isp1; + shift = 20; + pre_reg = &clk->div_isp1; + pre_shift = 8; + break; + default: + debug("%s: Unsupported peripheral ID %d\n", __func__, + periph_id); + return -1; + } + + clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift); + clrsetbits_le32(pre_reg, pre_div_mask << pre_shift, + (fine & pre_div_mask) << pre_shift); + + return 0; +} + +static unsigned long exynos4_get_i2c_clk(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + unsigned long sclk, aclk_100; + unsigned int ratio; + + sclk = get_pll_clk(APLL); + + ratio = (readl(&clk->div_top)) >> 4; + ratio &= 0xf; + aclk_100 = sclk / (ratio + 1); + return aclk_100; +} + +unsigned long get_pll_clk(int pllreg) +{ + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + return exynos542x_get_pll_clk(pllreg); + return exynos5_get_pll_clk(pllreg); + } else { + if (proid_is_exynos4412()) + return exynos4x12_get_pll_clk(pllreg); + return exynos4_get_pll_clk(pllreg); + } +} + +unsigned long get_arm_clk(void) +{ + if (cpu_is_exynos5()) + return exynos5_get_arm_clk(); + else { + if (proid_is_exynos4412()) + return exynos4x12_get_arm_clk(); + return exynos4_get_arm_clk(); + } +} + +unsigned long get_i2c_clk(void) +{ + if (cpu_is_exynos5()) { + return clock_get_periph_rate(PERIPH_ID_I2C0); + } else if (cpu_is_exynos4()) { + return exynos4_get_i2c_clk(); + } else { + debug("I2C clock is not set for this CPU\n"); + return 0; + } +} + +unsigned long get_pwm_clk(void) +{ + if (cpu_is_exynos5()) { + return clock_get_periph_rate(PERIPH_ID_PWM0); + } else { + if (proid_is_exynos4412()) + return exynos4x12_get_pwm_clk(); + return exynos4_get_pwm_clk(); + } +} + +unsigned long get_uart_clk(int dev_index) +{ + enum periph_id id; + + switch (dev_index) { + case 0: + id = PERIPH_ID_UART0; + break; + case 1: + id = PERIPH_ID_UART1; + break; + case 2: + id = PERIPH_ID_UART2; + break; + case 3: + id = PERIPH_ID_UART3; + break; + default: + debug("%s: invalid UART index %d", __func__, dev_index); + return -1; + } + + if (cpu_is_exynos5()) { + return clock_get_periph_rate(id); + } else { + if (proid_is_exynos4412()) + return exynos4x12_get_uart_clk(dev_index); + return exynos4_get_uart_clk(dev_index); + } +} + +unsigned long get_mmc_clk(int dev_index) +{ + enum periph_id id; + + switch (dev_index) { + case 0: + id = PERIPH_ID_SDMMC0; + break; + case 1: + id = PERIPH_ID_SDMMC1; + break; + case 2: + id = PERIPH_ID_SDMMC2; + break; + case 3: + id = PERIPH_ID_SDMMC3; + break; + default: + debug("%s: invalid MMC index %d", __func__, dev_index); + return -1; + } + + if (cpu_is_exynos5()) { + return clock_get_periph_rate(id); + } else { + return exynos4_get_mmc_clk(dev_index); + } +} + +void set_mmc_clk(int dev_index, unsigned int div) +{ + /* If want to set correct value, it needs to substract one from div.*/ + if (div > 0) + div -= 1; + + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + exynos5420_set_mmc_clk(dev_index, div); + else + exynos5_set_mmc_clk(dev_index, div); + } else { + exynos4_set_mmc_clk(dev_index, div); + } +} + +unsigned long get_lcd_clk(void) +{ + if (cpu_is_exynos4()) + return exynos4_get_lcd_clk(); + else { + if (proid_is_exynos5420()) + return exynos5420_get_lcd_clk(); + else if (proid_is_exynos5800()) + return exynos5800_get_lcd_clk(); + else + return exynos5_get_lcd_clk(); + } +} + +void set_lcd_clk(void) +{ + if (cpu_is_exynos4()) + exynos4_set_lcd_clk(); + else { + if (proid_is_exynos5250()) + exynos5_set_lcd_clk(); + else if (proid_is_exynos5420()) + exynos5420_set_lcd_clk(); + else + exynos5800_set_lcd_clk(); + } +} + +void set_mipi_clk(void) +{ + if (cpu_is_exynos4()) + exynos4_set_mipi_clk(); +} + +int set_spi_clk(int periph_id, unsigned int rate) +{ + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + return exynos5420_set_spi_clk(periph_id, rate); + return exynos5_set_spi_clk(periph_id, rate); + } else { + return 0; + } +} + +int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq, + unsigned int i2s_id) +{ + if (cpu_is_exynos5()) + return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id); + else + return 0; +} + +int set_i2s_clk_source(unsigned int i2s_id) +{ + if (cpu_is_exynos5()) + return exynos5_set_i2s_clk_source(i2s_id); + else + return 0; +} + +int set_epll_clk(unsigned long rate) +{ + if (cpu_is_exynos5()) + return exynos5_set_epll_clk(rate); + else + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init.h b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init.h new file mode 100644 index 0000000..fce502f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init.h
@@ -0,0 +1,158 @@ +/* + * Clock initialization routines + * + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __EXYNOS_CLOCK_INIT_H +#define __EXYNOS_CLOCK_INIT_H + +enum { +#ifdef CONFIG_EXYNOS5420 + MEM_TIMINGS_MSR_COUNT = 5, +#else + MEM_TIMINGS_MSR_COUNT = 4, +#endif +}; + +/* These are the ratio's for configuring ARM clock */ +struct arm_clk_ratios { + unsigned arm_freq_mhz; /* Frequency of ARM core in MHz */ + + unsigned apll_mdiv; + unsigned apll_pdiv; + unsigned apll_sdiv; + + unsigned arm2_ratio; + unsigned apll_ratio; + unsigned pclk_dbg_ratio; + unsigned atb_ratio; + unsigned periph_ratio; + unsigned acp_ratio; + unsigned cpud_ratio; + unsigned arm_ratio; +}; + +/* These are the memory timings for a particular memory type and speed */ +struct mem_timings { + enum mem_manuf mem_manuf; /* Memory manufacturer */ + enum ddr_mode mem_type; /* Memory type */ + unsigned frequency_mhz; /* Frequency of memory in MHz */ + + /* Here follow the timing parameters for the selected memory */ + unsigned apll_mdiv; + unsigned apll_pdiv; + unsigned apll_sdiv; + unsigned mpll_mdiv; + unsigned mpll_pdiv; + unsigned mpll_sdiv; + unsigned cpll_mdiv; + unsigned cpll_pdiv; + unsigned cpll_sdiv; + unsigned gpll_mdiv; + unsigned gpll_pdiv; + unsigned gpll_sdiv; + unsigned epll_mdiv; + unsigned epll_pdiv; + unsigned epll_sdiv; + unsigned vpll_mdiv; + unsigned vpll_pdiv; + unsigned vpll_sdiv; + unsigned bpll_mdiv; + unsigned bpll_pdiv; + unsigned bpll_sdiv; + unsigned kpll_mdiv; + unsigned kpll_pdiv; + unsigned kpll_sdiv; + unsigned dpll_mdiv; + unsigned dpll_pdiv; + unsigned dpll_sdiv; + unsigned ipll_mdiv; + unsigned ipll_pdiv; + unsigned ipll_sdiv; + unsigned spll_mdiv; + unsigned spll_pdiv; + unsigned spll_sdiv; + unsigned rpll_mdiv; + unsigned rpll_pdiv; + unsigned rpll_sdiv; + unsigned pclk_cdrex_ratio; + unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; + + unsigned timing_ref; + unsigned timing_row; + unsigned timing_data; + unsigned timing_power; + + /* DQS, DQ, DEBUG offsets */ + unsigned phy0_dqs; + unsigned phy1_dqs; + unsigned phy0_dq; + unsigned phy1_dq; + unsigned phy0_tFS; + unsigned phy1_tFS; + unsigned phy0_pulld_dqs; + unsigned phy1_pulld_dqs; + + unsigned lpddr3_ctrl_phy_reset; + unsigned ctrl_start_point; + unsigned ctrl_inc; + unsigned ctrl_start; + unsigned ctrl_dll_on; + unsigned ctrl_ref; + + unsigned ctrl_force; + unsigned ctrl_rdlat; + unsigned ctrl_bstlen; + + unsigned fp_resync; + unsigned iv_size; + unsigned dfi_init_start; + unsigned aref_en; + + unsigned rd_fetch; + + unsigned zq_mode_dds; + unsigned zq_mode_term; + unsigned zq_mode_noterm; /* 1 to allow termination disable */ + + unsigned memcontrol; + unsigned memconfig; + + unsigned membaseconfig0; + unsigned membaseconfig1; + unsigned prechconfig_tp_cnt; + unsigned dpwrdn_cyc; + unsigned dsref_cyc; + unsigned concontrol; + /* Channel and Chip Selection */ + uint8_t dmc_channels; /* number of memory channels */ + uint8_t chips_per_channel; /* number of chips per channel */ + uint8_t chips_to_configure; /* number of chips to configure */ + uint8_t send_zq_init; /* 1 to send this command */ + unsigned impedance; /* drive strength impedeance */ + uint8_t gate_leveling_enable; /* check gate leveling is enabled */ + uint8_t read_leveling_enable; /* check h/w read leveling is enabled */ +}; + +/** + * Get the correct memory timings for our selected memory type and speed. + * + * This function can be called from SPL or the main U-Boot. + * + * @return pointer to the memory timings that we should use + */ +struct mem_timings *clock_get_mem_timings(void); + +/* + * Initialize clock for the device + */ +void system_clock_init(void); + +/* + * Set clock divisor value for booting from EMMC. + */ +void emmc_boot_clk_div_set(void); +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos4.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos4.c new file mode 100644 index 0000000..584e4ba --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos4.c
@@ -0,0 +1,94 @@ +/* + * Clock Initialization for board based on EXYNOS4210 + * + * Copyright (C) 2013 Samsung Electronics + * Rajeshwari Shinde <rajeshwari.s@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 <config.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include "common_setup.h" +#include "exynos4_setup.h" + +/* + * system_clock_init: Initialize core clock and bus clock. + * void system_clock_init(void) + */ +void system_clock_init(void) +{ + struct exynos4_clock *clk = + (struct exynos4_clock *)samsung_get_base_clock(); + + writel(CLK_SRC_CPU_VAL, &clk->src_cpu); + + sdelay(0x10000); + + writel(CLK_SRC_TOP0_VAL, &clk->src_top0); + writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + writel(CLK_SRC_DMC_VAL, &clk->src_dmc); + writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus); + writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus); + writel(CLK_SRC_FSYS_VAL, &clk->src_fsys); + writel(CLK_SRC_PERIL0_VAL, &clk->src_peril0); + writel(CLK_SRC_CAM_VAL, &clk->src_cam); + writel(CLK_SRC_MFC_VAL, &clk->src_mfc); + writel(CLK_SRC_G3D_VAL, &clk->src_g3d); + writel(CLK_SRC_LCD0_VAL, &clk->src_lcd0); + + sdelay(0x10000); + + writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); + writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); + writel(CLK_DIV_DMC0_VAL, &clk->div_dmc0); + writel(CLK_DIV_DMC1_VAL, &clk->div_dmc1); + writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus); + writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus); + writel(CLK_DIV_TOP_VAL, &clk->div_top); + writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1); + writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2); + writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3); + writel(CLK_DIV_PERIL0_VAL, &clk->div_peril0); + writel(CLK_DIV_CAM_VAL, &clk->div_cam); + writel(CLK_DIV_MFC_VAL, &clk->div_mfc); + writel(CLK_DIV_G3D_VAL, &clk->div_g3d); + writel(CLK_DIV_LCD0_VAL, &clk->div_lcd0); + + /* Set PLL locktime */ + writel(PLL_LOCKTIME, &clk->apll_lock); + writel(PLL_LOCKTIME, &clk->mpll_lock); + writel(PLL_LOCKTIME, &clk->epll_lock); + writel(PLL_LOCKTIME, &clk->vpll_lock); + + writel(APLL_CON1_VAL, &clk->apll_con1); + writel(APLL_CON0_VAL, &clk->apll_con0); + writel(MPLL_CON1_VAL, &clk->mpll_con1); + writel(MPLL_CON0_VAL, &clk->mpll_con0); + writel(EPLL_CON1_VAL, &clk->epll_con1); + writel(EPLL_CON0_VAL, &clk->epll_con0); + writel(VPLL_CON1_VAL, &clk->vpll_con1); + writel(VPLL_CON0_VAL, &clk->vpll_con0); + + sdelay(0x30000); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos5.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos5.c new file mode 100644 index 0000000..0200fd1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/clock_init_exynos5.c
@@ -0,0 +1,1005 @@ +/* + * Clock setup for SMDK5250 board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> +#include <asm/arch/spl.h> +#include <asm/arch/dwmmc.h> + +#include "clock_init.h" +#include "common_setup.h" +#include "exynos5_setup.h" + +#define FSYS1_MMC0_DIV_MASK 0xff0f +#define FSYS1_MMC0_DIV_VAL 0x0701 + +DECLARE_GLOBAL_DATA_PTR; + +struct arm_clk_ratios arm_clk_ratios[] = { +#ifdef CONFIG_EXYNOS5420 + { + .arm_freq_mhz = 900, + + .apll_mdiv = 0x96, + .apll_pdiv = 0x2, + .apll_sdiv = 0x1, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x6, + .atb_ratio = 0x6, + .periph_ratio = 0x7, + .acp_ratio = 0x0, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + } +#else + { + .arm_freq_mhz = 600, + + .apll_mdiv = 0xc8, + .apll_pdiv = 0x4, + .apll_sdiv = 0x1, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x2, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x1, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 800, + + .apll_mdiv = 0x64, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x3, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1000, + + .apll_mdiv = 0x7d, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x1, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x4, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x2, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1200, + + .apll_mdiv = 0x96, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x5, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1400, + + .apll_mdiv = 0xaf, + .apll_pdiv = 0x3, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x6, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + }, { + .arm_freq_mhz = 1700, + + .apll_mdiv = 0x1a9, + .apll_pdiv = 0x6, + .apll_sdiv = 0x0, + + .arm2_ratio = 0x0, + .apll_ratio = 0x3, + .pclk_dbg_ratio = 0x1, + .atb_ratio = 0x6, + .periph_ratio = 0x7, + .acp_ratio = 0x7, + .cpud_ratio = 0x3, + .arm_ratio = 0x0, + } +#endif +}; + +struct mem_timings mem_timings[] = { +#ifdef CONFIG_EXYNOS5420 + { + .mem_manuf = MEM_MANUF_SAMSUNG, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + + /* MPLL @800MHz*/ + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x1, + /* CPLL @666MHz */ + .cpll_mdiv = 0xde, + .cpll_pdiv = 0x4, + .cpll_sdiv = 0x1, + /* EPLL @600MHz */ + .epll_mdiv = 0x64, + .epll_pdiv = 0x2, + .epll_sdiv = 0x1, + /* VPLL @430MHz */ + .vpll_mdiv = 0xd7, + .vpll_pdiv = 0x3, + .vpll_sdiv = 0x2, + /* BPLL @800MHz */ + .bpll_mdiv = 0xc8, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x1, + /* KPLL @600MHz */ + .kpll_mdiv = 0x190, + .kpll_pdiv = 0x4, + .kpll_sdiv = 0x2, + /* DPLL @600MHz */ + .dpll_mdiv = 0x190, + .dpll_pdiv = 0x4, + .dpll_sdiv = 0x2, + /* IPLL @370MHz */ + .ipll_mdiv = 0xb9, + .ipll_pdiv = 0x3, + .ipll_sdiv = 0x2, + /* SPLL @400MHz */ + .spll_mdiv = 0xc8, + .spll_pdiv = 0x3, + .spll_sdiv = 0x2, + /* RPLL @141Mhz */ + .rpll_mdiv = 0x5E, + .rpll_pdiv = 0x2, + .rpll_sdiv = 0x3, + + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010046, 0x00000d70, + 0x00000c70 + }, + .timing_ref = 0x000000bb, + .timing_row = 0x6836650f, + .timing_data = 0x3630580b, + .timing_power = 0x41000a26, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .phy0_tFS = 0x8, + .phy1_tFS = 0x8, + .phy0_pulld_dqs = 0xf, + .phy1_pulld_dqs = 0xf, + + .lpddr3_ctrl_phy_reset = 0x1, + .ctrl_start_point = 0x10, + .ctrl_inc = 0x10, + .ctrl_start = 0x1, + .ctrl_dll_on = 0x1, + .ctrl_ref = 0x8, + + .ctrl_force = 0x1a, + .ctrl_rdlat = 0x0b, + .ctrl_bstlen = 0x08, + + .fp_resync = 0x8, + .iv_size = 0x7, + .dfi_init_start = 1, + .aref_en = 1, + + .rd_fetch = 0x3, + + .zq_mode_dds = 0x7, + .zq_mode_term = 0x1, + .zq_mode_noterm = 1, + + /* + * Dynamic Clock: Always Running + * Memory Burst length: 8 + * Number of chips: 1 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 0 Cycle + */ + .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | + DMC_MEMCONTROL_DPWRDN_DISABLE | + DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | + DMC_MEMCONTROL_TP_DISABLE | + DMC_MEMCONTROL_DSREF_DISABLE | + DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | + DMC_MEMCONTROL_MEM_TYPE_DDR3 | + DMC_MEMCONTROL_MEM_WIDTH_32BIT | + DMC_MEMCONTROL_NUM_CHIP_1 | + DMC_MEMCONTROL_BL_8 | + DMC_MEMCONTROL_PZQ_DISABLE | + DMC_MEMCONTROL_MRR_BYTE_7_0, + .memconfig = DMC_MEMCONFIG_CHIP_MAP_SPLIT | + DMC_MEMCONFIGX_CHIP_COL_10 | + DMC_MEMCONFIGX_CHIP_ROW_15 | + DMC_MEMCONFIGX_CHIP_BANK_8, + .prechconfig_tp_cnt = 0xff, + .dpwrdn_cyc = 0xff, + .dsref_cyc = 0xffff, + .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | + DMC_CONCONTROL_TIMEOUT_LEVEL0 | + DMC_CONCONTROL_RD_FETCH_DISABLE | + DMC_CONCONTROL_EMPTY_DISABLE | + DMC_CONCONTROL_AREF_EN_DISABLE | + DMC_CONCONTROL_IO_PD_CON_DISABLE, + .dmc_channels = 1, + .chips_per_channel = 1, + .chips_to_configure = 1, + .send_zq_init = 1, + .gate_leveling_enable = 1, + .read_leveling_enable = 0, + } +#else + { + .mem_manuf = MEM_MANUF_ELPIDA, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x0, + .cpll_mdiv = 0xde, + .cpll_pdiv = 0x4, + .cpll_sdiv = 0x2, + .gpll_mdiv = 0x215, + .gpll_pdiv = 0xc, + .gpll_sdiv = 0x1, + .epll_mdiv = 0x60, + .epll_pdiv = 0x3, + .epll_sdiv = 0x3, + .vpll_mdiv = 0x96, + .vpll_pdiv = 0x3, + .vpll_sdiv = 0x2, + + .bpll_mdiv = 0x64, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x0, + .pclk_cdrex_ratio = 0x5, + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010042, 0x00000d70 + }, + .timing_ref = 0x000000bb, + .timing_row = 0x8c36650e, + .timing_data = 0x3630580b, + .timing_power = 0x41000a44, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .phy0_tFS = 0x4, + .phy1_tFS = 0x4, + .phy0_pulld_dqs = 0xf, + .phy1_pulld_dqs = 0xf, + + .lpddr3_ctrl_phy_reset = 0x1, + .ctrl_start_point = 0x10, + .ctrl_inc = 0x10, + .ctrl_start = 0x1, + .ctrl_dll_on = 0x1, + .ctrl_ref = 0x8, + + .ctrl_force = 0x1a, + .ctrl_rdlat = 0x0b, + .ctrl_bstlen = 0x08, + + .fp_resync = 0x8, + .iv_size = 0x7, + .dfi_init_start = 1, + .aref_en = 1, + + .rd_fetch = 0x3, + + .zq_mode_dds = 0x7, + .zq_mode_term = 0x1, + .zq_mode_noterm = 0, + + /* + * Dynamic Clock: Always Running + * Memory Burst length: 8 + * Number of chips: 1 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 0 Cycle + */ + .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | + DMC_MEMCONTROL_DPWRDN_DISABLE | + DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | + DMC_MEMCONTROL_TP_DISABLE | + DMC_MEMCONTROL_DSREF_ENABLE | + DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | + DMC_MEMCONTROL_MEM_TYPE_DDR3 | + DMC_MEMCONTROL_MEM_WIDTH_32BIT | + DMC_MEMCONTROL_NUM_CHIP_1 | + DMC_MEMCONTROL_BL_8 | + DMC_MEMCONTROL_PZQ_DISABLE | + DMC_MEMCONTROL_MRR_BYTE_7_0, + .memconfig = DMC_MEMCONFIGX_CHIP_MAP_INTERLEAVED | + DMC_MEMCONFIGX_CHIP_COL_10 | + DMC_MEMCONFIGX_CHIP_ROW_15 | + DMC_MEMCONFIGX_CHIP_BANK_8, + .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40), + .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80), + .prechconfig_tp_cnt = 0xff, + .dpwrdn_cyc = 0xff, + .dsref_cyc = 0xffff, + .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | + DMC_CONCONTROL_TIMEOUT_LEVEL0 | + DMC_CONCONTROL_RD_FETCH_DISABLE | + DMC_CONCONTROL_EMPTY_DISABLE | + DMC_CONCONTROL_AREF_EN_DISABLE | + DMC_CONCONTROL_IO_PD_CON_DISABLE, + .dmc_channels = 2, + .chips_per_channel = 2, + .chips_to_configure = 1, + .send_zq_init = 1, + .impedance = IMP_OUTPUT_DRV_30_OHM, + .gate_leveling_enable = 0, + }, { + .mem_manuf = MEM_MANUF_SAMSUNG, + .mem_type = DDR_MODE_DDR3, + .frequency_mhz = 800, + .mpll_mdiv = 0xc8, + .mpll_pdiv = 0x3, + .mpll_sdiv = 0x0, + .cpll_mdiv = 0xde, + .cpll_pdiv = 0x4, + .cpll_sdiv = 0x2, + .gpll_mdiv = 0x215, + .gpll_pdiv = 0xc, + .gpll_sdiv = 0x1, + .epll_mdiv = 0x60, + .epll_pdiv = 0x3, + .epll_sdiv = 0x3, + .vpll_mdiv = 0x96, + .vpll_pdiv = 0x3, + .vpll_sdiv = 0x2, + + .bpll_mdiv = 0x64, + .bpll_pdiv = 0x3, + .bpll_sdiv = 0x0, + .pclk_cdrex_ratio = 0x5, + .direct_cmd_msr = { + 0x00020018, 0x00030000, 0x00010000, 0x00000d70 + }, + .timing_ref = 0x000000bb, + .timing_row = 0x8c36650e, + .timing_data = 0x3630580b, + .timing_power = 0x41000a44, + .phy0_dqs = 0x08080808, + .phy1_dqs = 0x08080808, + .phy0_dq = 0x08080808, + .phy1_dq = 0x08080808, + .phy0_tFS = 0x8, + .phy1_tFS = 0x8, + .phy0_pulld_dqs = 0xf, + .phy1_pulld_dqs = 0xf, + + .lpddr3_ctrl_phy_reset = 0x1, + .ctrl_start_point = 0x10, + .ctrl_inc = 0x10, + .ctrl_start = 0x1, + .ctrl_dll_on = 0x1, + .ctrl_ref = 0x8, + + .ctrl_force = 0x1a, + .ctrl_rdlat = 0x0b, + .ctrl_bstlen = 0x08, + + .fp_resync = 0x8, + .iv_size = 0x7, + .dfi_init_start = 1, + .aref_en = 1, + + .rd_fetch = 0x3, + + .zq_mode_dds = 0x5, + .zq_mode_term = 0x1, + .zq_mode_noterm = 1, + + /* + * Dynamic Clock: Always Running + * Memory Burst length: 8 + * Number of chips: 1 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 0 Cycle + */ + .memcontrol = DMC_MEMCONTROL_CLK_STOP_DISABLE | + DMC_MEMCONTROL_DPWRDN_DISABLE | + DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE | + DMC_MEMCONTROL_TP_DISABLE | + DMC_MEMCONTROL_DSREF_ENABLE | + DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(0) | + DMC_MEMCONTROL_MEM_TYPE_DDR3 | + DMC_MEMCONTROL_MEM_WIDTH_32BIT | + DMC_MEMCONTROL_NUM_CHIP_1 | + DMC_MEMCONTROL_BL_8 | + DMC_MEMCONTROL_PZQ_DISABLE | + DMC_MEMCONTROL_MRR_BYTE_7_0, + .memconfig = DMC_MEMCONFIGX_CHIP_MAP_INTERLEAVED | + DMC_MEMCONFIGX_CHIP_COL_10 | + DMC_MEMCONFIGX_CHIP_ROW_15 | + DMC_MEMCONFIGX_CHIP_BANK_8, + .membaseconfig0 = DMC_MEMBASECONFIG_VAL(0x40), + .membaseconfig1 = DMC_MEMBASECONFIG_VAL(0x80), + .prechconfig_tp_cnt = 0xff, + .dpwrdn_cyc = 0xff, + .dsref_cyc = 0xffff, + .concontrol = DMC_CONCONTROL_DFI_INIT_START_DISABLE | + DMC_CONCONTROL_TIMEOUT_LEVEL0 | + DMC_CONCONTROL_RD_FETCH_DISABLE | + DMC_CONCONTROL_EMPTY_DISABLE | + DMC_CONCONTROL_AREF_EN_DISABLE | + DMC_CONCONTROL_IO_PD_CON_DISABLE, + .dmc_channels = 2, + .chips_per_channel = 2, + .chips_to_configure = 1, + .send_zq_init = 1, + .impedance = IMP_OUTPUT_DRV_40_OHM, + .gate_leveling_enable = 1, + } +#endif +}; + +/** + * Get the required memory type and speed (SPL version). + * + * In SPL we have no device tree, so we use the machine parameters + * + * @param mem_type Returns memory type + * @param frequency_mhz Returns memory speed in MHz + * @param arm_freq Returns ARM clock speed in MHz + * @param mem_manuf Return Memory Manufacturer name + */ +static void clock_get_mem_selection(enum ddr_mode *mem_type, + unsigned *frequency_mhz, unsigned *arm_freq, + enum mem_manuf *mem_manuf) +{ + struct spl_machine_param *params; + + params = spl_get_machine_params(); + *mem_type = params->mem_type; + *frequency_mhz = params->frequency_mhz; + *arm_freq = params->arm_freq_mhz; + *mem_manuf = params->mem_manuf; +} + +/* Get the ratios for setting ARM clock */ +struct arm_clk_ratios *get_arm_ratios(void) +{ + struct arm_clk_ratios *arm_ratio; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf); + + for (i = 0, arm_ratio = arm_clk_ratios; i < ARRAY_SIZE(arm_clk_ratios); + i++, arm_ratio++) { + if (arm_ratio->arm_freq_mhz == arm_freq) + return arm_ratio; + } + + /* will hang if failed to find clock ratio */ + while (1) + ; + + return NULL; +} + +struct mem_timings *clock_get_mem_timings(void) +{ + struct mem_timings *mem; + enum ddr_mode mem_type; + enum mem_manuf mem_manuf; + unsigned frequency_mhz, arm_freq; + int i; + + clock_get_mem_selection(&mem_type, &frequency_mhz, + &arm_freq, &mem_manuf); + for (i = 0, mem = mem_timings; i < ARRAY_SIZE(mem_timings); + i++, mem++) { + if (mem->mem_type == mem_type && + mem->frequency_mhz == frequency_mhz && + mem->mem_manuf == mem_manuf) + return mem; + } + + /* will hang if failed to find memory timings */ + while (1) + ; + + return NULL; +} + +static void exynos5250_system_clock_init(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + struct mem_timings *mem; + struct arm_clk_ratios *arm_clk_ratio; + u32 val, tmp; + + mem = clock_get_mem_timings(); + arm_clk_ratio = get_arm_ratios(); + + clrbits_le32(&clk->src_cpu, MUX_APLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_cpu); + } while ((val | MUX_APLL_SEL_MASK) != val); + + clrbits_le32(&clk->src_core1, MUX_MPLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_core1); + } while ((val | MUX_MPLL_SEL_MASK) != val); + + clrbits_le32(&clk->src_top2, MUX_CPLL_SEL_MASK); + clrbits_le32(&clk->src_top2, MUX_EPLL_SEL_MASK); + clrbits_le32(&clk->src_top2, MUX_VPLL_SEL_MASK); + clrbits_le32(&clk->src_top2, MUX_GPLL_SEL_MASK); + tmp = MUX_CPLL_SEL_MASK | MUX_EPLL_SEL_MASK | MUX_VPLL_SEL_MASK + | MUX_GPLL_SEL_MASK; + do { + val = readl(&clk->mux_stat_top2); + } while ((val | tmp) != val); + + clrbits_le32(&clk->src_cdrex, MUX_BPLL_SEL_MASK); + do { + val = readl(&clk->mux_stat_cdrex); + } while ((val | MUX_BPLL_SEL_MASK) != val); + + /* PLL locktime */ + writel(mem->apll_pdiv * PLL_LOCK_FACTOR, &clk->apll_lock); + writel(mem->mpll_pdiv * PLL_LOCK_FACTOR, &clk->mpll_lock); + writel(mem->bpll_pdiv * PLL_LOCK_FACTOR, &clk->bpll_lock); + writel(mem->cpll_pdiv * PLL_LOCK_FACTOR, &clk->cpll_lock); + writel(mem->gpll_pdiv * PLL_X_LOCK_FACTOR, &clk->gpll_lock); + writel(mem->epll_pdiv * PLL_X_LOCK_FACTOR, &clk->epll_lock); + writel(mem->vpll_pdiv * PLL_X_LOCK_FACTOR, &clk->vpll_lock); + + writel(CLK_REG_DISABLE, &clk->pll_div2_sel); + + writel(MUX_HPM_SEL_MASK, &clk->src_cpu); + do { + val = readl(&clk->mux_stat_cpu); + } while ((val | HPM_SEL_SCLK_MPLL) != val); + + val = arm_clk_ratio->arm2_ratio << 28 + | arm_clk_ratio->apll_ratio << 24 + | arm_clk_ratio->pclk_dbg_ratio << 20 + | arm_clk_ratio->atb_ratio << 16 + | arm_clk_ratio->periph_ratio << 12 + | arm_clk_ratio->acp_ratio << 8 + | arm_clk_ratio->cpud_ratio << 4 + | arm_clk_ratio->arm_ratio; + writel(val, &clk->div_cpu0); + do { + val = readl(&clk->div_stat_cpu0); + } while (0 != val); + + writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1); + do { + val = readl(&clk->div_stat_cpu1); + } while (0 != val); + + /* Set APLL */ + writel(APLL_CON1_VAL, &clk->apll_con1); + val = set_pll(arm_clk_ratio->apll_mdiv, arm_clk_ratio->apll_pdiv, + arm_clk_ratio->apll_sdiv); + writel(val, &clk->apll_con0); + while ((readl(&clk->apll_con0) & APLL_CON0_LOCKED) == 0) + ; + + /* Set MPLL */ + writel(MPLL_CON1_VAL, &clk->mpll_con1); + val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv); + writel(val, &clk->mpll_con0); + while ((readl(&clk->mpll_con0) & MPLL_CON0_LOCKED) == 0) + ; + + /* Set BPLL */ + writel(BPLL_CON1_VAL, &clk->bpll_con1); + val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv); + writel(val, &clk->bpll_con0); + while ((readl(&clk->bpll_con0) & BPLL_CON0_LOCKED) == 0) + ; + + /* Set CPLL */ + writel(CPLL_CON1_VAL, &clk->cpll_con1); + val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv); + writel(val, &clk->cpll_con0); + while ((readl(&clk->cpll_con0) & CPLL_CON0_LOCKED) == 0) + ; + + /* Set GPLL */ + writel(GPLL_CON1_VAL, &clk->gpll_con1); + val = set_pll(mem->gpll_mdiv, mem->gpll_pdiv, mem->gpll_sdiv); + writel(val, &clk->gpll_con0); + while ((readl(&clk->gpll_con0) & GPLL_CON0_LOCKED) == 0) + ; + + /* Set EPLL */ + writel(EPLL_CON2_VAL, &clk->epll_con2); + writel(EPLL_CON1_VAL, &clk->epll_con1); + val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv); + writel(val, &clk->epll_con0); + while ((readl(&clk->epll_con0) & EPLL_CON0_LOCKED) == 0) + ; + + /* Set VPLL */ + writel(VPLL_CON2_VAL, &clk->vpll_con2); + writel(VPLL_CON1_VAL, &clk->vpll_con1); + val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv); + writel(val, &clk->vpll_con0); + while ((readl(&clk->vpll_con0) & VPLL_CON0_LOCKED) == 0) + ; + + writel(CLK_SRC_CORE0_VAL, &clk->src_core0); + writel(CLK_DIV_CORE0_VAL, &clk->div_core0); + while (readl(&clk->div_stat_core0) != 0) + ; + + writel(CLK_DIV_CORE1_VAL, &clk->div_core1); + while (readl(&clk->div_stat_core1) != 0) + ; + + writel(CLK_DIV_SYSRGT_VAL, &clk->div_sysrgt); + while (readl(&clk->div_stat_sysrgt) != 0) + ; + + writel(CLK_DIV_ACP_VAL, &clk->div_acp); + while (readl(&clk->div_stat_acp) != 0) + ; + + writel(CLK_DIV_SYSLFT_VAL, &clk->div_syslft); + while (readl(&clk->div_stat_syslft) != 0) + ; + + writel(CLK_SRC_TOP0_VAL, &clk->src_top0); + writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + writel(TOP2_VAL, &clk->src_top2); + writel(CLK_SRC_TOP3_VAL, &clk->src_top3); + + writel(CLK_DIV_TOP0_VAL, &clk->div_top0); + while (readl(&clk->div_stat_top0)) + ; + + writel(CLK_DIV_TOP1_VAL, &clk->div_top1); + while (readl(&clk->div_stat_top1)) + ; + + writel(CLK_SRC_LEX_VAL, &clk->src_lex); + while (1) { + val = readl(&clk->mux_stat_lex); + if (val == (val | 1)) + break; + } + + writel(CLK_DIV_LEX_VAL, &clk->div_lex); + while (readl(&clk->div_stat_lex)) + ; + + writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + while (readl(&clk->div_stat_r0x)) + ; + + writel(CLK_DIV_R0X_VAL, &clk->div_r0x); + while (readl(&clk->div_stat_r0x)) + ; + + writel(CLK_DIV_R1X_VAL, &clk->div_r1x); + while (readl(&clk->div_stat_r1x)) + ; + + writel(CLK_REG_DISABLE, &clk->src_cdrex); + + writel(CLK_DIV_CDREX_VAL, &clk->div_cdrex); + while (readl(&clk->div_stat_cdrex)) + ; + + val = readl(&clk->src_cpu); + val |= CLK_SRC_CPU_VAL; + writel(val, &clk->src_cpu); + + val = readl(&clk->src_top2); + val |= CLK_SRC_TOP2_VAL; + writel(val, &clk->src_top2); + + val = readl(&clk->src_core1); + val |= CLK_SRC_CORE1_VAL; + writel(val, &clk->src_core1); + + writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys); + writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); + while (readl(&clk->div_stat_fsys0)) + ; + + writel(CLK_REG_DISABLE, &clk->clkout_cmu_cpu); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_core); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_acp); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_top); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_lex); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_r0x); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_r1x); + writel(CLK_REG_DISABLE, &clk->clkout_cmu_cdrex); + + writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); + writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); + + writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1); + writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1); + writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2); + writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3); + + writel(SCLK_SRC_ISP_VAL, &clk->sclk_src_isp); + writel(SCLK_DIV_ISP_VAL, &clk->sclk_div_isp); + writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); + writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); + writel(CLK_DIV_ISP2_VAL, &clk->div_isp2); + + /* FIMD1 SRC CLK SELECTION */ + writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp1_0); + + val = MMC2_PRE_RATIO_VAL << MMC2_PRE_RATIO_OFFSET + | MMC2_RATIO_VAL << MMC2_RATIO_OFFSET + | MMC3_PRE_RATIO_VAL << MMC3_PRE_RATIO_OFFSET + | MMC3_RATIO_VAL << MMC3_RATIO_OFFSET; + writel(val, &clk->div_fsys2); +} + +static void exynos5420_system_clock_init(void) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + struct mem_timings *mem; + struct arm_clk_ratios *arm_clk_ratio; + u32 val; + + mem = clock_get_mem_timings(); + arm_clk_ratio = get_arm_ratios(); + + /* PLL locktime */ + writel(arm_clk_ratio->apll_pdiv * PLL_LOCK_FACTOR, &clk->apll_lock); + writel(mem->mpll_pdiv * PLL_LOCK_FACTOR, &clk->mpll_lock); + writel(mem->bpll_pdiv * PLL_LOCK_FACTOR, &clk->bpll_lock); + writel(mem->cpll_pdiv * PLL_LOCK_FACTOR, &clk->cpll_lock); + writel(mem->dpll_pdiv * PLL_LOCK_FACTOR, &clk->dpll_lock); + writel(mem->epll_pdiv * PLL_X_LOCK_FACTOR, &clk->epll_lock); + writel(mem->vpll_pdiv * PLL_LOCK_FACTOR, &clk->vpll_lock); + writel(mem->ipll_pdiv * PLL_LOCK_FACTOR, &clk->ipll_lock); + writel(mem->spll_pdiv * PLL_LOCK_FACTOR, &clk->spll_lock); + writel(mem->kpll_pdiv * PLL_LOCK_FACTOR, &clk->kpll_lock); + writel(mem->rpll_pdiv * PLL_X_LOCK_FACTOR, &clk->rpll_lock); + + setbits_le32(&clk->src_cpu, MUX_HPM_SEL_MASK); + + writel(0, &clk->src_top6); + + writel(0, &clk->src_cdrex); + writel(SRC_KFC_HPM_SEL, &clk->src_kfc); + writel(HPM_RATIO, &clk->div_cpu1); + writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0); + + /* switch A15 clock source to OSC clock before changing APLL */ + clrbits_le32(&clk->src_cpu, APLL_FOUT); + + /* Set APLL */ + writel(APLL_CON1_VAL, &clk->apll_con1); + val = set_pll(arm_clk_ratio->apll_mdiv, + arm_clk_ratio->apll_pdiv, + arm_clk_ratio->apll_sdiv); + writel(val, &clk->apll_con0); + while ((readl(&clk->apll_con0) & PLL_LOCKED) == 0) + ; + + /* now it is safe to switch to APLL */ + setbits_le32(&clk->src_cpu, APLL_FOUT); + + writel(SRC_KFC_HPM_SEL, &clk->src_kfc); + writel(CLK_DIV_KFC_VAL, &clk->div_kfc0); + + /* switch A7 clock source to OSC clock before changing KPLL */ + clrbits_le32(&clk->src_kfc, KPLL_FOUT); + + /* Set KPLL*/ + writel(KPLL_CON1_VAL, &clk->kpll_con1); + val = set_pll(mem->kpll_mdiv, mem->kpll_pdiv, mem->kpll_sdiv); + writel(val, &clk->kpll_con0); + while ((readl(&clk->kpll_con0) & PLL_LOCKED) == 0) + ; + + /* now it is safe to switch to KPLL */ + setbits_le32(&clk->src_kfc, KPLL_FOUT); + + /* Set MPLL */ + writel(MPLL_CON1_VAL, &clk->mpll_con1); + val = set_pll(mem->mpll_mdiv, mem->mpll_pdiv, mem->mpll_sdiv); + writel(val, &clk->mpll_con0); + while ((readl(&clk->mpll_con0) & PLL_LOCKED) == 0) + ; + + /* Set DPLL */ + writel(DPLL_CON1_VAL, &clk->dpll_con1); + val = set_pll(mem->dpll_mdiv, mem->dpll_pdiv, mem->dpll_sdiv); + writel(val, &clk->dpll_con0); + while ((readl(&clk->dpll_con0) & PLL_LOCKED) == 0) + ; + + /* Set EPLL */ + writel(EPLL_CON2_VAL, &clk->epll_con2); + writel(EPLL_CON1_VAL, &clk->epll_con1); + val = set_pll(mem->epll_mdiv, mem->epll_pdiv, mem->epll_sdiv); + writel(val, &clk->epll_con0); + while ((readl(&clk->epll_con0) & PLL_LOCKED) == 0) + ; + + /* Set CPLL */ + writel(CPLL_CON1_VAL, &clk->cpll_con1); + val = set_pll(mem->cpll_mdiv, mem->cpll_pdiv, mem->cpll_sdiv); + writel(val, &clk->cpll_con0); + while ((readl(&clk->cpll_con0) & PLL_LOCKED) == 0) + ; + + /* Set IPLL */ + writel(IPLL_CON1_VAL, &clk->ipll_con1); + val = set_pll(mem->ipll_mdiv, mem->ipll_pdiv, mem->ipll_sdiv); + writel(val, &clk->ipll_con0); + while ((readl(&clk->ipll_con0) & PLL_LOCKED) == 0) + ; + + /* Set VPLL */ + writel(VPLL_CON1_VAL, &clk->vpll_con1); + val = set_pll(mem->vpll_mdiv, mem->vpll_pdiv, mem->vpll_sdiv); + writel(val, &clk->vpll_con0); + while ((readl(&clk->vpll_con0) & PLL_LOCKED) == 0) + ; + + /* Set BPLL */ + writel(BPLL_CON1_VAL, &clk->bpll_con1); + val = set_pll(mem->bpll_mdiv, mem->bpll_pdiv, mem->bpll_sdiv); + writel(val, &clk->bpll_con0); + while ((readl(&clk->bpll_con0) & PLL_LOCKED) == 0) + ; + + /* Set SPLL */ + writel(SPLL_CON1_VAL, &clk->spll_con1); + val = set_pll(mem->spll_mdiv, mem->spll_pdiv, mem->spll_sdiv); + writel(val, &clk->spll_con0); + while ((readl(&clk->spll_con0) & PLL_LOCKED) == 0) + ; + + /* Set RPLL */ + writel(RPLL_CON2_VAL, &clk->rpll_con2); + writel(RPLL_CON1_VAL, &clk->rpll_con1); + val = set_pll(mem->rpll_mdiv, mem->rpll_pdiv, mem->rpll_sdiv); + writel(val, &clk->rpll_con0); + while ((readl(&clk->rpll_con0) & PLL_LOCKED) == 0) + ; + + writel(CLK_DIV_CDREX0_VAL, &clk->div_cdrex0); + writel(CLK_DIV_CDREX1_VAL, &clk->div_cdrex1); + + writel(CLK_SRC_TOP0_VAL, &clk->src_top0); + writel(CLK_SRC_TOP1_VAL, &clk->src_top1); + writel(CLK_SRC_TOP2_VAL, &clk->src_top2); + writel(CLK_SRC_TOP7_VAL, &clk->src_top7); + + writel(CLK_DIV_TOP0_VAL, &clk->div_top0); + writel(CLK_DIV_TOP1_VAL, &clk->div_top1); + writel(CLK_DIV_TOP2_VAL, &clk->div_top2); + + writel(0, &clk->src_top10); + writel(0, &clk->src_top11); + writel(0, &clk->src_top12); + + writel(CLK_SRC_TOP3_VAL, &clk->src_top3); + writel(CLK_SRC_TOP4_VAL, &clk->src_top4); + writel(CLK_SRC_TOP5_VAL, &clk->src_top5); + + /* DISP1 BLK CLK SELECTION */ + writel(CLK_SRC_DISP1_0_VAL, &clk->src_disp10); + writel(CLK_DIV_DISP1_0_VAL, &clk->div_disp10); + + /* AUDIO BLK */ + writel(AUDIO0_SEL_EPLL, &clk->src_mau); + writel(DIV_MAU_VAL, &clk->div_mau); + + /* FSYS */ + writel(CLK_SRC_FSYS0_VAL, &clk->src_fsys); + writel(CLK_DIV_FSYS0_VAL, &clk->div_fsys0); + writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1); + writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2); + + writel(CLK_SRC_ISP_VAL, &clk->src_isp); + writel(CLK_DIV_ISP0_VAL, &clk->div_isp0); + writel(CLK_DIV_ISP1_VAL, &clk->div_isp1); + + writel(CLK_SRC_PERIC0_VAL, &clk->src_peric0); + writel(CLK_SRC_PERIC1_VAL, &clk->src_peric1); + + writel(CLK_DIV_PERIC0_VAL, &clk->div_peric0); + writel(CLK_DIV_PERIC1_VAL, &clk->div_peric1); + writel(CLK_DIV_PERIC2_VAL, &clk->div_peric2); + writel(CLK_DIV_PERIC3_VAL, &clk->div_peric3); + writel(CLK_DIV_PERIC4_VAL, &clk->div_peric4); + + writel(CLK_DIV_CPERI1_VAL, &clk->div_cperi1); + + writel(CLK_DIV2_RATIO, &clk->clkdiv2_ratio); + writel(CLK_DIV4_RATIO, &clk->clkdiv4_ratio); + writel(CLK_DIV_G2D, &clk->div_g2d); + + writel(CLK_SRC_TOP6_VAL, &clk->src_top6); + writel(CLK_SRC_CDREX_VAL, &clk->src_cdrex); + writel(CLK_SRC_KFC_VAL, &clk->src_kfc); +} + +void system_clock_init(void) +{ + if (proid_is_exynos5420() || proid_is_exynos5800()) + exynos5420_system_clock_init(); + else + exynos5250_system_clock_init(); +} + +void clock_init_dp_clock(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + /* DP clock enable */ + setbits_le32(&clk->gate_ip_disp1, CLK_GATE_DP1_ALLOW); + + /* We run DP at 267 Mhz */ + setbits_le32(&clk->div_disp1_0, CLK_DIV_DISP1_0_FIMD1); +} + +/* + * Set clock divisor value for booting from EMMC. + * Set DWMMC channel-0 clk div to operate mmc0 device at 50MHz. + */ +void emmc_boot_clk_div_set(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int div_mmc; + + div_mmc = readl((unsigned int) &clk->div_fsys1) & ~FSYS1_MMC0_DIV_MASK; + div_mmc |= FSYS1_MMC0_DIV_VAL; + writel(div_mmc, (unsigned int) &clk->div_fsys1); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/common_setup.h b/u-boot-imx/arch/arm/cpu/armv7/exynos/common_setup.h new file mode 100644 index 0000000..5235abb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/common_setup.h
@@ -0,0 +1,107 @@ +/* + * Common APIs for EXYNOS based board + * + * Copyright (C) 2013 Samsung Electronics + * Rajeshwari Shinde <rajeshwari.s@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 <asm/arch/system.h> + +#define DMC_OFFSET 0x10000 + +/* + * Memory initialization + * + * @param reset Reset PHY during initialization. + */ +void mem_ctrl_init(int reset); + + /* System Clock initialization */ +void system_clock_init(void); + +/* + * Init subsystems according to the reset status + * + * @return 0 for a normal boot, non-zero for a resume + */ +int do_lowlevel_init(void); + +void sdelay(unsigned long); + +enum l2_cache_params { + CACHE_DATA_RAM_LATENCY_2_CYCLES = (2 << 0), + CACHE_DATA_RAM_LATENCY_3_CYCLES = (3 << 0), + CACHE_DISABLE_CLEAN_EVICT = (1 << 3), + CACHE_DATA_RAM_SETUP = (1 << 5), + CACHE_TAG_RAM_LATENCY_2_CYCLES = (2 << 6), + CACHE_TAG_RAM_LATENCY_3_CYCLES = (3 << 6), + CACHE_ENABLE_HAZARD_DETECT = (1 << 7), + CACHE_TAG_RAM_SETUP = (1 << 9), + CACHE_ECC_AND_PARITY = (1 << 21), + CACHE_ENABLE_FORCE_L2_LOGIC = (1 << 27) +}; + + +#ifndef CONFIG_SYS_L2CACHE_OFF +/* + * Configure L2CTLR to get timings that keep us from hanging/crashing. + * + * Must be inline here since low_power_start() is called without a + * stack (!). + */ +static inline void configure_l2_ctlr(void) +{ + uint32_t val; + + mrc_l2_ctlr(val); + + val |= CACHE_TAG_RAM_SETUP | + CACHE_DATA_RAM_SETUP | + CACHE_TAG_RAM_LATENCY_2_CYCLES | + CACHE_DATA_RAM_LATENCY_2_CYCLES; + + if (proid_is_exynos5420() || proid_is_exynos5800()) { + val |= CACHE_ECC_AND_PARITY | + CACHE_TAG_RAM_LATENCY_3_CYCLES | + CACHE_DATA_RAM_LATENCY_3_CYCLES; + } + + mcr_l2_ctlr(val); +} + +/* + * Configure L2ACTLR. + * + * Must be inline here since low_power_start() is called without a + * stack (!). + */ +static inline void configure_l2_actlr(void) +{ + uint32_t val; + + if (proid_is_exynos5420() || proid_is_exynos5800()) { + mrc_l2_aux_ctlr(val); + val |= CACHE_ENABLE_FORCE_L2_LOGIC | + CACHE_DISABLE_CLEAN_EVICT; + mcr_l2_aux_ctlr(val); + } +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/config.mk b/u-boot-imx/arch/arm/cpu/armv7/exynos/config.mk new file mode 100644 index 0000000..ee0d2da --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/config.mk
@@ -0,0 +1,7 @@ +# +# Copyright (C) Albert ARIBAUD <albert.u.boot@aribaud.net> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +SPL_OBJCFLAGS += -j .machine_param
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_common.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_common.c new file mode 100644 index 0000000..9b6ee69 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_common.c
@@ -0,0 +1,176 @@ +/* + * Mem setup common file for different types of DDR present on Exynos boards. + * + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/spl.h> + +#include "clock_init.h" +#include "common_setup.h" +#include "exynos5_setup.h" + +#define ZQ_INIT_TIMEOUT 10000 + +int dmc_config_zq(struct mem_timings *mem, uint32_t *phy0_con16, + uint32_t *phy1_con16, uint32_t *phy0_con17, + uint32_t *phy1_con17) +{ + unsigned long val = 0; + int i; + + /* + * ZQ Calibration: + * Select Driver Strength, + * long calibration for manual calibration + */ + val = PHY_CON16_RESET_VAL; + val |= mem->zq_mode_dds << PHY_CON16_ZQ_MODE_DDS_SHIFT; + val |= mem->zq_mode_term << PHY_CON16_ZQ_MODE_TERM_SHIFT; + val |= ZQ_CLK_DIV_EN; + writel(val, phy0_con16); + writel(val, phy1_con16); + + /* Disable termination */ + if (mem->zq_mode_noterm) + val |= PHY_CON16_ZQ_MODE_NOTERM_MASK; + writel(val, phy0_con16); + writel(val, phy1_con16); + + /* ZQ_MANUAL_START: Enable */ + val |= ZQ_MANUAL_STR; + writel(val, phy0_con16); + writel(val, phy1_con16); + + /* ZQ_MANUAL_START: Disable */ + val &= ~ZQ_MANUAL_STR; + + /* + * Since we are manaully calibrating the ZQ values, + * we are looping for the ZQ_init to complete. + */ + i = ZQ_INIT_TIMEOUT; + while ((readl(phy0_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { + sdelay(100); + i--; + } + if (!i) + return -1; + writel(val, phy0_con16); + + i = ZQ_INIT_TIMEOUT; + while ((readl(phy1_con17) & ZQ_DONE) != ZQ_DONE && i > 0) { + sdelay(100); + i--; + } + if (!i) + return -1; + writel(val, phy1_con16); + + return 0; +} + +void update_reset_dll(uint32_t *phycontrol0, enum ddr_mode mode) +{ + unsigned long val; + + if (mode == DDR_MODE_DDR3) { + val = MEM_TERM_EN | PHY_TERM_EN | DMC_CTRL_SHGATE; + writel(val, phycontrol0); + } + + /* Update DLL Information: Force DLL Resyncronization */ + val = readl(phycontrol0); + val |= FP_RSYNC; + writel(val, phycontrol0); + + /* Reset Force DLL Resyncronization */ + val = readl(phycontrol0); + val &= ~FP_RSYNC; + writel(val, phycontrol0); +} + +void dmc_config_mrs(struct mem_timings *mem, uint32_t *directcmd) +{ + int channel, chip; + + for (channel = 0; channel < mem->dmc_channels; channel++) { + unsigned long mask; + + mask = channel << DIRECT_CMD_CHANNEL_SHIFT; + for (chip = 0; chip < mem->chips_to_configure; chip++) { + int i; + + mask |= chip << DIRECT_CMD_CHIP_SHIFT; + + /* Sending NOP command */ + writel(DIRECT_CMD_NOP | mask, directcmd); + + /* + * TODO(alim.akhtar@samsung.com): Do we need these + * delays? This one and the next were not there for + * DDR3. + */ + sdelay(0x10000); + + /* Sending EMRS/MRS commands */ + for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { + writel(mem->direct_cmd_msr[i] | mask, + directcmd); + sdelay(0x10000); + } + + if (mem->send_zq_init) { + /* Sending ZQINIT command */ + writel(DIRECT_CMD_ZQINIT | mask, + directcmd); + + sdelay(10000); + } + } + } +} + +void dmc_config_prech(struct mem_timings *mem, uint32_t *directcmd) +{ + int channel, chip; + + for (channel = 0; channel < mem->dmc_channels; channel++) { + unsigned long mask; + + mask = channel << DIRECT_CMD_CHANNEL_SHIFT; + for (chip = 0; chip < mem->chips_per_channel; chip++) { + mask |= chip << DIRECT_CMD_CHIP_SHIFT; + + /* PALL (all banks precharge) CMD */ + writel(DIRECT_CMD_PALL | mask, directcmd); + sdelay(0x10000); + } + } +} + +void mem_ctrl_init(int reset) +{ + struct spl_machine_param *param = spl_get_machine_params(); + struct mem_timings *mem; + int ret; + + mem = clock_get_mem_timings(); + + /* If there are any other memory variant, add their init call below */ + if (param->mem_type == DDR_MODE_DDR3) { + ret = ddr3_mem_ctrl_init(mem, reset); + if (ret) { + /* will hang if failed to init memory control */ + while (1) + ; + } + } else { + /* will hang if unknow memory type */ + while (1) + ; + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c new file mode 100644 index 0000000..7c0b12a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_ddr3.c
@@ -0,0 +1,866 @@ +/* + * DDR3 mem setup file for board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dmc.h> +#include <asm/arch/power.h> +#include "common_setup.h" +#include "exynos5_setup.h" +#include "clock_init.h" + +#define TIMEOUT_US 10000 +#define NUM_BYTE_LANES 4 +#define DEFAULT_DQS 8 +#define DEFAULT_DQS_X4 (DEFAULT_DQS << 24) || (DEFAULT_DQS << 16) \ + || (DEFAULT_DQS << 8) || (DEFAULT_DQS << 0) + +#ifdef CONFIG_EXYNOS5250 +static void reset_phy_ctrl(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + writel(DDR3PHY_CTRL_PHY_RESET_OFF, &clk->lpddr3phy_ctrl); + writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl); +} + +int ddr3_mem_ctrl_init(struct mem_timings *mem, int reset) +{ + unsigned int val; + struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; + struct exynos5_dmc *dmc; + int i; + + phy0_ctrl = (struct exynos5_phy_control *)samsung_get_base_dmc_phy(); + phy1_ctrl = (struct exynos5_phy_control *)(samsung_get_base_dmc_phy() + + DMC_OFFSET); + dmc = (struct exynos5_dmc *)samsung_get_base_dmc_ctrl(); + + if (reset) + reset_phy_ctrl(); + + /* Set Impedance Output Driver */ + val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) | + (mem->impedance << CA_CKE_DRVR_DS_OFFSET) | + (mem->impedance << CA_CS_DRVR_DS_OFFSET) | + (mem->impedance << CA_ADR_DRVR_DS_OFFSET); + writel(val, &phy0_ctrl->phy_con39); + writel(val, &phy1_ctrl->phy_con39); + + /* Set Read Latency and Burst Length for PHY0 and PHY1 */ + val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) | + (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT); + writel(val, &phy0_ctrl->phy_con42); + writel(val, &phy1_ctrl->phy_con42); + + /* ZQ Calibration */ + if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16, + &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17)) + return SETUP_ERR_ZQ_CALIBRATION_FAILURE; + + /* DQ Signal */ + writel(mem->phy0_pulld_dqs, &phy0_ctrl->phy_con14); + writel(mem->phy1_pulld_dqs, &phy1_ctrl->phy_con14); + + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) + | (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT), + &dmc->concontrol); + + update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3); + + /* DQS Signal */ + writel(mem->phy0_dqs, &phy0_ctrl->phy_con4); + writel(mem->phy1_dqs, &phy1_ctrl->phy_con4); + + writel(mem->phy0_dq, &phy0_ctrl->phy_con6); + writel(mem->phy1_dq, &phy1_ctrl->phy_con6); + + writel(mem->phy0_tFS, &phy0_ctrl->phy_con10); + writel(mem->phy1_tFS, &phy1_ctrl->phy_con10); + + val = (mem->ctrl_start_point << PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + /* Start DLL locking */ + writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), + &phy0_ctrl->phy_con12); + writel(val | (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT), + &phy1_ctrl->phy_con12); + + update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3); + + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), + &dmc->concontrol); + + /* Memory Channel Inteleaving Size */ + writel(mem->iv_size, &dmc->ivcontrol); + + writel(mem->memconfig, &dmc->memconfig0); + writel(mem->memconfig, &dmc->memconfig1); + writel(mem->membaseconfig0, &dmc->membaseconfig0); + writel(mem->membaseconfig1, &dmc->membaseconfig1); + + /* Precharge Configuration */ + writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, + &dmc->prechconfig); + + /* Power Down mode Configuration */ + writel(mem->dpwrdn_cyc << PWRDNCONFIG_DPWRDN_CYC_SHIFT | + mem->dsref_cyc << PWRDNCONFIG_DSREF_CYC_SHIFT, + &dmc->pwrdnconfig); + + /* TimingRow, TimingData, TimingPower and Timingaref + * values as per Memory AC parameters + */ + writel(mem->timing_ref, &dmc->timingref); + writel(mem->timing_row, &dmc->timingrow); + writel(mem->timing_data, &dmc->timingdata); + writel(mem->timing_power, &dmc->timingpower); + + /* Send PALL command */ + dmc_config_prech(mem, &dmc->directcmd); + + /* Send NOP, MRS and ZQINIT commands */ + dmc_config_mrs(mem, &dmc->directcmd); + + if (mem->gate_leveling_enable) { + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = PHY_CON2_RESET_VAL; + val |= INIT_DESKEW_EN; + writel(val, &phy0_ctrl->phy_con2); + writel(val, &phy1_ctrl->phy_con2); + + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + val |= BYTE_RDLVL_EN; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = (mem->ctrl_start_point << + PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | + (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + val = PHY_CON2_RESET_VAL; + val |= INIT_DESKEW_EN; + val |= RDLVL_GATE_EN; + writel(val, &phy0_ctrl->phy_con2); + writel(val, &phy1_ctrl->phy_con2); + + val = PHY_CON0_RESET_VAL; + val |= P0_CMD_EN; + val |= BYTE_RDLVL_EN; + val |= CTRL_SHGATE; + writel(val, &phy0_ctrl->phy_con0); + writel(val, &phy1_ctrl->phy_con0); + + val = PHY_CON1_RESET_VAL; + val &= ~(CTRL_GATEDURADJ_MASK); + writel(val, &phy0_ctrl->phy_con1); + writel(val, &phy1_ctrl->phy_con1); + + writel(CTRL_RDLVL_GATE_ENABLE, &dmc->rdlvl_config); + i = TIMEOUT_US; + while ((readl(&dmc->phystatus) & + (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1)) != + (RDLVL_COMPLETE_CHO | RDLVL_COMPLETE_CH1) && i > 0) { + /* + * TODO(waihong): Comment on how long this take to + * timeout + */ + sdelay(100); + i--; + } + if (!i) + return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; + writel(CTRL_RDLVL_GATE_DISABLE, &dmc->rdlvl_config); + + writel(0, &phy0_ctrl->phy_con14); + writel(0, &phy1_ctrl->phy_con14); + + val = (mem->ctrl_start_point << + PHY_CON12_CTRL_START_POINT_SHIFT) | + (mem->ctrl_inc << PHY_CON12_CTRL_INC_SHIFT) | + (mem->ctrl_force << PHY_CON12_CTRL_FORCE_SHIFT) | + (mem->ctrl_start << PHY_CON12_CTRL_START_SHIFT) | + (mem->ctrl_dll_on << PHY_CON12_CTRL_DLL_ON_SHIFT) | + (mem->ctrl_ref << PHY_CON12_CTRL_REF_SHIFT); + writel(val, &phy0_ctrl->phy_con12); + writel(val, &phy1_ctrl->phy_con12); + + update_reset_dll(&dmc->phycontrol0, DDR_MODE_DDR3); + } + + /* Send PALL command */ + dmc_config_prech(mem, &dmc->directcmd); + + writel(mem->memcontrol, &dmc->memcontrol); + + /* Set DMC Concontrol and enable auto-refresh counter */ + writel(mem->concontrol | (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT) + | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT), &dmc->concontrol); + return 0; +} +#endif + +#ifdef CONFIG_EXYNOS5420 +/** + * RAM address to use in the test. + * + * We'll use 4 words at this address and 4 at this address + 0x80 (Ares + * interleaves channels every 128 bytes). This will allow us to evaluate all of + * the chips in a 1 chip per channel (2GB) system and half the chips in a 2 + * chip per channel (4GB) system. We can't test the 2nd chip since we need to + * do tests before the 2nd chip is enabled. Looking at the 2nd chip isn't + * critical because the 1st and 2nd chip have very similar timings (they'd + * better have similar timings, since there's only a single adjustment that is + * shared by both chips). + */ +const unsigned int test_addr = CONFIG_SYS_SDRAM_BASE; + +/* Test pattern with which RAM will be tested */ +static const unsigned int test_pattern[] = { + 0x5a5a5a5a, + 0xa5a5a5a5, + 0xf0f0f0f0, + 0x0f0f0f0f, +}; + +/** + * This function is a test vector for sw read leveling, + * it compares the read data with the written data. + * + * @param ch DMC channel number + * @param byte_lane which DQS byte offset, + * possible values are 0,1,2,3 + * @return TRUE if memory was good, FALSE if not. + */ +static bool dmc_valid_window_test_vector(int ch, int byte_lane) +{ + unsigned int read_data; + unsigned int mask; + int i; + + mask = 0xFF << (8 * byte_lane); + + for (i = 0; i < ARRAY_SIZE(test_pattern); i++) { + read_data = readl(test_addr + i * 4 + ch * 0x80); + if ((read_data & mask) != (test_pattern[i] & mask)) + return false; + } + + return true; +} + +/** + * This function returns current read offset value. + * + * @param phy_ctrl pointer to the current phy controller + */ +static unsigned int dmc_get_read_offset_value(struct exynos5420_phy_control + *phy_ctrl) +{ + return readl(&phy_ctrl->phy_con4); +} + +/** + * This function performs resync, so that slave DLL is updated. + * + * @param phy_ctrl pointer to the current phy controller + */ +static void ddr_phy_set_do_resync(struct exynos5420_phy_control *phy_ctrl) +{ + setbits_le32(&phy_ctrl->phy_con10, PHY_CON10_CTRL_OFFSETR3); + clrbits_le32(&phy_ctrl->phy_con10, PHY_CON10_CTRL_OFFSETR3); +} + +/** + * This function sets read offset value register with 'offset'. + * + * ...we also call call ddr_phy_set_do_resync(). + * + * @param phy_ctrl pointer to the current phy controller + * @param offset offset to read DQS + */ +static void dmc_set_read_offset_value(struct exynos5420_phy_control *phy_ctrl, + unsigned int offset) +{ + writel(offset, &phy_ctrl->phy_con4); + ddr_phy_set_do_resync(phy_ctrl); +} + +/** + * Convert a 2s complement byte to a byte with a sign bit. + * + * NOTE: you shouldn't use normal math on the number returned by this function. + * As an example, -10 = 0xf6. After this function -10 = 0x8a. If you wanted + * to do math and get the average of 10 and -10 (should be 0): + * 0x8a + 0xa = 0x94 (-108) + * 0x94 / 2 = 0xca (-54) + * ...and 0xca = sign bit plus 0x4a, or -74 + * + * Also note that you lose the ability to represent -128 since there are two + * representations of 0. + * + * @param b The byte to convert in two's complement. + * @return The 7-bit value + sign bit. + */ + +unsigned char make_signed_byte(signed char b) +{ + if (b < 0) + return 0x80 | -b; + else + return b; +} + +/** + * Test various shifts starting at 'start' and going to 'end'. + * + * For each byte lane, we'll walk through shift starting at 'start' and going + * to 'end' (inclusive). When we are finally able to read the test pattern + * we'll store the value in the results array. + * + * @param phy_ctrl pointer to the current phy controller + * @param ch channel number + * @param start the start shift. -127 to 127 + * @param end the end shift. -127 to 127 + * @param results we'll store results for each byte lane. + */ + +void test_shifts(struct exynos5420_phy_control *phy_ctrl, int ch, + int start, int end, int results[NUM_BYTE_LANES]) +{ + int incr = (start < end) ? 1 : -1; + int byte_lane; + + for (byte_lane = 0; byte_lane < NUM_BYTE_LANES; byte_lane++) { + int shift; + + dmc_set_read_offset_value(phy_ctrl, DEFAULT_DQS_X4); + results[byte_lane] = DEFAULT_DQS; + + for (shift = start; shift != (end + incr); shift += incr) { + unsigned int byte_offsetr; + unsigned int offsetr; + + byte_offsetr = make_signed_byte(shift); + + offsetr = dmc_get_read_offset_value(phy_ctrl); + offsetr &= ~(0xFF << (8 * byte_lane)); + offsetr |= (byte_offsetr << (8 * byte_lane)); + dmc_set_read_offset_value(phy_ctrl, offsetr); + + if (dmc_valid_window_test_vector(ch, byte_lane)) { + results[byte_lane] = shift; + break; + } + } + } +} + +/** + * This function performs SW read leveling to compensate DQ-DQS skew at + * receiver it first finds the optimal read offset value on each DQS + * then applies the value to PHY. + * + * Read offset value has its min margin and max margin. If read offset + * value exceeds its min or max margin, read data will have corruption. + * To avoid this we are doing sw read leveling. + * + * SW read leveling is: + * 1> Finding offset value's left_limit and right_limit + * 2> and calculate its center value + * 3> finally programs that center value to PHY + * 4> then PHY gets its optimal offset value. + * + * @param phy_ctrl pointer to the current phy controller + * @param ch channel number + * @param coarse_lock_val The coarse lock value read from PHY_CON13. + * (0 - 0x7f) + */ +static void software_find_read_offset(struct exynos5420_phy_control *phy_ctrl, + int ch, unsigned int coarse_lock_val) +{ + unsigned int offsetr_cent; + int byte_lane; + int left_limit; + int right_limit; + int left[NUM_BYTE_LANES]; + int right[NUM_BYTE_LANES]; + int i; + + /* Fill the memory with test patterns */ + for (i = 0; i < ARRAY_SIZE(test_pattern); i++) + writel(test_pattern[i], test_addr + i * 4 + ch * 0x80); + + /* Figure out the limits we'll test with; keep -127 < limit < 127 */ + left_limit = DEFAULT_DQS - coarse_lock_val; + right_limit = DEFAULT_DQS + coarse_lock_val; + if (right_limit > 127) + right_limit = 127; + + /* Fill in the location where reads were OK from left and right */ + test_shifts(phy_ctrl, ch, left_limit, right_limit, left); + test_shifts(phy_ctrl, ch, right_limit, left_limit, right); + + /* Make a final value by taking the center between the left and right */ + offsetr_cent = 0; + for (byte_lane = 0; byte_lane < NUM_BYTE_LANES; byte_lane++) { + int temp_center; + unsigned int vmwc; + + temp_center = (left[byte_lane] + right[byte_lane]) / 2; + vmwc = make_signed_byte(temp_center); + offsetr_cent |= vmwc << (8 * byte_lane); + } + dmc_set_read_offset_value(phy_ctrl, offsetr_cent); +} + +int ddr3_mem_ctrl_init(struct mem_timings *mem, int reset) +{ + struct exynos5420_clock *clk = + (struct exynos5420_clock *)samsung_get_base_clock(); + struct exynos5420_power *power = + (struct exynos5420_power *)samsung_get_base_power(); + struct exynos5420_phy_control *phy0_ctrl, *phy1_ctrl; + struct exynos5420_dmc *drex0, *drex1; + struct exynos5420_tzasc *tzasc0, *tzasc1; + struct exynos5_power *pmu; + uint32_t val, n_lock_r, n_lock_w_phy0, n_lock_w_phy1; + uint32_t lock0_info, lock1_info; + int chip; + int i; + + phy0_ctrl = (struct exynos5420_phy_control *)samsung_get_base_dmc_phy(); + phy1_ctrl = (struct exynos5420_phy_control *)(samsung_get_base_dmc_phy() + + DMC_OFFSET); + drex0 = (struct exynos5420_dmc *)samsung_get_base_dmc_ctrl(); + drex1 = (struct exynos5420_dmc *)(samsung_get_base_dmc_ctrl() + + DMC_OFFSET); + tzasc0 = (struct exynos5420_tzasc *)samsung_get_base_dmc_tzasc(); + tzasc1 = (struct exynos5420_tzasc *)(samsung_get_base_dmc_tzasc() + + DMC_OFFSET); + pmu = (struct exynos5_power *)EXYNOS5420_POWER_BASE; + + if (CONFIG_NR_DRAM_BANKS > 4) { + /* Need both controllers. */ + mem->memcontrol |= DMC_MEMCONTROL_NUM_CHIP_2; + mem->chips_per_channel = 2; + mem->chips_to_configure = 2; + } else { + /* 2GB requires a single controller */ + mem->memcontrol |= DMC_MEMCONTROL_NUM_CHIP_1; + } + + /* Enable PAUSE for DREX */ + setbits_le32(&clk->pause, ENABLE_BIT); + + /* Enable BYPASS mode */ + setbits_le32(&clk->bpll_con1, BYPASS_EN); + + writel(MUX_BPLL_SEL_FOUTBPLL, &clk->src_cdrex); + do { + val = readl(&clk->mux_stat_cdrex); + val &= BPLL_SEL_MASK; + } while (val != FOUTBPLL); + + clrbits_le32(&clk->bpll_con1, BYPASS_EN); + + /* Specify the DDR memory type as DDR3 */ + val = readl(&phy0_ctrl->phy_con0); + val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT); + val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT); + writel(val, &phy0_ctrl->phy_con0); + + val = readl(&phy1_ctrl->phy_con0); + val &= ~(PHY_CON0_CTRL_DDR_MODE_MASK << PHY_CON0_CTRL_DDR_MODE_SHIFT); + val |= (DDR_MODE_DDR3 << PHY_CON0_CTRL_DDR_MODE_SHIFT); + writel(val, &phy1_ctrl->phy_con0); + + /* Set Read Latency and Burst Length for PHY0 and PHY1 */ + val = (mem->ctrl_bstlen << PHY_CON42_CTRL_BSTLEN_SHIFT) | + (mem->ctrl_rdlat << PHY_CON42_CTRL_RDLAT_SHIFT); + writel(val, &phy0_ctrl->phy_con42); + writel(val, &phy1_ctrl->phy_con42); + + val = readl(&phy0_ctrl->phy_con26); + val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET); + val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET); + writel(val, &phy0_ctrl->phy_con26); + + val = readl(&phy1_ctrl->phy_con26); + val &= ~(T_WRDATA_EN_MASK << T_WRDATA_EN_OFFSET); + val |= (T_WRDATA_EN_DDR3 << T_WRDATA_EN_OFFSET); + writel(val, &phy1_ctrl->phy_con26); + + /* + * Set Driver strength for CK, CKE, CS & CA to 0x7 + * Set Driver strength for Data Slice 0~3 to 0x7 + */ + val = (0x7 << CA_CK_DRVR_DS_OFFSET) | (0x7 << CA_CKE_DRVR_DS_OFFSET) | + (0x7 << CA_CS_DRVR_DS_OFFSET) | (0x7 << CA_ADR_DRVR_DS_OFFSET); + val |= (0x7 << DA_3_DS_OFFSET) | (0x7 << DA_2_DS_OFFSET) | + (0x7 << DA_1_DS_OFFSET) | (0x7 << DA_0_DS_OFFSET); + writel(val, &phy0_ctrl->phy_con39); + writel(val, &phy1_ctrl->phy_con39); + + /* ZQ Calibration */ + if (dmc_config_zq(mem, &phy0_ctrl->phy_con16, &phy1_ctrl->phy_con16, + &phy0_ctrl->phy_con17, &phy1_ctrl->phy_con17)) + return SETUP_ERR_ZQ_CALIBRATION_FAILURE; + + clrbits_le32(&phy0_ctrl->phy_con16, ZQ_CLK_DIV_EN); + clrbits_le32(&phy1_ctrl->phy_con16, ZQ_CLK_DIV_EN); + + /* DQ Signal */ + val = readl(&phy0_ctrl->phy_con14); + val |= mem->phy0_pulld_dqs; + writel(val, &phy0_ctrl->phy_con14); + val = readl(&phy1_ctrl->phy_con14); + val |= mem->phy1_pulld_dqs; + writel(val, &phy1_ctrl->phy_con14); + + val = MEM_TERM_EN | PHY_TERM_EN; + writel(val, &drex0->phycontrol0); + writel(val, &drex1->phycontrol0); + + writel(mem->concontrol | + (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) | + (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), + &drex0->concontrol); + writel(mem->concontrol | + (mem->dfi_init_start << CONCONTROL_DFI_INIT_START_SHIFT) | + (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT), + &drex1->concontrol); + + do { + val = readl(&drex0->phystatus); + } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE); + do { + val = readl(&drex1->phystatus); + } while ((val & DFI_INIT_COMPLETE) != DFI_INIT_COMPLETE); + + clrbits_le32(&drex0->concontrol, DFI_INIT_START); + clrbits_le32(&drex1->concontrol, DFI_INIT_START); + + update_reset_dll(&drex0->phycontrol0, DDR_MODE_DDR3); + update_reset_dll(&drex1->phycontrol0, DDR_MODE_DDR3); + + /* + * Set Base Address: + * 0x2000_0000 ~ 0x5FFF_FFFF + * 0x6000_0000 ~ 0x9FFF_FFFF + */ + /* MEMBASECONFIG0 */ + val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_0) | + DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK); + writel(val, &tzasc0->membaseconfig0); + writel(val, &tzasc1->membaseconfig0); + + /* MEMBASECONFIG1 */ + val = DMC_MEMBASECONFIGX_CHIP_BASE(DMC_CHIP_BASE_1) | + DMC_MEMBASECONFIGX_CHIP_MASK(DMC_CHIP_MASK); + writel(val, &tzasc0->membaseconfig1); + writel(val, &tzasc1->membaseconfig1); + + /* + * Memory Channel Inteleaving Size + * Ares Channel interleaving = 128 bytes + */ + /* MEMCONFIG0/1 */ + writel(mem->memconfig, &tzasc0->memconfig0); + writel(mem->memconfig, &tzasc1->memconfig0); + writel(mem->memconfig, &tzasc0->memconfig1); + writel(mem->memconfig, &tzasc1->memconfig1); + + /* Precharge Configuration */ + writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, + &drex0->prechconfig0); + writel(mem->prechconfig_tp_cnt << PRECHCONFIG_TP_CNT_SHIFT, + &drex1->prechconfig0); + + /* + * TimingRow, TimingData, TimingPower and Timingaref + * values as per Memory AC parameters + */ + writel(mem->timing_ref, &drex0->timingref); + writel(mem->timing_ref, &drex1->timingref); + writel(mem->timing_row, &drex0->timingrow0); + writel(mem->timing_row, &drex1->timingrow0); + writel(mem->timing_data, &drex0->timingdata0); + writel(mem->timing_data, &drex1->timingdata0); + writel(mem->timing_power, &drex0->timingpower0); + writel(mem->timing_power, &drex1->timingpower0); + + if (reset) { + /* + * Send NOP, MRS and ZQINIT commands + * Sending MRS command will reset the DRAM. We should not be + * reseting the DRAM after resume, this will lead to memory + * corruption as DRAM content is lost after DRAM reset + */ + dmc_config_mrs(mem, &drex0->directcmd); + dmc_config_mrs(mem, &drex1->directcmd); + } + + /* + * Get PHY_CON13 from both phys. Gate CLKM around reading since + * PHY_CON13 is glitchy when CLKM is running. We're paranoid and + * wait until we get a "fine lock", though a coarse lock is probably + * OK (we only use the coarse numbers below). We try to gate the + * clock for as short a time as possible in case SDRAM is somehow + * sensitive. sdelay(10) in the loop is arbitrary to make sure + * there is some time for PHY_CON13 to get updated. In practice + * no delay appears to be needed. + */ + val = readl(&clk->gate_bus_cdrex); + while (true) { + writel(val & ~0x1, &clk->gate_bus_cdrex); + lock0_info = readl(&phy0_ctrl->phy_con13); + writel(val, &clk->gate_bus_cdrex); + + if ((lock0_info & CTRL_FINE_LOCKED) == CTRL_FINE_LOCKED) + break; + + sdelay(10); + } + while (true) { + writel(val & ~0x2, &clk->gate_bus_cdrex); + lock1_info = readl(&phy1_ctrl->phy_con13); + writel(val, &clk->gate_bus_cdrex); + + if ((lock1_info & CTRL_FINE_LOCKED) == CTRL_FINE_LOCKED) + break; + + sdelay(10); + } + + if (!reset) { + /* + * During Suspend-Resume & S/W-Reset, as soon as PMU releases + * pad retention, CKE goes high. This causes memory contents + * not to be retained during DRAM initialization. Therfore, + * there is a new control register(0x100431e8[28]) which lets us + * release pad retention and retain the memory content until the + * initialization is complete. + */ + writel(PAD_RETENTION_DRAM_COREBLK_VAL, + &power->pad_retention_dram_coreblk_option); + do { + val = readl(&power->pad_retention_dram_status); + } while (val != 0x1); + + /* + * CKE PAD retention disables DRAM self-refresh mode. + * Send auto refresh command for DRAM refresh. + */ + for (i = 0; i < 128; i++) { + for (chip = 0; chip < mem->chips_to_configure; chip++) { + writel(DIRECT_CMD_REFA | + (chip << DIRECT_CMD_CHIP_SHIFT), + &drex0->directcmd); + writel(DIRECT_CMD_REFA | + (chip << DIRECT_CMD_CHIP_SHIFT), + &drex1->directcmd); + } + } + } + + if (mem->gate_leveling_enable) { + writel(PHY_CON0_RESET_VAL, &phy0_ctrl->phy_con0); + writel(PHY_CON0_RESET_VAL, &phy1_ctrl->phy_con0); + + setbits_le32(&phy0_ctrl->phy_con0, P0_CMD_EN); + setbits_le32(&phy1_ctrl->phy_con0, P0_CMD_EN); + + val = PHY_CON2_RESET_VAL; + val |= INIT_DESKEW_EN; + writel(val, &phy0_ctrl->phy_con2); + writel(val, &phy1_ctrl->phy_con2); + + val = readl(&phy0_ctrl->phy_con1); + val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET); + writel(val, &phy0_ctrl->phy_con1); + + val = readl(&phy1_ctrl->phy_con1); + val |= (RDLVL_PASS_ADJ_VAL << RDLVL_PASS_ADJ_OFFSET); + writel(val, &phy1_ctrl->phy_con1); + + n_lock_w_phy0 = (lock0_info & CTRL_LOCK_COARSE_MASK) >> 2; + n_lock_r = readl(&phy0_ctrl->phy_con12); + n_lock_r &= ~CTRL_DLL_ON; + n_lock_r |= n_lock_w_phy0; + writel(n_lock_r, &phy0_ctrl->phy_con12); + + n_lock_w_phy1 = (lock1_info & CTRL_LOCK_COARSE_MASK) >> 2; + n_lock_r = readl(&phy1_ctrl->phy_con12); + n_lock_r &= ~CTRL_DLL_ON; + n_lock_r |= n_lock_w_phy1; + writel(n_lock_r, &phy1_ctrl->phy_con12); + + val = (0x3 << DIRECT_CMD_BANK_SHIFT) | 0x4; + for (chip = 0; chip < mem->chips_to_configure; chip++) { + writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), + &drex0->directcmd); + writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), + &drex1->directcmd); + } + + setbits_le32(&phy0_ctrl->phy_con2, RDLVL_GATE_EN); + setbits_le32(&phy1_ctrl->phy_con2, RDLVL_GATE_EN); + + setbits_le32(&phy0_ctrl->phy_con0, CTRL_SHGATE); + setbits_le32(&phy1_ctrl->phy_con0, CTRL_SHGATE); + + val = readl(&phy0_ctrl->phy_con1); + val &= ~(CTRL_GATEDURADJ_MASK); + writel(val, &phy0_ctrl->phy_con1); + + val = readl(&phy1_ctrl->phy_con1); + val &= ~(CTRL_GATEDURADJ_MASK); + writel(val, &phy1_ctrl->phy_con1); + + writel(CTRL_RDLVL_GATE_ENABLE, &drex0->rdlvl_config); + i = TIMEOUT_US; + while (((readl(&drex0->phystatus) & RDLVL_COMPLETE_CHO) != + RDLVL_COMPLETE_CHO) && (i > 0)) { + /* + * TODO(waihong): Comment on how long this take to + * timeout + */ + sdelay(100); + i--; + } + if (!i) + return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; + writel(CTRL_RDLVL_GATE_DISABLE, &drex0->rdlvl_config); + + writel(CTRL_RDLVL_GATE_ENABLE, &drex1->rdlvl_config); + i = TIMEOUT_US; + while (((readl(&drex1->phystatus) & RDLVL_COMPLETE_CHO) != + RDLVL_COMPLETE_CHO) && (i > 0)) { + /* + * TODO(waihong): Comment on how long this take to + * timeout + */ + sdelay(100); + i--; + } + if (!i) + return SETUP_ERR_RDLV_COMPLETE_TIMEOUT; + writel(CTRL_RDLVL_GATE_DISABLE, &drex1->rdlvl_config); + + writel(0, &phy0_ctrl->phy_con14); + writel(0, &phy1_ctrl->phy_con14); + + val = (0x3 << DIRECT_CMD_BANK_SHIFT); + for (chip = 0; chip < mem->chips_to_configure; chip++) { + writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), + &drex0->directcmd); + writel(val | (chip << DIRECT_CMD_CHIP_SHIFT), + &drex1->directcmd); + } + + /* Common Settings for Leveling */ + val = PHY_CON12_RESET_VAL; + writel((val + n_lock_w_phy0), &phy0_ctrl->phy_con12); + writel((val + n_lock_w_phy1), &phy1_ctrl->phy_con12); + + setbits_le32(&phy0_ctrl->phy_con2, DLL_DESKEW_EN); + setbits_le32(&phy1_ctrl->phy_con2, DLL_DESKEW_EN); + } + + /* + * Do software read leveling + * + * Do this before we turn on auto refresh since the auto refresh can + * be in conflict with the resync operation that's part of setting + * read leveling. + */ + if (!reset) { + /* restore calibrated value after resume */ + dmc_set_read_offset_value(phy0_ctrl, readl(&pmu->pmu_spare1)); + dmc_set_read_offset_value(phy1_ctrl, readl(&pmu->pmu_spare2)); + } else { + software_find_read_offset(phy0_ctrl, 0, + CTRL_LOCK_COARSE(lock0_info)); + software_find_read_offset(phy1_ctrl, 1, + CTRL_LOCK_COARSE(lock1_info)); + /* save calibrated value to restore after resume */ + writel(dmc_get_read_offset_value(phy0_ctrl), &pmu->pmu_spare1); + writel(dmc_get_read_offset_value(phy1_ctrl), &pmu->pmu_spare2); + } + + /* Send PALL command */ + dmc_config_prech(mem, &drex0->directcmd); + dmc_config_prech(mem, &drex1->directcmd); + + writel(mem->memcontrol, &drex0->memcontrol); + writel(mem->memcontrol, &drex1->memcontrol); + + /* + * Set DMC Concontrol: Enable auto-refresh counter, provide + * read data fetch cycles and enable DREX auto set powerdown + * for input buffer of I/O in none read memory state. + */ + writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) | + (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)| + DMC_CONCONTROL_IO_PD_CON(0x2), + &drex0->concontrol); + writel(mem->concontrol | (mem->aref_en << CONCONTROL_AREF_EN_SHIFT) | + (mem->rd_fetch << CONCONTROL_RD_FETCH_SHIFT)| + DMC_CONCONTROL_IO_PD_CON(0x2), + &drex1->concontrol); + + /* + * Enable Clock Gating Control for DMC + * this saves around 25 mw dmc power as compared to the power + * consumption without these bits enabled + */ + setbits_le32(&drex0->cgcontrol, DMC_INTERNAL_CG); + setbits_le32(&drex1->cgcontrol, DMC_INTERNAL_CG); + + /* + * As per Exynos5800 UM ver 0.00 section 17.13.2.1 + * CONCONTROL register bit 3 [update_mode], Exynos5800 does not + * support the PHY initiated update. And it is recommended to set + * this field to 1'b1 during initialization + * + * When we apply PHY-initiated mode, DLL lock value is determined + * once at DMC init time and not updated later when we change the MIF + * voltage based on ASV group in kernel. Applying MC-initiated mode + * makes sure that DLL tracing is ON so that silicon is able to + * compensate the voltage variation. + */ + val = readl(&drex0->concontrol); + val |= CONCONTROL_UPDATE_MODE; + writel(val , &drex0->concontrol); + val = readl(&drex1->concontrol); + val |= CONCONTROL_UPDATE_MODE; + writel(val , &drex1->concontrol); + + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_exynos4.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_exynos4.c new file mode 100644 index 0000000..ecddc72 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/dmc_init_exynos4.c
@@ -0,0 +1,213 @@ +/* + * Memory setup for board based on EXYNOS4210 + * + * Copyright (C) 2013 Samsung Electronics + * Rajeshwari Shinde <rajeshwari.s@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 <config.h> +#include <asm/arch/dmc.h> +#include "common_setup.h" +#include "exynos4_setup.h" + +struct mem_timings mem = { + .direct_cmd_msr = { + DIRECT_CMD1, DIRECT_CMD2, DIRECT_CMD3, DIRECT_CMD4 + }, + .timingref = TIMINGREF_VAL, + .timingrow = TIMINGROW_VAL, + .timingdata = TIMINGDATA_VAL, + .timingpower = TIMINGPOWER_VAL, + .zqcontrol = ZQ_CONTROL_VAL, + .control0 = CONTROL0_VAL, + .control1 = CONTROL1_VAL, + .control2 = CONTROL2_VAL, + .concontrol = CONCONTROL_VAL, + .prechconfig = PRECHCONFIG, + .memcontrol = MEMCONTROL_VAL, + .memconfig0 = MEMCONFIG0_VAL, + .memconfig1 = MEMCONFIG1_VAL, + .dll_resync = FORCE_DLL_RESYNC, + .dll_on = DLL_CONTROL_ON, +}; +static void phy_control_reset(int ctrl_no, struct exynos4_dmc *dmc) +{ + if (ctrl_no) { + writel((mem.control1 | (1 << mem.dll_resync)), + &dmc->phycontrol1); + writel((mem.control1 | (0 << mem.dll_resync)), + &dmc->phycontrol1); + } else { + writel((mem.control0 | (0 << mem.dll_on)), + &dmc->phycontrol0); + writel((mem.control0 | (1 << mem.dll_on)), + &dmc->phycontrol0); + } +} + +static void dmc_config_mrs(struct exynos4_dmc *dmc, int chip) +{ + int i; + unsigned long mask = 0; + + if (chip) + mask = DIRECT_CMD_CHIP1_SHIFT; + + for (i = 0; i < MEM_TIMINGS_MSR_COUNT; i++) { + writel(mem.direct_cmd_msr[i] | mask, + &dmc->directcmd); + } +} + +static void dmc_init(struct exynos4_dmc *dmc) +{ + /* + * DLL Parameter Setting: + * Termination: Enable R/W + * Phase Delay for DQS Cleaning: 180' Shift + */ + writel(mem.control1, &dmc->phycontrol1); + + /* + * ZQ Calibration + * Termination: Disable + * Auto Calibration Start: Enable + */ + writel(mem.zqcontrol, &dmc->phyzqcontrol); + sdelay(0x100000); + + /* + * Update DLL Information: + * Force DLL Resyncronization + */ + phy_control_reset(1, dmc); + phy_control_reset(0, dmc); + + /* Set DLL Parameters */ + writel(mem.control1, &dmc->phycontrol1); + + /* DLL Start */ + writel((mem.control0 | CTRL_START | CTRL_DLL_ON), &dmc->phycontrol0); + + writel(mem.control2, &dmc->phycontrol2); + + /* Set Clock Ratio of Bus clock to Memory Clock */ + writel(mem.concontrol, &dmc->concontrol); + + /* + * Memor Burst length: 8 + * Number of chips: 2 + * Memory Bus width: 32 bit + * Memory Type: DDR3 + * Additional Latancy for PLL: 1 Cycle + */ + writel(mem.memcontrol, &dmc->memcontrol); + + writel(mem.memconfig0, &dmc->memconfig0); + writel(mem.memconfig1, &dmc->memconfig1); + + /* Config Precharge Policy */ + writel(mem.prechconfig, &dmc->prechconfig); + /* + * TimingAref, TimingRow, TimingData, TimingPower Setting: + * Values as per Memory AC Parameters + */ + writel(mem.timingref, &dmc->timingref); + writel(mem.timingrow, &dmc->timingrow); + writel(mem.timingdata, &dmc->timingdata); + writel(mem.timingpower, &dmc->timingpower); + + /* Chip0: NOP Command: Assert and Hold CKE to high level */ + writel(DIRECT_CMD_NOP, &dmc->directcmd); + sdelay(0x100000); + + /* Chip0: EMRS2, EMRS3, EMRS, MRS Commands Using Direct Command */ + dmc_config_mrs(dmc, 0); + sdelay(0x100000); + + /* Chip0: ZQINIT */ + writel(DIRECT_CMD_ZQ, &dmc->directcmd); + sdelay(0x100000); + + writel((DIRECT_CMD_NOP | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd); + sdelay(0x100000); + + /* Chip1: EMRS2, EMRS3, EMRS, MRS Commands Using Direct Command */ + dmc_config_mrs(dmc, 1); + sdelay(0x100000); + + /* Chip1: ZQINIT */ + writel((DIRECT_CMD_ZQ | DIRECT_CMD_CHIP1_SHIFT), &dmc->directcmd); + sdelay(0x100000); + + phy_control_reset(1, dmc); + sdelay(0x100000); + + /* turn on DREX0, DREX1 */ + writel((mem.concontrol | AREF_EN), &dmc->concontrol); +} + +void mem_ctrl_init(int reset) +{ + struct exynos4_dmc *dmc; + + /* + * Async bridge configuration at CPU_core: + * 1: half_sync + * 0: full_sync + */ + writel(1, ASYNC_CONFIG); +#ifdef CONFIG_ORIGEN + /* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */ + writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_INTERLEAVE_CONF_OFFSET); + /* Update MIU Configuration */ + writel(APB_SFR_ARBRITATION_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_ARBRITATION_CONF_OFFSET); +#else + writel(APB_SFR_INTERLEAVE_CONF_VAL, EXYNOS4_MIU_BASE + + APB_SFR_INTERLEAVE_CONF_OFFSET); + writel(INTERLEAVE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_INTERLEAVE_ADDRMAP_START_OFFSET); + writel(INTERLEAVE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_INTERLEAVE_ADDRMAP_END_OFFSET); + writel(INTERLEAVE_ADDR_MAP_EN, EXYNOS4_MIU_BASE + + ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); +#ifdef CONFIG_MIU_LINEAR + writel(SLAVE0_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV0_SINGLE_ADDRMAP_START_OFFSET); + writel(SLAVE0_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV0_SINGLE_ADDRMAP_END_OFFSET); + writel(SLAVE1_SINGLE_ADDR_MAP_START_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET); + writel(SLAVE1_SINGLE_ADDR_MAP_END_ADDR, EXYNOS4_MIU_BASE + + ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET); + writel(APB_SFR_SLV_ADDR_MAP_CONF_VAL, EXYNOS4_MIU_BASE + + ABP_SFR_SLV_ADDRMAP_CONF_OFFSET); +#endif +#endif + /* DREX0 */ + dmc = (struct exynos4_dmc *)samsung_get_base_dmc_ctrl(); + dmc_init(dmc); + dmc = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl() + + DMC_OFFSET); + dmc_init(dmc); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos4_setup.h b/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos4_setup.h new file mode 100644 index 0000000..9f29d94 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos4_setup.h
@@ -0,0 +1,577 @@ +/* + * Machine Specific Values for EXYNOS4012 based board + * + * Copyright (C) 2011 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ORIGEN_SETUP_H +#define _ORIGEN_SETUP_H + +#include <config.h> +#include <asm/arch/cpu.h> + +#ifdef CONFIG_CLK_800_330_165 +#define DRAM_CLK_330 +#endif +#ifdef CONFIG_CLK_1000_200_200 +#define DRAM_CLK_200 +#endif +#ifdef CONFIG_CLK_1000_330_165 +#define DRAM_CLK_330 +#endif +#ifdef CONFIG_CLK_1000_400_200 +#define DRAM_CLK_400 +#endif + +/* Bus Configuration Register Address */ +#define ASYNC_CONFIG 0x10010350 + +/* CLK_SRC_CPU */ +#define MUX_HPM_SEL_MOUTAPLL 0x0 +#define MUX_HPM_SEL_SCLKMPLL 0x1 +#define MUX_CORE_SEL_MOUTAPLL 0x0 +#define MUX_CORE_SEL_SCLKMPLL 0x1 +#define MUX_MPLL_SEL_FILPLL 0x0 +#define MUX_MPLL_SEL_MOUTMPLLFOUT 0x1 +#define MUX_APLL_SEL_FILPLL 0x0 +#define MUX_APLL_SEL_MOUTMPLLFOUT 0x1 +#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL_MOUTAPLL << 20) \ + | (MUX_CORE_SEL_MOUTAPLL << 16) \ + | (MUX_MPLL_SEL_MOUTMPLLFOUT << 8)\ + | (MUX_APLL_SEL_MOUTMPLLFOUT << 0)) + +/* CLK_DIV_CPU0 */ +#define APLL_RATIO 0x0 +#define PCLK_DBG_RATIO 0x1 +#define ATB_RATIO 0x3 +#define PERIPH_RATIO 0x3 +#define COREM1_RATIO 0x7 +#define COREM0_RATIO 0x3 +#define CORE_RATIO 0x0 +#define CLK_DIV_CPU0_VAL ((APLL_RATIO << 24) \ + | (PCLK_DBG_RATIO << 20) \ + | (ATB_RATIO << 16) \ + | (PERIPH_RATIO << 12) \ + | (COREM1_RATIO << 8) \ + | (COREM0_RATIO << 4) \ + | (CORE_RATIO << 0)) + +/* CLK_DIV_CPU1 */ +#define HPM_RATIO 0x0 +#define COPY_RATIO 0x3 +#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) | (COPY_RATIO)) + +/* CLK_SRC_DMC */ +#define MUX_PWI_SEL_XXTI 0x0 +#define MUX_PWI_SEL_XUSBXTI 0x1 +#define MUX_PWI_SEL_SCLK_HDMI24M 0x2 +#define MUX_PWI_SEL_SCLK_USBPHY0 0x3 +#define MUX_PWI_SEL_SCLK_USBPHY1 0x4 +#define MUX_PWI_SEL_SCLK_HDMIPHY 0x5 +#define MUX_PWI_SEL_SCLKMPLL 0x6 +#define MUX_PWI_SEL_SCLKEPLL 0x7 +#define MUX_PWI_SEL_SCLKVPLL 0x8 +#define MUX_DPHY_SEL_SCLKMPLL 0x0 +#define MUX_DPHY_SEL_SCLKAPLL 0x1 +#define MUX_DMC_BUS_SEL_SCLKMPLL 0x0 +#define MUX_DMC_BUS_SEL_SCLKAPLL 0x1 +#define CLK_SRC_DMC_VAL ((MUX_PWI_SEL_XUSBXTI << 16) \ + | (MUX_DPHY_SEL_SCLKMPLL << 8) \ + | (MUX_DMC_BUS_SEL_SCLKMPLL << 4)) + +/* CLK_DIV_DMC0 */ +#define CORE_TIMERS_RATIO 0x1 +#define COPY2_RATIO 0x3 +#define DMCP_RATIO 0x1 +#define DMCD_RATIO 0x1 +#define DMC_RATIO 0x1 +#define DPHY_RATIO 0x1 +#define ACP_PCLK_RATIO 0x1 +#define ACP_RATIO 0x3 +#define CLK_DIV_DMC0_VAL ((CORE_TIMERS_RATIO << 28) \ + | (COPY2_RATIO << 24) \ + | (DMCP_RATIO << 20) \ + | (DMCD_RATIO << 16) \ + | (DMC_RATIO << 12) \ + | (DPHY_RATIO << 8) \ + | (ACP_PCLK_RATIO << 4) \ + | (ACP_RATIO << 0)) + +/* CLK_DIV_DMC1 */ +#define DPM_RATIO 0x1 +#define DVSEM_RATIO 0x1 +#define PWI_RATIO 0x1 +#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \ + | (DVSEM_RATIO << 16) \ + | (PWI_RATIO << 8)) + +/* CLK_SRC_TOP0 */ +#define MUX_ONENAND_SEL_ACLK_133 0x0 +#define MUX_ONENAND_SEL_ACLK_160 0x1 +#define MUX_ACLK_133_SEL_SCLKMPLL 0x0 +#define MUX_ACLK_133_SEL_SCLKAPLL 0x1 +#define MUX_ACLK_160_SEL_SCLKMPLL 0x0 +#define MUX_ACLK_160_SEL_SCLKAPLL 0x1 +#define MUX_ACLK_100_SEL_SCLKMPLL 0x0 +#define MUX_ACLK_100_SEL_SCLKAPLL 0x1 +#define MUX_ACLK_200_SEL_SCLKMPLL 0x0 +#define MUX_ACLK_200_SEL_SCLKAPLL 0x1 +#define MUX_VPLL_SEL_FINPLL 0x0 +#define MUX_VPLL_SEL_FOUTVPLL 0x1 +#define MUX_EPLL_SEL_FINPLL 0x0 +#define MUX_EPLL_SEL_FOUTEPLL 0x1 +#define MUX_ONENAND_1_SEL_MOUTONENAND 0x0 +#define MUX_ONENAND_1_SEL_SCLKVPLL 0x1 +#define CLK_SRC_TOP0_VAL ((MUX_ONENAND_SEL_ACLK_133 << 28) \ + | (MUX_ACLK_133_SEL_SCLKMPLL << 24) \ + | (MUX_ACLK_160_SEL_SCLKMPLL << 20) \ + | (MUX_ACLK_100_SEL_SCLKMPLL << 16) \ + | (MUX_ACLK_200_SEL_SCLKMPLL << 12) \ + | (MUX_VPLL_SEL_FINPLL << 8) \ + | (MUX_EPLL_SEL_FINPLL << 4)\ + | (MUX_ONENAND_1_SEL_MOUTONENAND << 0)) + +/* CLK_SRC_TOP1 */ +#define VPLLSRC_SEL_FINPLL 0x0 +#define VPLLSRC_SEL_SCLKHDMI24M 0x1 +#define CLK_SRC_TOP1_VAL (VPLLSRC_SEL_FINPLL) + +/* CLK_DIV_TOP */ +#define ONENAND_RATIO 0x0 +#define ACLK_133_RATIO 0x5 +#define ACLK_160_RATIO 0x4 +#define ACLK_100_RATIO 0x7 +#define ACLK_200_RATIO 0x3 +#define CLK_DIV_TOP_VAL ((ONENAND_RATIO << 16) \ + | (ACLK_133_RATIO << 12)\ + | (ACLK_160_RATIO << 8) \ + | (ACLK_100_RATIO << 4) \ + | (ACLK_200_RATIO << 0)) + +/* CLK_SRC_LEFTBUS */ +#define MUX_GDL_SEL_SCLKMPLL 0x0 +#define MUX_GDL_SEL_SCLKAPLL 0x1 +#define CLK_SRC_LEFTBUS_VAL (MUX_GDL_SEL_SCLKMPLL) + +/* CLK_DIV_LEFTBUS */ +#define GPL_RATIO 0x1 +#define GDL_RATIO 0x3 +#define CLK_DIV_LEFTBUS_VAL ((GPL_RATIO << 4) | (GDL_RATIO)) + +/* CLK_SRC_RIGHTBUS */ +#define MUX_GDR_SEL_SCLKMPLL 0x0 +#define MUX_GDR_SEL_SCLKAPLL 0x1 +#define CLK_SRC_RIGHTBUS_VAL (MUX_GDR_SEL_SCLKMPLL) + +/* CLK_DIV_RIGHTBUS */ +#define GPR_RATIO 0x1 +#define GDR_RATIO 0x3 +#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) | (GDR_RATIO)) + +/* CLK_SRS_FSYS: 6 = SCLKMPLL */ +#define SATA_SEL_SCLKMPLL 0 +#define SATA_SEL_SCLKAPLL 1 + +#define MMC_SEL_XXTI 0 +#define MMC_SEL_XUSBXTI 1 +#define MMC_SEL_SCLK_HDMI24M 2 +#define MMC_SEL_SCLK_USBPHY0 3 +#define MMC_SEL_SCLK_USBPHY1 4 +#define MMC_SEL_SCLK_HDMIPHY 5 +#define MMC_SEL_SCLKMPLL 6 +#define MMC_SEL_SCLKEPLL 7 +#define MMC_SEL_SCLKVPLL 8 + +#define MMCC0_SEL MMC_SEL_SCLKMPLL +#define MMCC1_SEL MMC_SEL_SCLKMPLL +#define MMCC2_SEL MMC_SEL_SCLKMPLL +#define MMCC3_SEL MMC_SEL_SCLKMPLL +#define MMCC4_SEL MMC_SEL_SCLKMPLL +#define CLK_SRC_FSYS_VAL ((SATA_SEL_SCLKMPLL << 24) \ + | (MMCC4_SEL << 16) \ + | (MMCC3_SEL << 12) \ + | (MMCC2_SEL << 8) \ + | (MMCC1_SEL << 4) \ + | (MMCC0_SEL << 0)) + +/* SCLK_MMC[0-4] = MOUTMMC[0-4]/(MMC[0-4]_RATIO + 1)/(MMC[0-4]_PRE_RATIO +1) */ +/* CLK_DIV_FSYS1 */ +#define MMC0_RATIO 0xF +#define MMC0_PRE_RATIO 0x0 +#define MMC1_RATIO 0xF +#define MMC1_PRE_RATIO 0x0 +#define CLK_DIV_FSYS1_VAL ((MMC1_PRE_RATIO << 24) \ + | (MMC1_RATIO << 16) \ + | (MMC0_PRE_RATIO << 8) \ + | (MMC0_RATIO << 0)) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO 0xF +#define MMC2_PRE_RATIO 0x0 +#define MMC3_RATIO 0xF +#define MMC3_PRE_RATIO 0x0 +#define CLK_DIV_FSYS2_VAL ((MMC3_PRE_RATIO << 24) \ + | (MMC3_RATIO << 16) \ + | (MMC2_PRE_RATIO << 8) \ + | (MMC2_RATIO << 0)) + +/* CLK_DIV_FSYS3 */ +#define MMC4_RATIO 0xF +#define MMC4_PRE_RATIO 0x0 +#define CLK_DIV_FSYS3_VAL ((MMC4_PRE_RATIO << 8) \ + | (MMC4_RATIO << 0)) + +/* CLK_SRC_PERIL0 */ +#define UART_SEL_XXTI 0 +#define UART_SEL_XUSBXTI 1 +#define UART_SEL_SCLK_HDMI24M 2 +#define UART_SEL_SCLK_USBPHY0 3 +#define UART_SEL_SCLK_USBPHY1 4 +#define UART_SEL_SCLK_HDMIPHY 5 +#define UART_SEL_SCLKMPLL 6 +#define UART_SEL_SCLKEPLL 7 +#define UART_SEL_SCLKVPLL 8 + +#define UART0_SEL UART_SEL_SCLKMPLL +#define UART1_SEL UART_SEL_SCLKMPLL +#define UART2_SEL UART_SEL_SCLKMPLL +#define UART3_SEL UART_SEL_SCLKMPLL +#define UART4_SEL UART_SEL_SCLKMPLL +#define CLK_SRC_PERIL0_VAL ((UART4_SEL << 16) \ + | (UART3_SEL << 12) \ + | (UART2_SEL << 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL << 0)) + +/* SCLK_UART[0-4] = MOUTUART[0-4]/(UART[0-4]_RATIO + 1) */ +/* CLK_DIV_PERIL0 */ +#define UART0_RATIO 7 +#define UART1_RATIO 7 +#define UART2_RATIO 7 +#define UART3_RATIO 7 +#define UART4_RATIO 7 +#define CLK_DIV_PERIL0_VAL ((UART4_RATIO << 16) \ + | (UART3_RATIO << 12) \ + | (UART2_RATIO << 8) \ + | (UART1_RATIO << 4) \ + | (UART0_RATIO << 0)) + +/* Clock Source CAM/FIMC */ +/* CLK_SRC_CAM */ +#define CAM0_SEL_XUSBXTI 1 +#define CAM1_SEL_XUSBXTI 1 +#define CSIS0_SEL_XUSBXTI 1 +#define CSIS1_SEL_XUSBXTI 1 + +#define FIMC_SEL_SCLKMPLL 6 +#define FIMC0_LCLK_SEL FIMC_SEL_SCLKMPLL +#define FIMC1_LCLK_SEL FIMC_SEL_SCLKMPLL +#define FIMC2_LCLK_SEL FIMC_SEL_SCLKMPLL +#define FIMC3_LCLK_SEL FIMC_SEL_SCLKMPLL + +#define CLK_SRC_CAM_VAL ((CSIS1_SEL_XUSBXTI << 28) \ + | (CSIS0_SEL_XUSBXTI << 24) \ + | (CAM1_SEL_XUSBXTI << 20) \ + | (CAM0_SEL_XUSBXTI << 16) \ + | (FIMC3_LCLK_SEL << 12) \ + | (FIMC2_LCLK_SEL << 8) \ + | (FIMC1_LCLK_SEL << 4) \ + | (FIMC0_LCLK_SEL << 0)) + +/* SCLK CAM */ +/* CLK_DIV_CAM */ +#define FIMC0_LCLK_RATIO 4 +#define FIMC1_LCLK_RATIO 4 +#define FIMC2_LCLK_RATIO 4 +#define FIMC3_LCLK_RATIO 4 +#define CLK_DIV_CAM_VAL ((FIMC3_LCLK_RATIO << 12) \ + | (FIMC2_LCLK_RATIO << 8) \ + | (FIMC1_LCLK_RATIO << 4) \ + | (FIMC0_LCLK_RATIO << 0)) + +/* SCLK MFC */ +/* CLK_SRC_MFC */ +#define MFC_SEL_MPLL 0 +#define MOUTMFC_0 0 +#define MFC_SEL MOUTMFC_0 +#define MFC_0_SEL MFC_SEL_MPLL +#define CLK_SRC_MFC_VAL ((MFC_SEL << 8) | (MFC_0_SEL)) + + +/* CLK_DIV_MFC */ +#define MFC_RATIO 3 +#define CLK_DIV_MFC_VAL (MFC_RATIO) + +/* SCLK G3D */ +/* CLK_SRC_G3D */ +#define G3D_SEL_MPLL 0 +#define MOUTG3D_0 0 +#define G3D_SEL MOUTG3D_0 +#define G3D_0_SEL G3D_SEL_MPLL +#define CLK_SRC_G3D_VAL ((G3D_SEL << 8) | (G3D_0_SEL)) + +/* CLK_DIV_G3D */ +#define G3D_RATIO 1 +#define CLK_DIV_G3D_VAL (G3D_RATIO) + +/* SCLK LCD0 */ +/* CLK_SRC_LCD0 */ +#define FIMD_SEL_SCLKMPLL 6 +#define MDNIE0_SEL_XUSBXTI 1 +#define MDNIE_PWM0_SEL_XUSBXTI 1 +#define MIPI0_SEL_XUSBXTI 1 +#define CLK_SRC_LCD0_VAL ((MIPI0_SEL_XUSBXTI << 12) \ + | (MDNIE_PWM0_SEL_XUSBXTI << 8) \ + | (MDNIE0_SEL_XUSBXTI << 4) \ + | (FIMD_SEL_SCLKMPLL << 0)) + +/* CLK_DIV_LCD0 */ +#define FIMD0_RATIO 4 +#define CLK_DIV_LCD0_VAL (FIMD0_RATIO) + +/* Required period to generate a stable clock output */ +/* PLL_LOCK_TIME */ +#define PLL_LOCKTIME 0x1C20 + +/* PLL Values */ +#define DISABLE 0 +#define ENABLE 1 +#define SET_PLL(mdiv, pdiv, sdiv) ((ENABLE << 31)\ + | (mdiv << 16) \ + | (pdiv << 8) \ + | (sdiv << 0)) + +/* APLL_CON0 */ +#define APLL_MDIV 0xFA +#define APLL_PDIV 0x6 +#define APLL_SDIV 0x1 +#define APLL_CON0_VAL SET_PLL(APLL_MDIV, APLL_PDIV, APLL_SDIV) + +/* APLL_CON1 */ +#define APLL_AFC_ENB 0x1 +#define APLL_AFC 0xC +#define APLL_CON1_VAL ((APLL_AFC_ENB << 31) | (APLL_AFC << 0)) + +/* MPLL_CON0 */ +#define MPLL_MDIV 0xC8 +#define MPLL_PDIV 0x6 +#define MPLL_SDIV 0x1 +#define MPLL_CON0_VAL SET_PLL(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV) + +/* MPLL_CON1 */ +#define MPLL_AFC_ENB 0x0 +#define MPLL_AFC 0x1C +#define MPLL_CON1_VAL ((MPLL_AFC_ENB << 31) | (MPLL_AFC << 0)) + +/* EPLL_CON0 */ +#define EPLL_MDIV 0x30 +#define EPLL_PDIV 0x3 +#define EPLL_SDIV 0x2 +#define EPLL_CON0_VAL SET_PLL(EPLL_MDIV, EPLL_PDIV, EPLL_SDIV) + +/* EPLL_CON1 */ +#define EPLL_K 0x0 +#define EPLL_CON1_VAL (EPLL_K >> 0) + +/* VPLL_CON0 */ +#define VPLL_MDIV 0x35 +#define VPLL_PDIV 0x3 +#define VPLL_SDIV 0x2 +#define VPLL_CON0_VAL SET_PLL(VPLL_MDIV, VPLL_PDIV, VPLL_SDIV) + +/* VPLL_CON1 */ +#define VPLL_SSCG_EN DISABLE +#define VPLL_SEL_PF_DN_SPREAD 0x0 +#define VPLL_MRR 0x11 +#define VPLL_MFR 0x0 +#define VPLL_K 0x400 +#define VPLL_CON1_VAL ((VPLL_SSCG_EN << 31)\ + | (VPLL_SEL_PF_DN_SPREAD << 29) \ + | (VPLL_MRR << 24) \ + | (VPLL_MFR << 16) \ + | (VPLL_K << 0)) + +/* DMC */ +#define DIRECT_CMD_NOP 0x07000000 +#define DIRECT_CMD_ZQ 0x0a000000 +#define DIRECT_CMD_CHIP1_SHIFT (1 << 20) +#define MEM_TIMINGS_MSR_COUNT 4 +#define CTRL_START (1 << 0) +#define CTRL_DLL_ON (1 << 1) +#define AREF_EN (1 << 5) +#define DRV_TYPE (1 << 6) + +struct mem_timings { + unsigned direct_cmd_msr[MEM_TIMINGS_MSR_COUNT]; + unsigned timingref; + unsigned timingrow; + unsigned timingdata; + unsigned timingpower; + unsigned zqcontrol; + unsigned control0; + unsigned control1; + unsigned control2; + unsigned concontrol; + unsigned prechconfig; + unsigned memcontrol; + unsigned memconfig0; + unsigned memconfig1; + unsigned dll_resync; + unsigned dll_on; +}; + +/* MIU */ +/* MIU Config Register Offsets*/ +#define APB_SFR_INTERLEAVE_CONF_OFFSET 0x400 +#define APB_SFR_ARBRITATION_CONF_OFFSET 0xC00 +#define ABP_SFR_SLV_ADDRMAP_CONF_OFFSET 0x800 +#define ABP_SFR_INTERLEAVE_ADDRMAP_START_OFFSET 0x808 +#define ABP_SFR_INTERLEAVE_ADDRMAP_END_OFFSET 0x810 +#define ABP_SFR_SLV0_SINGLE_ADDRMAP_START_OFFSET 0x818 +#define ABP_SFR_SLV0_SINGLE_ADDRMAP_END_OFFSET 0x820 +#define ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET 0x828 +#define ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET 0x830 + +#ifdef CONFIG_ORIGEN +/* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */ +#define APB_SFR_INTERLEAVE_CONF_VAL 0x20001507 +#define APB_SFR_ARBRITATION_CONF_VAL 0x00000001 +#endif + +#define INTERLEAVE_ADDR_MAP_START_ADDR 0x40000000 +#define INTERLEAVE_ADDR_MAP_END_ADDR 0xbfffffff +#define INTERLEAVE_ADDR_MAP_EN 0x00000001 + +#ifdef CONFIG_MIU_1BIT_INTERLEAVED +/* Interleave_bit0: 0xC*/ +#define APB_SFR_INTERLEAVE_CONF_VAL 0x0000000c +#endif +#ifdef CONFIG_MIU_2BIT_INTERLEAVED +/* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0xc */ +#define APB_SFR_INTERLEAVE_CONF_VAL 0x2000150c +#endif +#define SLAVE0_SINGLE_ADDR_MAP_START_ADDR 0x40000000 +#define SLAVE0_SINGLE_ADDR_MAP_END_ADDR 0x7fffffff +#define SLAVE1_SINGLE_ADDR_MAP_START_ADDR 0x80000000 +#define SLAVE1_SINGLE_ADDR_MAP_END_ADDR 0xbfffffff +/* Enable SME0 and SME1*/ +#define APB_SFR_SLV_ADDR_MAP_CONF_VAL 0x00000006 + +#define FORCE_DLL_RESYNC 3 +#define DLL_CONTROL_ON 1 + +#define DIRECT_CMD1 0x00020000 +#define DIRECT_CMD2 0x00030000 +#define DIRECT_CMD3 0x00010002 +#define DIRECT_CMD4 0x00000328 + +#define CTRL_ZQ_MODE_NOTERM (0x1 << 0) +#define CTRL_ZQ_START (0x1 << 1) +#define CTRL_ZQ_DIV (0 << 4) +#define CTRL_ZQ_MODE_DDS (0x7 << 8) +#define CTRL_ZQ_MODE_TERM (0x2 << 11) +#define CTRL_ZQ_FORCE_IMPN (0x5 << 14) +#define CTRL_ZQ_FORCE_IMPP (0x6 << 17) +#define CTRL_DCC (0xE38 << 20) +#define ZQ_CONTROL_VAL (CTRL_ZQ_MODE_NOTERM | CTRL_ZQ_START\ + | CTRL_ZQ_DIV | CTRL_ZQ_MODE_DDS\ + | CTRL_ZQ_MODE_TERM | CTRL_ZQ_FORCE_IMPN\ + | CTRL_ZQ_FORCE_IMPP | CTRL_DCC) + +#define ASYNC (0 << 0) +#define CLK_RATIO (1 << 1) +#define DIV_PIPE (1 << 3) +#define AWR_ON (1 << 4) +#define AREF_DISABLE (0 << 5) +#define DRV_TYPE_DISABLE (0 << 6) +#define CHIP0_NOT_EMPTY (0 << 8) +#define CHIP1_NOT_EMPTY (0 << 9) +#define DQ_SWAP_DISABLE (0 << 10) +#define QOS_FAST_DISABLE (0 << 11) +#define RD_FETCH (0x3 << 12) +#define TIMEOUT_LEVEL0 (0xFFF << 16) +#define CONCONTROL_VAL (ASYNC | CLK_RATIO | DIV_PIPE | AWR_ON\ + | AREF_DISABLE | DRV_TYPE_DISABLE\ + | CHIP0_NOT_EMPTY | CHIP1_NOT_EMPTY\ + | DQ_SWAP_DISABLE | QOS_FAST_DISABLE\ + | RD_FETCH | TIMEOUT_LEVEL0) + +#define CLK_STOP_DISABLE (0 << 1) +#define DPWRDN_DISABLE (0 << 2) +#define DPWRDN_TYPE (0 << 3) +#define TP_DISABLE (0 << 4) +#define DSREF_DIABLE (0 << 5) +#define ADD_LAT_PALL (1 << 6) +#define MEM_TYPE_DDR3 (0x6 << 8) +#define MEM_WIDTH_32 (0x2 << 12) +#define NUM_CHIP_2 (1 << 16) +#define BL_8 (0x3 << 20) +#define MEMCONTROL_VAL (CLK_STOP_DISABLE | DPWRDN_DISABLE\ + | DPWRDN_TYPE | TP_DISABLE | DSREF_DIABLE\ + | ADD_LAT_PALL | MEM_TYPE_DDR3 | MEM_WIDTH_32\ + | NUM_CHIP_2 | BL_8) + + +#define CHIP_BANK_8 (0x3 << 0) +#define CHIP_ROW_14 (0x2 << 4) +#define CHIP_COL_10 (0x3 << 8) +#define CHIP_MAP_INTERLEAVED (1 << 12) +#define CHIP_MASK (0xe0 << 16) +#ifdef CONFIG_MIU_LINEAR +#define CHIP0_BASE (0x40 << 24) +#define CHIP1_BASE (0x60 << 24) +#else +#define CHIP0_BASE (0x20 << 24) +#define CHIP1_BASE (0x40 << 24) +#endif +#define MEMCONFIG0_VAL (CHIP_BANK_8 | CHIP_ROW_14 | CHIP_COL_10\ + | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP0_BASE) +#define MEMCONFIG1_VAL (CHIP_BANK_8 | CHIP_ROW_14 | CHIP_COL_10\ + | CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP1_BASE) + +#define TP_CNT (0xff << 24) +#define PRECHCONFIG TP_CNT + +#define CTRL_OFF (0 << 0) +#define CTRL_DLL_OFF (0 << 1) +#define CTRL_HALF (0 << 2) +#define CTRL_DFDQS (1 << 3) +#define DQS_DELAY (0 << 4) +#define CTRL_START_POINT (0x10 << 8) +#define CTRL_INC (0x10 << 16) +#define CTRL_FORCE (0x71 << 24) +#define CONTROL0_VAL (CTRL_OFF | CTRL_DLL_OFF | CTRL_HALF\ + | CTRL_DFDQS | DQS_DELAY | CTRL_START_POINT\ + | CTRL_INC | CTRL_FORCE) + +#define CTRL_SHIFTC (0x6 << 0) +#define CTRL_REF (8 << 4) +#define CTRL_SHGATE (1 << 29) +#define TERM_READ_EN (1 << 30) +#define TERM_WRITE_EN (1 << 31) +#define CONTROL1_VAL (CTRL_SHIFTC | CTRL_REF | CTRL_SHGATE\ + | TERM_READ_EN | TERM_WRITE_EN) + +#define CONTROL2_VAL 0x00000000 + +#ifdef CONFIG_ORIGEN +#define TIMINGREF_VAL 0x000000BB +#define TIMINGROW_VAL 0x4046654f +#define TIMINGDATA_VAL 0x46400506 +#define TIMINGPOWER_VAL 0x52000A3C +#else +#define TIMINGREF_VAL 0x000000BC +#ifdef DRAM_CLK_330 +#define TIMINGROW_VAL 0x3545548d +#define TIMINGDATA_VAL 0x45430506 +#define TIMINGPOWER_VAL 0x4439033c +#endif +#ifdef DRAM_CLK_400 +#define TIMINGROW_VAL 0x45430506 +#define TIMINGDATA_VAL 0x56500506 +#define TIMINGPOWER_VAL 0x5444033d +#endif +#endif +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos5_setup.h b/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos5_setup.h new file mode 100644 index 0000000..9073f50 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/exynos5_setup.h
@@ -0,0 +1,947 @@ +/* + * Machine Specific Values for SMDK5250 board based on EXYNOS5 + * + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SMDK5250_SETUP_H +#define _SMDK5250_SETUP_H + +#include <config.h> +#include <asm/arch/dmc.h> + +#define NOT_AVAILABLE 0 +#define DATA_MASK 0xFFFFF + +#define ENABLE_BIT 0x1 +#define DISABLE_BIT 0x0 +#define CA_SWAP_EN (1 << 0) + +/* Set PLL */ +#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv) + +/* MEMCONTROL register bit fields */ +#define DMC_MEMCONTROL_CLK_STOP_DISABLE (0 << 0) +#define DMC_MEMCONTROL_DPWRDN_DISABLE (0 << 1) +#define DMC_MEMCONTROL_DPWRDN_ACTIVE_PRECHARGE (0 << 2) +#define DMC_MEMCONTROL_TP_DISABLE (0 << 4) +#define DMC_MEMCONTROL_DSREF_DISABLE (0 << 5) +#define DMC_MEMCONTROL_DSREF_ENABLE (1 << 5) +#define DMC_MEMCONTROL_ADD_LAT_PALL_CYCLE(x) (x << 6) + +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR3 (7 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_DDR3 (6 << 8) +#define DMC_MEMCONTROL_MEM_TYPE_LPDDR2 (5 << 8) + +#define DMC_MEMCONTROL_MEM_WIDTH_32BIT (2 << 12) + +#define DMC_MEMCONTROL_NUM_CHIP_1 (0 << 16) +#define DMC_MEMCONTROL_NUM_CHIP_2 (1 << 16) + +#define DMC_MEMCONTROL_BL_8 (3 << 20) +#define DMC_MEMCONTROL_BL_4 (2 << 20) + +#define DMC_MEMCONTROL_PZQ_DISABLE (0 << 24) + +#define DMC_MEMCONTROL_MRR_BYTE_7_0 (0 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_15_8 (1 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_23_16 (2 << 25) +#define DMC_MEMCONTROL_MRR_BYTE_31_24 (3 << 25) + +/* MEMCONFIG0 register bit fields */ +#define DMC_MEMCONFIGX_CHIP_MAP_INTERLEAVED (1 << 12) +#define DMC_MEMCONFIG_CHIP_MAP_SPLIT (2 << 12) +#define DMC_MEMCONFIGX_CHIP_COL_10 (3 << 8) +#define DMC_MEMCONFIGX_CHIP_ROW_14 (2 << 4) +#define DMC_MEMCONFIGX_CHIP_ROW_15 (3 << 4) +#define DMC_MEMCONFIGX_CHIP_BANK_8 (3 << 0) + +#define DMC_MEMBASECONFIGX_CHIP_BASE(x) (x << 16) +#define DMC_MEMBASECONFIGX_CHIP_MASK(x) (x << 0) +#define DMC_MEMBASECONFIG_VAL(x) ( \ + DMC_MEMBASECONFIGX_CHIP_BASE(x) | \ + DMC_MEMBASECONFIGX_CHIP_MASK(0x780) \ +) + +/* + * As we use channel interleaving, therefore value of the base address + * register must be set as half of the bus base address + * RAM start addess is 0x2000_0000 which means chip_base is 0x20, so + * we need to set half 0x10 to the membaseconfigx registers + * see exynos5420 UM section 17.17.3.21 for more. + */ +#define DMC_CHIP_BASE_0 0x10 +#define DMC_CHIP_BASE_1 0x50 +#define DMC_CHIP_MASK 0x7C0 + +#define DMC_MEMBASECONFIG0_VAL DMC_MEMBASECONFIG_VAL(0x40) +#define DMC_MEMBASECONFIG1_VAL DMC_MEMBASECONFIG_VAL(0x80) + +#define DMC_PRECHCONFIG_VAL 0xFF000000 +#define DMC_PWRDNCONFIG_VAL 0xFFFF00FF + +#define DMC_CONCONTROL_RESET_VAL 0x0FFF0000 +#define DFI_INIT_START (1 << 28) +#define EMPTY (1 << 8) +#define AREF_EN (1 << 5) + +#define DFI_INIT_COMPLETE_CHO (1 << 2) +#define DFI_INIT_COMPLETE_CH1 (1 << 3) + +#define RDLVL_COMPLETE_CHO (1 << 14) +#define RDLVL_COMPLETE_CH1 (1 << 15) + +#define CLK_STOP_EN (1 << 0) +#define DPWRDN_EN (1 << 1) +#define DSREF_EN (1 << 5) + +/* COJCONTROL register bit fields */ +#define DMC_CONCONTROL_IO_PD_CON_DISABLE (0 << 3) +#define DMC_CONCONTROL_IO_PD_CON_ENABLE (1 << 3) +#define DMC_CONCONTROL_AREF_EN_DISABLE (0 << 5) +#define DMC_CONCONTROL_AREF_EN_ENABLE (1 << 5) +#define DMC_CONCONTROL_EMPTY_DISABLE (0 << 8) +#define DMC_CONCONTROL_EMPTY_ENABLE (1 << 8) +#define DMC_CONCONTROL_RD_FETCH_DISABLE (0x0 << 12) +#define DMC_CONCONTROL_TIMEOUT_LEVEL0 (0xFFF << 16) +#define DMC_CONCONTROL_DFI_INIT_START_DISABLE (0 << 28) + +#define DMC_CONCONTROL_VAL 0x1FFF2101 + +#define DREX_CONCONTROL_VAL DMC_CONCONTROL_VAL \ + | DMC_CONCONTROL_AREF_EN_ENABLE \ + | DMC_CONCONTROL_IO_PD_CON_ENABLE + +#define DMC_CONCONTROL_IO_PD_CON(x) (x << 6) + +/* CLK_DIV_CPU1 */ +#define HPM_RATIO 0x2 +#define COPY_RATIO 0x0 + +/* CLK_DIV_CPU1 = 0x00000003 */ +#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \ + | (COPY_RATIO)) + +/* CLK_SRC_CORE0 */ +#define CLK_SRC_CORE0_VAL 0x00000000 + +/* CLK_SRC_CORE1 */ +#define CLK_SRC_CORE1_VAL 0x100 + +/* CLK_DIV_CORE0 */ +#define CLK_DIV_CORE0_VAL 0x00120000 + +/* CLK_DIV_CORE1 */ +#define CLK_DIV_CORE1_VAL 0x07070700 + +/* CLK_DIV_SYSRGT */ +#define CLK_DIV_SYSRGT_VAL 0x00000111 + +/* CLK_DIV_ACP */ +#define CLK_DIV_ACP_VAL 0x12 + +/* CLK_DIV_SYSLFT */ +#define CLK_DIV_SYSLFT_VAL 0x00000311 + +#define MUX_APLL_SEL_MASK (1 << 0) +#define MUX_MPLL_SEL_MASK (1 << 8) +#define MPLL_SEL_MOUT_MPLLFOUT (2 << 8) +#define MUX_CPLL_SEL_MASK (1 << 8) +#define MUX_EPLL_SEL_MASK (1 << 12) +#define MUX_VPLL_SEL_MASK (1 << 16) +#define MUX_GPLL_SEL_MASK (1 << 28) +#define MUX_BPLL_SEL_MASK (1 << 0) +#define MUX_HPM_SEL_MASK (1 << 20) +#define HPM_SEL_SCLK_MPLL (1 << 21) +#define PLL_LOCKED (1 << 29) +#define APLL_CON0_LOCKED (1 << 29) +#define MPLL_CON0_LOCKED (1 << 29) +#define BPLL_CON0_LOCKED (1 << 29) +#define CPLL_CON0_LOCKED (1 << 29) +#define EPLL_CON0_LOCKED (1 << 29) +#define GPLL_CON0_LOCKED (1 << 29) +#define VPLL_CON0_LOCKED (1 << 29) +#define CLK_REG_DISABLE 0x0 +#define TOP2_VAL 0x0110000 + +/* SCLK_SRC_ISP - set SPI0/1 to 6 = SCLK_MPLL_USER */ +#define SPI0_ISP_SEL 6 +#define SPI1_ISP_SEL 6 +#define SCLK_SRC_ISP_VAL (SPI1_ISP_SEL << 4) \ + | (SPI0_ISP_SEL << 0) + +/* SCLK_DIV_ISP - set SPI0/1 to 0xf = divide by 16 */ +#define SPI0_ISP_RATIO 0xf +#define SPI1_ISP_RATIO 0xf +#define SCLK_DIV_ISP_VAL (SPI1_ISP_RATIO << 12) \ + | (SPI0_ISP_RATIO << 0) + +/* CLK_DIV_FSYS2 */ +#define MMC2_RATIO_MASK 0xf +#define MMC2_RATIO_VAL 0x3 +#define MMC2_RATIO_OFFSET 0 + +#define MMC2_PRE_RATIO_MASK 0xff +#define MMC2_PRE_RATIO_VAL 0x9 +#define MMC2_PRE_RATIO_OFFSET 8 + +#define MMC3_RATIO_MASK 0xf +#define MMC3_RATIO_VAL 0x1 +#define MMC3_RATIO_OFFSET 16 + +#define MMC3_PRE_RATIO_MASK 0xff +#define MMC3_PRE_RATIO_VAL 0x0 +#define MMC3_PRE_RATIO_OFFSET 24 + +/* CLK_SRC_LEX */ +#define CLK_SRC_LEX_VAL 0x0 + +/* CLK_DIV_LEX */ +#define CLK_DIV_LEX_VAL 0x10 + +/* CLK_DIV_R0X */ +#define CLK_DIV_R0X_VAL 0x10 + +/* CLK_DIV_L0X */ +#define CLK_DIV_R1X_VAL 0x10 + +/* CLK_DIV_ISP2 */ +#define CLK_DIV_ISP2_VAL 0x1 + +/* CLK_SRC_KFC */ +#define SRC_KFC_HPM_SEL (1 << 15) + +/* CLK_SRC_KFC */ +#define CLK_SRC_KFC_VAL 0x00008001 + +/* CLK_DIV_KFC */ +#define CLK_DIV_KFC_VAL 0x03300110 + +/* CLK_DIV2_RATIO */ +#define CLK_DIV2_RATIO 0x10111150 + +/* CLK_DIV4_RATIO */ +#define CLK_DIV4_RATIO 0x00000003 + +/* CLK_DIV_G2D */ +#define CLK_DIV_G2D 0x00000010 + +/* + * DIV_DISP1_0 + * For DP, divisor should be 2 + */ +#define CLK_DIV_DISP1_0_FIMD1 (2 << 0) + +/* CLK_GATE_IP_DISP1 */ +#define CLK_GATE_DP1_ALLOW (1 << 4) + +/* AUDIO CLK SEL */ +#define AUDIO0_SEL_EPLL (0x6 << 28) +#define AUDIO0_RATIO 0x5 +#define PCM0_RATIO 0x3 +#define DIV_MAU_VAL (PCM0_RATIO << 24 | AUDIO0_RATIO << 20) + +/* CLK_SRC_CDREX */ +#define MUX_MCLK_CDR_MSPLL (1 << 4) +#define MUX_BPLL_SEL_FOUTBPLL (1 << 0) +#define BPLL_SEL_MASK 0x7 +#define FOUTBPLL 2 + +#define DDR3PHY_CTRL_PHY_RESET (1 << 0) +#define DDR3PHY_CTRL_PHY_RESET_OFF (0 << 0) + +#define PHY_CON0_RESET_VAL 0x17020a40 +#define P0_CMD_EN (1 << 14) +#define BYTE_RDLVL_EN (1 << 13) +#define CTRL_SHGATE (1 << 8) + +#define PHY_CON1_RESET_VAL 0x09210100 +#define RDLVL_PASS_ADJ_VAL 0x6 +#define RDLVL_PASS_ADJ_OFFSET 16 +#define CTRL_GATEDURADJ_MASK (0xf << 20) +#define READ_LEVELLING_DDR3 0x0100 + +#define PHY_CON2_RESET_VAL 0x00010004 +#define INIT_DESKEW_EN (1 << 6) +#define DLL_DESKEW_EN (1 << 12) +#define RDLVL_GATE_EN (1 << 24) +#define RDLVL_EN (1 << 25) +#define RDLVL_INCR_ADJ (0x1 << 16) + +/* DREX_PAUSE */ +#define DREX_PAUSE_EN (1 << 0) + +#define BYPASS_EN (1 << 22) + +/* MEMMORY VAL */ +#define PHY_CON0_VAL 0x17021A00 + +#define PHY_CON12_RESET_VAL 0x10100070 +#define PHY_CON12_VAL 0x10107F50 +#define CTRL_START (1 << 6) +#define CTRL_DLL_ON (1 << 5) +#define CTRL_LOCK_COARSE_OFFSET 10 +#define CTRL_LOCK_COARSE_MASK (0x7F << CTRL_LOCK_COARSE_OFFSET) +#define CTRL_LOCK_COARSE(x) (((x) & CTRL_LOCK_COARSE_MASK) >> \ + CTRL_LOCK_COARSE_OFFSET) +#define CTRL_FORCE_MASK (0x7F << 8) +#define CTRL_FINE_LOCKED 0x7 + +#define CTRL_OFFSETD_RESET_VAL 0x8 +#define CTRL_OFFSETD_VAL 0x7F + +#define CTRL_OFFSETR0 0x7F +#define CTRL_OFFSETR1 0x7F +#define CTRL_OFFSETR2 0x7F +#define CTRL_OFFSETR3 0x7F +#define PHY_CON4_VAL (CTRL_OFFSETR0 << 0 | \ + CTRL_OFFSETR1 << 8 | \ + CTRL_OFFSETR2 << 16 | \ + CTRL_OFFSETR3 << 24) +#define PHY_CON4_RESET_VAL 0x08080808 + +#define CTRL_OFFSETW0 0x7F +#define CTRL_OFFSETW1 0x7F +#define CTRL_OFFSETW2 0x7F +#define CTRL_OFFSETW3 0x7F +#define PHY_CON6_VAL (CTRL_OFFSETW0 << 0 | \ + CTRL_OFFSETW1 << 8 | \ + CTRL_OFFSETW2 << 16 | \ + CTRL_OFFSETW3 << 24) +#define PHY_CON6_RESET_VAL 0x08080808 + +#define PHY_CON14_RESET_VAL 0x001F0000 +#define CTRL_PULLD_DQS 0xF +#define CTRL_PULLD_DQS_OFFSET 0 + +/* ZQ Configurations */ +#define PHY_CON16_RESET_VAL 0x08000304 + +#define ZQ_CLK_EN (1 << 27) +#define ZQ_CLK_DIV_EN (1 << 18) +#define ZQ_MANUAL_STR (1 << 1) +#define ZQ_DONE (1 << 0) +#define ZQ_MODE_DDS_OFFSET 24 + +#define CTRL_RDLVL_GATE_ENABLE 1 +#define CTRL_RDLVL_GATE_DISABLE 0 +#define CTRL_RDLVL_DATA_ENABLE 2 + +/* Direct Command */ +#define DIRECT_CMD_NOP 0x07000000 +#define DIRECT_CMD_PALL 0x01000000 +#define DIRECT_CMD_ZQINIT 0x0a000000 +#define DIRECT_CMD_CHANNEL_SHIFT 28 +#define DIRECT_CMD_CHIP_SHIFT 20 +#define DIRECT_CMD_BANK_SHIFT 16 +#define DIRECT_CMD_REFA (5 << 24) +#define DIRECT_CMD_MRS1 0x71C00 +#define DIRECT_CMD_MRS2 0x10BFC +#define DIRECT_CMD_MRS3 0x0050C +#define DIRECT_CMD_MRS4 0x00868 +#define DIRECT_CMD_MRS5 0x00C04 + +/* Drive Strength */ +#define IMPEDANCE_48_OHM 4 +#define IMPEDANCE_40_OHM 5 +#define IMPEDANCE_34_OHM 6 +#define IMPEDANCE_30_OHM 7 +#define PHY_CON39_VAL_48_OHM 0x09240924 +#define PHY_CON39_VAL_40_OHM 0x0B6D0B6D +#define PHY_CON39_VAL_34_OHM 0x0DB60DB6 +#define PHY_CON39_VAL_30_OHM 0x0FFF0FFF + +#define CTRL_BSTLEN_OFFSET 8 +#define CTRL_RDLAT_OFFSET 0 + +#define CMD_DEFAULT_LPDDR3 0xF +#define CMD_DEFUALT_OFFSET 0 +#define T_WRDATA_EN 0x7 +#define T_WRDATA_EN_DDR3 0x8 +#define T_WRDATA_EN_OFFSET 16 +#define T_WRDATA_EN_MASK 0x1f + +#define PHY_CON31_VAL 0x0C183060 +#define PHY_CON32_VAL 0x60C18306 +#define PHY_CON33_VAL 0x00000030 + +#define PHY_CON31_RESET_VAL 0x0 +#define PHY_CON32_RESET_VAL 0x0 +#define PHY_CON33_RESET_VAL 0x0 + +#define SL_DLL_DYN_CON_EN (1 << 1) +#define FP_RESYNC (1 << 3) +#define CTRL_START (1 << 6) + +#define DMC_AREF_EN (1 << 5) +#define DMC_CONCONTROL_EMPTY (1 << 8) +#define DFI_INIT_START (1 << 28) + +#define DMC_MEMCONTROL_VAL 0x00312700 +#define CLK_STOP_EN (1 << 0) +#define DPWRDN_EN (1 << 1) +#define DSREF_EN (1 << 5) + +#define MEMBASECONFIG_CHIP_MASK_VAL 0x7E0 +#define MEMBASECONFIG_CHIP_MASK_OFFSET 0 +#define MEMBASECONFIG0_CHIP_BASE_VAL 0x20 +#define MEMBASECONFIG1_CHIP_BASE_VAL 0x40 +#define CHIP_BASE_OFFSET 16 + +#define MEMCONFIG_VAL 0x1323 +#define PRECHCONFIG_DEFAULT_VAL 0xFF000000 +#define PWRDNCONFIG_DEFAULT_VAL 0xFFFF00FF + +#define TIMINGAREF_VAL 0x5d +#define TIMINGROW_VAL 0x345A8692 +#define TIMINGDATA_VAL 0x3630065C +#define TIMINGPOWER_VAL 0x50380336 +#define DFI_INIT_COMPLETE (1 << 3) + +#define BRBRSVCONTROL_VAL 0x00000033 +#define BRBRSVCONFIG_VAL 0x88778877 + +/* Clock Gating Control (CGCONTROL) register */ +#define MEMIF_CG_EN (1 << 3) /* Memory interface clock gating */ +#define SCG_CG_EN (1 << 2) /* Scheduler clock gating */ +#define BUSIF_WR_CG_EN (1 << 1) /* Bus interface write channel clock gating */ +#define BUSIF_RD_CG_EN (1 << 0) /* Bus interface read channel clock gating */ +#define DMC_INTERNAL_CG (MEMIF_CG_EN | SCG_CG_EN | \ + BUSIF_WR_CG_EN | BUSIF_RD_CG_EN) + +/* DMC PHY Control0 register */ +#define PHY_CONTROL0_RESET_VAL 0x0 +#define MEM_TERM_EN (1 << 31) /* Termination enable for memory */ +#define PHY_TERM_EN (1 << 30) /* Termination enable for PHY */ +#define DMC_CTRL_SHGATE (1 << 29) /* Duration of DQS gating signal */ +#define FP_RSYNC (1 << 3) /* Force DLL resyncronization */ + +/* Driver strength for CK, CKE, CS & CA */ +#define IMP_OUTPUT_DRV_40_OHM 0x5 +#define IMP_OUTPUT_DRV_30_OHM 0x7 +#define DA_3_DS_OFFSET 25 +#define DA_2_DS_OFFSET 22 +#define DA_1_DS_OFFSET 19 +#define DA_0_DS_OFFSET 16 +#define CA_CK_DRVR_DS_OFFSET 9 +#define CA_CKE_DRVR_DS_OFFSET 6 +#define CA_CS_DRVR_DS_OFFSET 3 +#define CA_ADR_DRVR_DS_OFFSET 0 + +#define PHY_CON42_CTRL_BSTLEN_SHIFT 8 +#define PHY_CON42_CTRL_RDLAT_SHIFT 0 + +/* + * Definitions that differ with SoC's. + * Below is the part defining macros for Exynos5250. + * Else part introduces macros for Exynos5420. + */ +#ifndef CONFIG_EXYNOS5420 + +/* APLL_CON1 */ +#define APLL_CON1_VAL (0x00203800) + +/* MPLL_CON1 */ +#define MPLL_CON1_VAL (0x00203800) + +/* CPLL_CON1 */ +#define CPLL_CON1_VAL (0x00203800) + +/* DPLL_CON1 */ +#define DPLL_CON1_VAL (NOT_AVAILABLE) + +/* GPLL_CON1 */ +#define GPLL_CON1_VAL (0x00203800) + +/* EPLL_CON1, CON2 */ +#define EPLL_CON1_VAL 0x00000000 +#define EPLL_CON2_VAL 0x00000080 + +/* VPLL_CON1, CON2 */ +#define VPLL_CON1_VAL 0x00000000 +#define VPLL_CON2_VAL 0x00000080 + +/* RPLL_CON1, CON2 */ +#define RPLL_CON1_VAL NOT_AVAILABLE +#define RPLL_CON2_VAL NOT_AVAILABLE + +/* BPLL_CON1 */ +#define BPLL_CON1_VAL 0x00203800 + +/* SPLL_CON1 */ +#define SPLL_CON1_VAL NOT_AVAILABLE + +/* IPLL_CON1 */ +#define IPLL_CON1_VAL NOT_AVAILABLE + +/* KPLL_CON1 */ +#define KPLL_CON1_VAL NOT_AVAILABLE + +/* CLK_SRC_ISP */ +#define CLK_SRC_ISP_VAL NOT_AVAILABLE +#define CLK_DIV_ISP0_VAL 0x31 +#define CLK_DIV_ISP1_VAL 0x0 + +/* CLK_FSYS */ +#define CLK_SRC_FSYS0_VAL 0x66666 +#define CLK_DIV_FSYS0_VAL 0x0BB00000 +#define CLK_DIV_FSYS1_VAL NOT_AVAILABLE +#define CLK_DIV_FSYS2_VAL NOT_AVAILABLE + +/* CLK_SRC_CPU */ +/* 0 = MOUTAPLL, 1 = SCLKMPLL */ +#define MUX_HPM_SEL 0 +#define MUX_CPU_SEL 0 +#define MUX_APLL_SEL 1 + +#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \ + | (MUX_CPU_SEL << 16) \ + | (MUX_APLL_SEL)) + +/* CLK_SRC_CDREX */ +#define CLK_SRC_CDREX_VAL 0x1 + +/* CLK_DIV_CDREX */ +#define CLK_DIV_CDREX0_VAL NOT_AVAILABLE +#define CLK_DIV_CDREX1_VAL NOT_AVAILABLE + +/* CLK_DIV_CPU0_VAL */ +#define CLK_DIV_CPU0_VAL NOT_AVAILABLE + +#define MCLK_CDREX2_RATIO 0x0 +#define ACLK_EFCON_RATIO 0x1 +#define MCLK_DPHY_RATIO 0x1 +#define MCLK_CDREX_RATIO 0x1 +#define ACLK_C2C_200_RATIO 0x1 +#define C2C_CLK_400_RATIO 0x1 +#define PCLK_CDREX_RATIO 0x1 +#define ACLK_CDREX_RATIO 0x1 + +#define CLK_DIV_CDREX_VAL ((MCLK_DPHY_RATIO << 24) \ + | (C2C_CLK_400_RATIO << 6) \ + | (PCLK_CDREX_RATIO << 4) \ + | (ACLK_CDREX_RATIO)) + +/* CLK_SRC_TOP0 */ +#define MUX_ACLK_300_GSCL_SEL 0x0 +#define MUX_ACLK_300_GSCL_MID_SEL 0x0 +#define MUX_ACLK_400_G3D_MID_SEL 0x0 +#define MUX_ACLK_333_SEL 0x0 +#define MUX_ACLK_300_DISP1_SEL 0x0 +#define MUX_ACLK_300_DISP1_MID_SEL 0x0 +#define MUX_ACLK_200_SEL 0x0 +#define MUX_ACLK_166_SEL 0x0 +#define CLK_SRC_TOP0_VAL ((MUX_ACLK_300_GSCL_SEL << 25) \ + | (MUX_ACLK_300_GSCL_MID_SEL << 24) \ + | (MUX_ACLK_400_G3D_MID_SEL << 20) \ + | (MUX_ACLK_333_SEL << 16) \ + | (MUX_ACLK_300_DISP1_SEL << 15) \ + | (MUX_ACLK_300_DISP1_MID_SEL << 14) \ + | (MUX_ACLK_200_SEL << 12) \ + | (MUX_ACLK_166_SEL << 8)) + +/* CLK_SRC_TOP1 */ +#define MUX_ACLK_400_G3D_SEL 0x1 +#define MUX_ACLK_400_ISP_SEL 0x0 +#define MUX_ACLK_400_IOP_SEL 0x0 +#define MUX_ACLK_MIPI_HSI_TXBASE_SEL 0x0 +#define MUX_ACLK_300_GSCL_MID1_SEL 0x0 +#define MUX_ACLK_300_DISP1_MID1_SEL 0x0 +#define CLK_SRC_TOP1_VAL ((MUX_ACLK_400_G3D_SEL << 28) \ + |(MUX_ACLK_400_ISP_SEL << 24) \ + |(MUX_ACLK_400_IOP_SEL << 20) \ + |(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16) \ + |(MUX_ACLK_300_GSCL_MID1_SEL << 12) \ + |(MUX_ACLK_300_DISP1_MID1_SEL << 8)) + +/* CLK_SRC_TOP2 */ +#define MUX_GPLL_SEL 0x1 +#define MUX_BPLL_USER_SEL 0x0 +#define MUX_MPLL_USER_SEL 0x0 +#define MUX_VPLL_SEL 0x1 +#define MUX_EPLL_SEL 0x1 +#define MUX_CPLL_SEL 0x1 +#define VPLLSRC_SEL 0x0 +#define CLK_SRC_TOP2_VAL ((MUX_GPLL_SEL << 28) \ + | (MUX_BPLL_USER_SEL << 24) \ + | (MUX_MPLL_USER_SEL << 20) \ + | (MUX_VPLL_SEL << 16) \ + | (MUX_EPLL_SEL << 12) \ + | (MUX_CPLL_SEL << 8) \ + | (VPLLSRC_SEL)) +/* CLK_SRC_TOP3 */ +#define MUX_ACLK_333_SUB_SEL 0x1 +#define MUX_ACLK_400_SUB_SEL 0x1 +#define MUX_ACLK_266_ISP_SUB_SEL 0x1 +#define MUX_ACLK_266_GPS_SUB_SEL 0x0 +#define MUX_ACLK_300_GSCL_SUB_SEL 0x1 +#define MUX_ACLK_266_GSCL_SUB_SEL 0x1 +#define MUX_ACLK_300_DISP1_SUB_SEL 0x1 +#define MUX_ACLK_200_DISP1_SUB_SEL 0x1 +#define CLK_SRC_TOP3_VAL ((MUX_ACLK_333_SUB_SEL << 24) \ + | (MUX_ACLK_400_SUB_SEL << 20) \ + | (MUX_ACLK_266_ISP_SUB_SEL << 16) \ + | (MUX_ACLK_266_GPS_SUB_SEL << 12) \ + | (MUX_ACLK_300_GSCL_SUB_SEL << 10) \ + | (MUX_ACLK_266_GSCL_SUB_SEL << 8) \ + | (MUX_ACLK_300_DISP1_SUB_SEL << 6) \ + | (MUX_ACLK_200_DISP1_SUB_SEL << 4)) + +#define CLK_SRC_TOP4_VAL NOT_AVAILABLE +#define CLK_SRC_TOP5_VAL NOT_AVAILABLE +#define CLK_SRC_TOP6_VAL NOT_AVAILABLE +#define CLK_SRC_TOP7_VAL NOT_AVAILABLE + +/* CLK_DIV_TOP0 */ +#define ACLK_300_DISP1_RATIO 0x2 +#define ACLK_400_G3D_RATIO 0x0 +#define ACLK_333_RATIO 0x0 +#define ACLK_266_RATIO 0x2 +#define ACLK_200_RATIO 0x3 +#define ACLK_166_RATIO 0x1 +#define ACLK_133_RATIO 0x1 +#define ACLK_66_RATIO 0x5 + +#define CLK_DIV_TOP0_VAL ((ACLK_300_DISP1_RATIO << 28) \ + | (ACLK_400_G3D_RATIO << 24) \ + | (ACLK_333_RATIO << 20) \ + | (ACLK_266_RATIO << 16) \ + | (ACLK_200_RATIO << 12) \ + | (ACLK_166_RATIO << 8) \ + | (ACLK_133_RATIO << 4) \ + | (ACLK_66_RATIO)) + +/* CLK_DIV_TOP1 */ +#define ACLK_MIPI_HSI_TX_BASE_RATIO 0x3 +#define ACLK_66_PRE_RATIO 0x1 +#define ACLK_400_ISP_RATIO 0x1 +#define ACLK_400_IOP_RATIO 0x1 +#define ACLK_300_GSCL_RATIO 0x2 + +#define CLK_DIV_TOP1_VAL ((ACLK_MIPI_HSI_TX_BASE_RATIO << 28) \ + | (ACLK_66_PRE_RATIO << 24) \ + | (ACLK_400_ISP_RATIO << 20) \ + | (ACLK_400_IOP_RATIO << 16) \ + | (ACLK_300_GSCL_RATIO << 12)) + +#define CLK_DIV_TOP2_VAL NOT_AVAILABLE + +/* PLL Lock Value Factor */ +#define PLL_LOCK_FACTOR 250 +#define PLL_X_LOCK_FACTOR 3000 + +/* CLK_SRC_PERIC0 */ +#define PWM_SEL 6 +#define UART3_SEL 6 +#define UART2_SEL 6 +#define UART1_SEL 6 +#define UART0_SEL 6 +/* SRC_CLOCK = SCLK_MPLL */ +#define CLK_SRC_PERIC0_VAL ((PWM_SEL << 24) \ + | (UART3_SEL << 12) \ + | (UART2_SEL << 8) \ + | (UART1_SEL << 4) \ + | (UART0_SEL)) + +/* CLK_SRC_PERIC1 */ +/* SRC_CLOCK = SCLK_MPLL */ +#define SPI0_SEL 6 +#define SPI1_SEL 6 +#define SPI2_SEL 6 +#define CLK_SRC_PERIC1_VAL ((SPI2_SEL << 24) \ + | (SPI1_SEL << 20) \ + | (SPI0_SEL << 16)) + +/* CLK_DIV_PERIL0 */ +#define UART5_RATIO 7 +#define UART4_RATIO 7 +#define UART3_RATIO 7 +#define UART2_RATIO 7 +#define UART1_RATIO 7 +#define UART0_RATIO 7 + +#define CLK_DIV_PERIC0_VAL ((UART3_RATIO << 12) \ + | (UART2_RATIO << 8) \ + | (UART1_RATIO << 4) \ + | (UART0_RATIO)) +/* CLK_DIV_PERIC1 */ +#define SPI1_RATIO 0x7 +#define SPI0_RATIO 0xf +#define SPI1_SUB_RATIO 0x0 +#define SPI0_SUB_RATIO 0x0 +#define CLK_DIV_PERIC1_VAL ((SPI1_SUB_RATIO << 24) \ + | ((SPI1_RATIO << 16) \ + | (SPI0_SUB_RATIO << 8) \ + | (SPI0_RATIO << 0))) + +/* CLK_DIV_PERIC2 */ +#define SPI2_RATIO 0xf +#define SPI2_SUB_RATIO 0x0 +#define CLK_DIV_PERIC2_VAL ((SPI2_SUB_RATIO << 8) \ + | (SPI2_RATIO << 0)) + +/* CLK_DIV_PERIC3 */ +#define PWM_RATIO 8 +#define CLK_DIV_PERIC3_VAL (PWM_RATIO << 0) + + +/* CLK_DIV_PERIC4 */ +#define CLK_DIV_PERIC4_VAL NOT_AVAILABLE + +/* CLK_SRC_DISP1_0 */ +#define CLK_SRC_DISP1_0_VAL 0x6 +#define CLK_DIV_DISP1_0_VAL NOT_AVAILABLE + +#define APLL_FOUT (1 << 0) +#define KPLL_FOUT NOT_AVAILABLE + +#define CLK_DIV_CPERI1_VAL NOT_AVAILABLE + +#else + +#define CPU_CONFIG_STATUS_OFFSET 0x80 +#define CPU_RST_FLAG_VAL 0xFCBA0D10 +#define PAD_RETENTION_DRAM_COREBLK_VAL 0x10000000 + +/* APLL_CON1 */ +#define APLL_CON1_VAL (0x0020F300) + +/* MPLL_CON1 */ +#define MPLL_CON1_VAL (0x0020F300) + + +/* CPLL_CON1 */ +#define CPLL_CON1_VAL 0x0020f300 + +/* DPLL_CON1 */ +#define DPLL_CON1_VAL (0x0020F300) + +/* GPLL_CON1 */ +#define GPLL_CON1_VAL (NOT_AVAILABLE) + + +/* EPLL_CON1, CON2 */ +#define EPLL_CON1_VAL 0x00000000 +#define EPLL_CON2_VAL 0x00000080 + +/* VPLL_CON1, CON2 */ +#define VPLL_CON1_VAL 0x0020f300 +#define VPLL_CON2_VAL NOT_AVAILABLE + +/* RPLL_CON1, CON2 */ +#define RPLL_CON1_VAL 0x00000000 +#define RPLL_CON2_VAL 0x00000080 + +/* BPLL_CON1 */ +#define BPLL_CON1_VAL 0x0020f300 + +/* SPLL_CON1 */ +#define SPLL_CON1_VAL 0x0020f300 + +/* IPLL_CON1 */ +#define IPLL_CON1_VAL 0x00000080 + +/* KPLL_CON1 */ +#define KPLL_CON1_VAL 0x200000 + +/* CLK_SRC_ISP */ +#define CLK_SRC_ISP_VAL 0x33366000 +#define CLK_DIV_ISP0_VAL 0x13131300 +#define CLK_DIV_ISP1_VAL 0xbb110202 + + +/* CLK_FSYS */ +#define CLK_SRC_FSYS0_VAL 0x33033300 +#define CLK_DIV_FSYS0_VAL 0x0 +#define CLK_DIV_FSYS1_VAL 0x04f13c4f +#define CLK_DIV_FSYS2_VAL 0x041d0000 + +/* CLK_SRC_CPU */ +/* 0 = MOUTAPLL, 1 = SCLKMPLL */ +#define MUX_HPM_SEL 1 +#define MUX_CPU_SEL 0 +#define MUX_APLL_SEL 1 + +#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \ + | (MUX_CPU_SEL << 16) \ + | (MUX_APLL_SEL)) + +/* CLK_SRC_CDREX */ +#define CLK_SRC_CDREX_VAL 0x00000011 + +/* CLK_DIV_CDREX */ +#define CLK_DIV_CDREX0_VAL 0x30010100 +#define CLK_DIV_CDREX1_VAL 0x300 + +#define CLK_DIV_CDREX_VAL 0x17010100 + +/* CLK_DIV_CPU0_VAL */ +#define CLK_DIV_CPU0_VAL 0x01440020 + +/* CLK_SRC_TOP */ +#define CLK_SRC_TOP0_VAL 0x12221222 +#define CLK_SRC_TOP1_VAL 0x00100200 +#define CLK_SRC_TOP2_VAL 0x11101000 +#define CLK_SRC_TOP3_VAL 0x11111111 +#define CLK_SRC_TOP4_VAL 0x11110111 +#define CLK_SRC_TOP5_VAL 0x11111101 +#define CLK_SRC_TOP6_VAL 0x11110111 +#define CLK_SRC_TOP7_VAL 0x00022200 + +/* CLK_DIV_TOP */ +#define CLK_DIV_TOP0_VAL 0x23712311 +#define CLK_DIV_TOP1_VAL 0x13100B00 +#define CLK_DIV_TOP2_VAL 0x11101100 + +/* PLL Lock Value Factor */ +#define PLL_LOCK_FACTOR 200 +#define PLL_X_LOCK_FACTOR 3000 + +/* CLK_SRC_PERIC0 */ +#define SPDIF_SEL 1 +#define PWM_SEL 3 +#define UART4_SEL 3 +#define UART3_SEL 3 +#define UART2_SEL 3 +#define UART1_SEL 3 +#define UART0_SEL 3 +/* SRC_CLOCK = SCLK_RPLL */ +#define CLK_SRC_PERIC0_VAL ((SPDIF_SEL << 28) \ + | (PWM_SEL << 24) \ + | (UART4_SEL << 20) \ + | (UART3_SEL << 16) \ + | (UART2_SEL << 12) \ + | (UART1_SEL << 8) \ + | (UART0_SEL << 4)) + +/* CLK_SRC_PERIC1 */ +/* SRC_CLOCK = SCLK_EPLL */ +#define SPI0_SEL 6 +#define SPI1_SEL 6 +#define SPI2_SEL 6 +#define AUDIO0_SEL 6 +#define AUDIO1_SEL 6 +#define AUDIO2_SEL 6 +#define CLK_SRC_PERIC1_VAL ((SPI2_SEL << 28) \ + | (SPI1_SEL << 24) \ + | (SPI0_SEL << 20) \ + | (AUDIO2_SEL << 16) \ + | (AUDIO2_SEL << 12) \ + | (AUDIO2_SEL << 8)) + +/* CLK_DIV_PERIC0 */ +#define PWM_RATIO 8 +#define UART4_RATIO 9 +#define UART3_RATIO 9 +#define UART2_RATIO 9 +#define UART1_RATIO 9 +#define UART0_RATIO 9 + +#define CLK_DIV_PERIC0_VAL ((PWM_RATIO << 28) \ + | (UART4_RATIO << 24) \ + | (UART3_RATIO << 20) \ + | (UART2_RATIO << 16) \ + | (UART1_RATIO << 12) \ + | (UART0_RATIO << 8)) +/* CLK_DIV_PERIC1 */ +#define SPI2_RATIO 0x1 +#define SPI1_RATIO 0x1 +#define SPI0_RATIO 0x1 +#define CLK_DIV_PERIC1_VAL ((SPI2_RATIO << 28) \ + | (SPI1_RATIO << 24) \ + | (SPI0_RATIO << 20)) + +/* CLK_DIV_PERIC2 */ +#define PCM2_RATIO 0x3 +#define PCM1_RATIO 0x3 +#define CLK_DIV_PERIC2_VAL ((PCM2_RATIO << 24) \ + | (PCM1_RATIO << 16)) + +/* CLK_DIV_PERIC3 */ +#define AUDIO2_RATIO 0x5 +#define AUDIO1_RATIO 0x5 +#define AUDIO0_RATIO 0x5 +#define CLK_DIV_PERIC3_VAL ((AUDIO2_RATIO << 28) \ + | (AUDIO1_RATIO << 24) \ + | (AUDIO0_RATIO << 20)) + +/* CLK_DIV_PERIC4 */ +#define SPI2_PRE_RATIO 0x2 +#define SPI1_PRE_RATIO 0x2 +#define SPI0_PRE_RATIO 0x2 +#define CLK_DIV_PERIC4_VAL ((SPI2_PRE_RATIO << 24) \ + | (SPI1_PRE_RATIO << 16) \ + | (SPI0_PRE_RATIO << 8)) + +/* CLK_SRC_DISP1_0 */ +#define CLK_SRC_DISP1_0_VAL 0x10666600 +#define CLK_DIV_DISP1_0_VAL 0x01050211 + +#define APLL_FOUT (1 << 0) +#define KPLL_FOUT (1 << 0) + +#define CLK_DIV_CPERI1_VAL 0x3f3f0000 +#endif + +struct mem_timings; + +/* Errors that we can encourter in low-level setup */ +enum { + SETUP_ERR_OK, + SETUP_ERR_RDLV_COMPLETE_TIMEOUT = -1, + SETUP_ERR_ZQ_CALIBRATION_FAILURE = -2, +}; + +/* + * Memory variant specific initialization code for DDR3 + * + * @param mem Memory timings for this memory type. + * @param reset Reset DDR PHY during initialization. + * @return 0 if ok, SETUP_ERR_... if there is a problem + */ +int ddr3_mem_ctrl_init(struct mem_timings *mem, int reset); + +/* Memory variant specific initialization code for LPDDR3 */ +void lpddr3_mem_ctrl_init(void); + +/* + * Configure ZQ I/O interface + * + * @param mem Memory timings for this memory type. + * @param phy0_con16 Register address for dmc_phy0->phy_con16 + * @param phy1_con16 Register address for dmc_phy1->phy_con16 + * @param phy0_con17 Register address for dmc_phy0->phy_con17 + * @param phy1_con17 Register address for dmc_phy1->phy_con17 + * @return 0 if ok, -1 on error + */ +int dmc_config_zq(struct mem_timings *mem, uint32_t *phy0_con16, + uint32_t *phy1_con16, uint32_t *phy0_con17, + uint32_t *phy1_con17); +/* + * Send NOP and MRS/EMRS Direct commands + * + * @param mem Memory timings for this memory type. + * @param directcmd Register address for dmc_phy->directcmd + */ +void dmc_config_mrs(struct mem_timings *mem, uint32_t *directcmd); + +/* + * Send PALL Direct commands + * + * @param mem Memory timings for this memory type. + * @param directcmd Register address for dmc_phy->directcmd + */ +void dmc_config_prech(struct mem_timings *mem, uint32_t *directcmd); + +/* + * Reset the DLL. This function is common between DDR3 and LPDDR2. + * However, the reset value is different. So we are passing a flag + * ddr_mode to distinguish between LPDDR2 and DDR3. + * + * @param phycontrol0 Register address for dmc_phy->phycontrol0 + * @param ddr_mode Type of DDR memory + */ +void update_reset_dll(uint32_t *phycontrol0, enum ddr_mode); +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/lowlevel_init.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/lowlevel_init.c new file mode 100644 index 0000000..120aaf8 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/lowlevel_init.c
@@ -0,0 +1,224 @@ +/* + * Lowlevel setup for EXYNOS5 based board + * + * Copyright (C) 2013 Samsung Electronics + * Rajeshwari Shinde <rajeshwari.s@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 <config.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dmc.h> +#include <asm/arch/power.h> +#include <asm/arch/tzpc.h> +#include <asm/arch/periph.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/system.h> +#include <asm/armv7.h> +#include "common_setup.h" +#include "exynos5_setup.h" + +/* These are the things we can do during low-level init */ +enum { + DO_WAKEUP = 1 << 0, + DO_CLOCKS = 1 << 1, + DO_MEM_RESET = 1 << 2, + DO_UART = 1 << 3, + DO_POWER = 1 << 4, +}; + +#ifdef CONFIG_EXYNOS5420 +/* + * Power up secondary CPUs. + */ +static void secondary_cpu_start(void) +{ + v7_enable_smp(EXYNOS5420_INFORM_BASE); + svc32_mode_en(); + branch_bx(CONFIG_EXYNOS_RELOCATE_CODE_BASE); +} + +/* + * This is the entry point of hotplug-in and + * cluster switching. + */ +static void low_power_start(void) +{ + uint32_t val, reg_val; + + reg_val = readl(EXYNOS5420_SPARE_BASE); + if (reg_val != CPU_RST_FLAG_VAL) { + writel(0x0, CONFIG_LOWPOWER_FLAG); + branch_bx(0x0); + } + + reg_val = readl(CONFIG_PHY_IRAM_BASE + 0x4); + if (reg_val != (uint32_t)&low_power_start) { + /* Store jump address as low_power_start if not present */ + writel((uint32_t)&low_power_start, CONFIG_PHY_IRAM_BASE + 0x4); + dsb(); + sev(); + } + + /* Set the CPU to SVC32 mode */ + svc32_mode_en(); + +#ifndef CONFIG_SYS_L2CACHE_OFF + /* Read MIDR for Primary Part Number */ + mrc_midr(val); + val = (val >> 4); + val &= 0xf; + + if (val == 0xf) { + configure_l2_ctlr(); + configure_l2_actlr(); + v7_enable_l2_hazard_detect(); + } +#endif + + /* Invalidate L1 & TLB */ + val = 0x0; + mcr_tlb(val); + mcr_icache(val); + + /* Disable MMU stuff and caches */ + mrc_sctlr(val); + + val &= ~((0x2 << 12) | 0x7); + val |= ((0x1 << 12) | (0x8 << 8) | 0x2); + mcr_sctlr(val); + + /* CPU state is hotplug or reset */ + secondary_cpu_start(); + + /* Core should not enter into WFI here */ + wfi(); +} + +/* + * Pointer to this function is stored in iRam which is used + * for jump and power down of a specific core. + */ +static void power_down_core(void) +{ + uint32_t tmp, core_id, core_config; + + /* Get the unique core id */ + /* + * Multiprocessor Affinity Register + * [11:8] Cluster ID + * [1:0] CPU ID + */ + mrc_mpafr(core_id); + tmp = core_id & 0x3; + core_id = (core_id >> 6) & ~3; + core_id |= tmp; + core_id &= 0x3f; + + /* Set the status of the core to low */ + core_config = (core_id * CPU_CONFIG_STATUS_OFFSET); + core_config += EXYNOS5420_CPU_CONFIG_BASE; + writel(0x0, core_config); + + /* Core enter WFI */ + wfi(); +} + +/* + * Configurations for secondary cores are inapt at this stage. + * Reconfigure secondary cores. Shutdown and change the status + * of all cores except the primary core. + */ +static void secondary_cores_configure(void) +{ + /* Clear secondary boot iRAM base */ + writel(0x0, (CONFIG_EXYNOS_RELOCATE_CODE_BASE + 0x1C)); + + /* set lowpower flag and address */ + writel(CPU_RST_FLAG_VAL, CONFIG_LOWPOWER_FLAG); + writel((uint32_t)&low_power_start, CONFIG_LOWPOWER_ADDR); + writel(CPU_RST_FLAG_VAL, EXYNOS5420_SPARE_BASE); + /* Store jump address for power down */ + writel((uint32_t)&power_down_core, CONFIG_PHY_IRAM_BASE + 0x4); + + /* Need all core power down check */ + dsb(); + sev(); +} + +extern void relocate_wait_code(void); +#endif + +int do_lowlevel_init(void) +{ + uint32_t reset_status; + int actions = 0; + + arch_cpu_init(); + +#ifndef CONFIG_SYS_L2CACHE_OFF + /* + * Init L2 cache parameters here for use by boot and resume + * + * These are here instead of in v7_outer_cache_enable() so that the + * L2 cache settings get properly set even at resume time or if we're + * running U-Boot with the cache off. The kernel still needs us to + * set these for it. + */ + configure_l2_ctlr(); + configure_l2_actlr(); + dsb(); + isb(); +#endif + +#ifdef CONFIG_EXYNOS5420 + relocate_wait_code(); + + /* Reconfigure secondary cores */ + secondary_cores_configure(); +#endif + + reset_status = get_reset_status(); + + switch (reset_status) { + case S5P_CHECK_SLEEP: + actions = DO_CLOCKS | DO_WAKEUP; + break; + case S5P_CHECK_DIDLE: + case S5P_CHECK_LPA: + actions = DO_WAKEUP; + break; + default: + /* This is a normal boot (not a wake from sleep) */ + actions = DO_CLOCKS | DO_MEM_RESET | DO_POWER; + } + + if (actions & DO_POWER) + set_ps_hold_ctrl(); + + if (actions & DO_CLOCKS) { + system_clock_init(); + mem_ctrl_init(actions & DO_MEM_RESET); + tzpc_init(); + } + + return actions & DO_WAKEUP; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/pinmux.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/pinmux.c new file mode 100644 index 0000000..be43e22 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -0,0 +1,905 @@ +/* + * Copyright (c) 2012 Samsung Electronics. + * Abhilash Kesavan <a.kesavan@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fdtdec.h> +#include <asm/gpio.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/sromc.h> + +static void exynos5_uart_config(int peripheral) +{ + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + start = EXYNOS5_GPIO_A00; + count = 4; + break; + case PERIPH_ID_UART1: + start = EXYNOS5_GPIO_D00; + count = 4; + break; + case PERIPH_ID_UART2: + start = EXYNOS5_GPIO_A10; + count = 4; + break; + case PERIPH_ID_UART3: + start = EXYNOS5_GPIO_A14; + count = 2; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; + } + for (i = start; i < start + count; i++) { + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + } +} + +static void exynos5420_uart_config(int peripheral) +{ + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + start = EXYNOS5420_GPIO_A00; + count = 4; + break; + case PERIPH_ID_UART1: + start = EXYNOS5420_GPIO_A04; + count = 4; + break; + case PERIPH_ID_UART2: + start = EXYNOS5420_GPIO_A10; + count = 4; + break; + case PERIPH_ID_UART3: + start = EXYNOS5420_GPIO_A14; + count = 2; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; + } + + for (i = start; i < start + count; i++) { + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + } +} + +static int exynos5_mmc_config(int peripheral, int flags) +{ + int i, start, start_ext, gpio_func = 0; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + start = EXYNOS5_GPIO_C00; + start_ext = EXYNOS5_GPIO_C10; + gpio_func = S5P_GPIO_FUNC(0x2); + break; + case PERIPH_ID_SDMMC1: + start = EXYNOS5_GPIO_C20; + start_ext = 0; + break; + case PERIPH_ID_SDMMC2: + start = EXYNOS5_GPIO_C30; + start_ext = EXYNOS5_GPIO_C43; + gpio_func = S5P_GPIO_FUNC(0x3); + break; + case PERIPH_ID_SDMMC3: + start = EXYNOS5_GPIO_C40; + start_ext = 0; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = start_ext; i <= (start_ext + 3); i++) { + gpio_cfg_pin(i, gpio_func); + gpio_set_pull(i, S5P_GPIO_PULL_UP); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + } + for (i = start; i < (start + 2); i++) { + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + for (i = (start + 3); i <= (start + 6); i++) { + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + gpio_set_pull(i, S5P_GPIO_PULL_UP); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + + return 0; +} + +static int exynos5420_mmc_config(int peripheral, int flags) +{ + int i, start = 0, start_ext = 0; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + start = EXYNOS5420_GPIO_C00; + start_ext = EXYNOS5420_GPIO_C30; + break; + case PERIPH_ID_SDMMC1: + start = EXYNOS5420_GPIO_C10; + start_ext = EXYNOS5420_GPIO_D14; + break; + case PERIPH_ID_SDMMC2: + start = EXYNOS5420_GPIO_C20; + start_ext = 0; + break; + default: + start = 0; + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) { + debug("SDMMC device %d does not support 8bit mode", + peripheral); + return -1; + } + + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = start_ext; i <= (start_ext + 3); i++) { + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + gpio_set_pull(i, S5P_GPIO_PULL_UP); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + } + + for (i = start; i < (start + 3); i++) { + /* + * MMC0 is intended to be used for eMMC. The + * card detect pin is used as a VDDEN signal to + * power on the eMMC. The 5420 iROM makes + * this same assumption. + */ + if ((peripheral == PERIPH_ID_SDMMC0) && (i == (start + 2))) { +#ifndef CONFIG_SPL_BUILD + gpio_request(i, "sdmmc0_vdden"); +#endif + gpio_set_value(i, 1); + gpio_cfg_pin(i, S5P_GPIO_OUTPUT); + } else { + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + } + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + + for (i = (start + 3); i <= (start + 6); i++) { + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + gpio_set_pull(i, S5P_GPIO_PULL_UP); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + + return 0; +} + +static void exynos5_sromc_config(int flags) +{ + int i; + + /* + * SROM:CS1 and EBI + * + * GPY0[0] SROM_CSn[0] + * GPY0[1] SROM_CSn[1](2) + * GPY0[2] SROM_CSn[2] + * GPY0[3] SROM_CSn[3] + * GPY0[4] EBI_OEn(2) + * GPY0[5] EBI_EEn(2) + * + * GPY1[0] EBI_BEn[0](2) + * GPY1[1] EBI_BEn[1](2) + * GPY1[2] SROM_WAIT(2) + * GPY1[3] EBI_DATA_RDn(2) + */ + gpio_cfg_pin(EXYNOS5_GPIO_Y00 + (flags & PINMUX_FLAG_BANK), + S5P_GPIO_FUNC(2)); + gpio_cfg_pin(EXYNOS5_GPIO_Y04, S5P_GPIO_FUNC(2)); + gpio_cfg_pin(EXYNOS5_GPIO_Y05, S5P_GPIO_FUNC(2)); + + for (i = 0; i < 4; i++) + gpio_cfg_pin(EXYNOS5_GPIO_Y10 + i, S5P_GPIO_FUNC(2)); + + /* + * EBI: 8 Addrss Lines + * + * GPY3[0] EBI_ADDR[0](2) + * GPY3[1] EBI_ADDR[1](2) + * GPY3[2] EBI_ADDR[2](2) + * GPY3[3] EBI_ADDR[3](2) + * GPY3[4] EBI_ADDR[4](2) + * GPY3[5] EBI_ADDR[5](2) + * GPY3[6] EBI_ADDR[6](2) + * GPY3[7] EBI_ADDR[7](2) + * + * EBI: 16 Data Lines + * + * GPY5[0] EBI_DATA[0](2) + * GPY5[1] EBI_DATA[1](2) + * GPY5[2] EBI_DATA[2](2) + * GPY5[3] EBI_DATA[3](2) + * GPY5[4] EBI_DATA[4](2) + * GPY5[5] EBI_DATA[5](2) + * GPY5[6] EBI_DATA[6](2) + * GPY5[7] EBI_DATA[7](2) + * + * GPY6[0] EBI_DATA[8](2) + * GPY6[1] EBI_DATA[9](2) + * GPY6[2] EBI_DATA[10](2) + * GPY6[3] EBI_DATA[11](2) + * GPY6[4] EBI_DATA[12](2) + * GPY6[5] EBI_DATA[13](2) + * GPY6[6] EBI_DATA[14](2) + * GPY6[7] EBI_DATA[15](2) + */ + for (i = 0; i < 8; i++) { + gpio_cfg_pin(EXYNOS5_GPIO_Y30 + i, S5P_GPIO_FUNC(2)); + gpio_set_pull(EXYNOS5_GPIO_Y30 + i, S5P_GPIO_PULL_UP); + + gpio_cfg_pin(EXYNOS5_GPIO_Y50 + i, S5P_GPIO_FUNC(2)); + gpio_set_pull(EXYNOS5_GPIO_Y50 + i, S5P_GPIO_PULL_UP); + + gpio_cfg_pin(EXYNOS5_GPIO_Y60 + i, S5P_GPIO_FUNC(2)); + gpio_set_pull(EXYNOS5_GPIO_Y60 + i, S5P_GPIO_PULL_UP); + } +} + +static void exynos5_i2c_config(int peripheral, int flags) +{ + int func01, func23; + + /* High-Speed I2C */ + if (flags & PINMUX_FLAG_HS_MODE) { + func01 = 4; + func23 = 4; + } else { + func01 = 2; + func23 = 3; + } + + switch (peripheral) { + case PERIPH_ID_I2C0: + gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01)); + break; + case PERIPH_ID_I2C1: + gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01)); + gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01)); + break; + case PERIPH_ID_I2C2: + gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23)); + break; + case PERIPH_ID_I2C3: + gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23)); + gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23)); + break; + case PERIPH_ID_I2C4: + gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A21, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + gpio_cfg_pin(EXYNOS5_GPIO_A22, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_A23, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + gpio_cfg_pin(EXYNOS5_GPIO_B13, S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS5_GPIO_B14, S5P_GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + gpio_cfg_pin(EXYNOS5_GPIO_B22, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5_GPIO_B23, S5P_GPIO_FUNC(0x3)); + break; + } +} + +static void exynos5420_i2c_config(int peripheral) +{ + switch (peripheral) { + case PERIPH_ID_I2C0: + gpio_cfg_pin(EXYNOS5420_GPIO_B30, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5420_GPIO_B31, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C1: + gpio_cfg_pin(EXYNOS5420_GPIO_B32, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5420_GPIO_B33, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + gpio_cfg_pin(EXYNOS5420_GPIO_A06, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5420_GPIO_A07, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + gpio_cfg_pin(EXYNOS5420_GPIO_A12, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5420_GPIO_A13, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + gpio_cfg_pin(EXYNOS5420_GPIO_A20, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5420_GPIO_A21, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + gpio_cfg_pin(EXYNOS5420_GPIO_A22, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5420_GPIO_A23, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + gpio_cfg_pin(EXYNOS5420_GPIO_B13, S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS5420_GPIO_B14, S5P_GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + gpio_cfg_pin(EXYNOS5420_GPIO_B22, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS5420_GPIO_B23, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C8: + gpio_cfg_pin(EXYNOS5420_GPIO_B34, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5420_GPIO_B35, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C9: + gpio_cfg_pin(EXYNOS5420_GPIO_B36, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5420_GPIO_B37, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C10: + gpio_cfg_pin(EXYNOS5420_GPIO_B40, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS5420_GPIO_B41, S5P_GPIO_FUNC(0x2)); + break; + } +} + +static void exynos5_i2s_config(int peripheral) +{ + int i; + + switch (peripheral) { + case PERIPH_ID_I2S0: + for (i = 0; i < 5; i++) + gpio_cfg_pin(EXYNOS5_GPIO_Z0 + i, S5P_GPIO_FUNC(0x02)); + break; + case PERIPH_ID_I2S1: + for (i = 0; i < 5; i++) + gpio_cfg_pin(EXYNOS5_GPIO_B00 + i, S5P_GPIO_FUNC(0x02)); + break; + } +} + +void exynos5_spi_config(int peripheral) +{ + int cfg = 0, pin = 0, i; + + switch (peripheral) { + case PERIPH_ID_SPI0: + cfg = S5P_GPIO_FUNC(0x2); + pin = EXYNOS5_GPIO_A20; + break; + case PERIPH_ID_SPI1: + cfg = S5P_GPIO_FUNC(0x2); + pin = EXYNOS5_GPIO_A24; + break; + case PERIPH_ID_SPI2: + cfg = S5P_GPIO_FUNC(0x5); + pin = EXYNOS5_GPIO_B11; + break; + case PERIPH_ID_SPI3: + cfg = S5P_GPIO_FUNC(0x2); + pin = EXYNOS5_GPIO_F10; + break; + case PERIPH_ID_SPI4: + for (i = 0; i < 2; i++) { + gpio_cfg_pin(EXYNOS5_GPIO_F02 + i, S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS5_GPIO_E04 + i, S5P_GPIO_FUNC(0x4)); + } + break; + } + if (peripheral != PERIPH_ID_SPI4) { + for (i = pin; i < pin + 4; i++) + gpio_cfg_pin(i, cfg); + } +} + +void exynos5420_spi_config(int peripheral) +{ + int cfg, pin, i; + + switch (peripheral) { + case PERIPH_ID_SPI0: + pin = EXYNOS5420_GPIO_A20; + cfg = S5P_GPIO_FUNC(0x2); + break; + case PERIPH_ID_SPI1: + pin = EXYNOS5420_GPIO_A24; + cfg = S5P_GPIO_FUNC(0x2); + break; + case PERIPH_ID_SPI2: + pin = EXYNOS5420_GPIO_B11; + cfg = S5P_GPIO_FUNC(0x5); + break; + case PERIPH_ID_SPI3: + pin = EXYNOS5420_GPIO_F10; + cfg = S5P_GPIO_FUNC(0x2); + break; + case PERIPH_ID_SPI4: + cfg = 0; + pin = 0; + break; + default: + cfg = 0; + pin = 0; + debug("%s: invalid peripheral %d", __func__, peripheral); + return; + } + + if (peripheral != PERIPH_ID_SPI4) { + for (i = pin; i < pin + 4; i++) + gpio_cfg_pin(i, cfg); + } else { + for (i = 0; i < 2; i++) { + gpio_cfg_pin(EXYNOS5420_GPIO_F02 + i, + S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS5420_GPIO_E04 + i, + S5P_GPIO_FUNC(0x4)); + } + } +} + +static int exynos5_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos5_uart_config(peripheral); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + return exynos5_mmc_config(peripheral, flags); + case PERIPH_ID_SROMC: + exynos5_sromc_config(flags); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos5_i2c_config(peripheral, flags); + break; + case PERIPH_ID_I2S0: + case PERIPH_ID_I2S1: + exynos5_i2s_config(peripheral); + break; + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + case PERIPH_ID_SPI2: + case PERIPH_ID_SPI3: + case PERIPH_ID_SPI4: + exynos5_spi_config(peripheral); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +static int exynos5420_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos5420_uart_config(peripheral); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC3: + return exynos5420_mmc_config(peripheral, flags); + case PERIPH_ID_SPI0: + case PERIPH_ID_SPI1: + case PERIPH_ID_SPI2: + case PERIPH_ID_SPI3: + case PERIPH_ID_SPI4: + exynos5420_spi_config(peripheral); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + case PERIPH_ID_I2C8: + case PERIPH_ID_I2C9: + case PERIPH_ID_I2C10: + exynos5420_i2c_config(peripheral); + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +static void exynos4_i2c_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_I2C0: + gpio_cfg_pin(EXYNOS4_GPIO_D10, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS4_GPIO_D11, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C1: + gpio_cfg_pin(EXYNOS4_GPIO_D12, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS4_GPIO_D13, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + gpio_cfg_pin(EXYNOS4_GPIO_A06, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4_GPIO_A07, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + gpio_cfg_pin(EXYNOS4_GPIO_A12, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4_GPIO_A13, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + gpio_cfg_pin(EXYNOS4_GPIO_B2, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4_GPIO_B3, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + gpio_cfg_pin(EXYNOS4_GPIO_B6, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4_GPIO_B7, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + gpio_cfg_pin(EXYNOS4_GPIO_C13, S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS4_GPIO_C14, S5P_GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + gpio_cfg_pin(EXYNOS4_GPIO_D02, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4_GPIO_D03, S5P_GPIO_FUNC(0x3)); + break; + } +} + +static int exynos4_mmc_config(int peripheral, int flags) +{ + int i, start = 0, start_ext = 0; + unsigned int func, ext_func; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + start = EXYNOS4_GPIO_K00; + start_ext = EXYNOS4_GPIO_K13; + func = S5P_GPIO_FUNC(0x2); + ext_func = S5P_GPIO_FUNC(0x3); + break; + case PERIPH_ID_SDMMC2: + start = EXYNOS4_GPIO_K20; + start_ext = EXYNOS4_GPIO_K33; + func = S5P_GPIO_FUNC(0x2); + ext_func = S5P_GPIO_FUNC(0x3); + break; + case PERIPH_ID_SDMMC4: + start = EXYNOS4_GPIO_K00; + start_ext = EXYNOS4_GPIO_K13; + func = S5P_GPIO_FUNC(0x3); + ext_func = S5P_GPIO_FUNC(0x4); + break; + default: + return -1; + } + for (i = start; i < (start + 7); i++) { + if (i == (start + 2)) + continue; + gpio_cfg_pin(i, func); + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + /* SDMMC2 do not use 8bit mode at exynos4 */ + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = start_ext; i < (start_ext + 4); i++) { + gpio_cfg_pin(i, ext_func); + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + } + + return 0; +} + +static void exynos4_uart_config(int peripheral) +{ + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + start = EXYNOS4_GPIO_A00; + count = 4; + break; + case PERIPH_ID_UART1: + start = EXYNOS4_GPIO_A04; + count = 4; + break; + case PERIPH_ID_UART2: + start = EXYNOS4_GPIO_A10; + count = 4; + break; + case PERIPH_ID_UART3: + start = EXYNOS4_GPIO_A14; + count = 2; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; + } + for (i = start; i < (start + count); i++) { + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + } +} + +static void exynos4x12_i2c_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_I2C0: + gpio_cfg_pin(EXYNOS4X12_GPIO_D10, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS4X12_GPIO_D11, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C1: + gpio_cfg_pin(EXYNOS4X12_GPIO_D12, S5P_GPIO_FUNC(0x2)); + gpio_cfg_pin(EXYNOS4X12_GPIO_D13, S5P_GPIO_FUNC(0x2)); + break; + case PERIPH_ID_I2C2: + gpio_cfg_pin(EXYNOS4X12_GPIO_A06, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4X12_GPIO_A07, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C3: + gpio_cfg_pin(EXYNOS4X12_GPIO_A12, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4X12_GPIO_A13, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C4: + gpio_cfg_pin(EXYNOS4X12_GPIO_B2, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4X12_GPIO_B3, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C5: + gpio_cfg_pin(EXYNOS4X12_GPIO_B6, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4X12_GPIO_B7, S5P_GPIO_FUNC(0x3)); + break; + case PERIPH_ID_I2C6: + gpio_cfg_pin(EXYNOS4X12_GPIO_C13, S5P_GPIO_FUNC(0x4)); + gpio_cfg_pin(EXYNOS4X12_GPIO_C14, S5P_GPIO_FUNC(0x4)); + break; + case PERIPH_ID_I2C7: + gpio_cfg_pin(EXYNOS4X12_GPIO_D02, S5P_GPIO_FUNC(0x3)); + gpio_cfg_pin(EXYNOS4X12_GPIO_D03, S5P_GPIO_FUNC(0x3)); + break; + } +} + +static int exynos4x12_mmc_config(int peripheral, int flags) +{ + int i, start = 0, start_ext = 0; + unsigned int func, ext_func; + + switch (peripheral) { + case PERIPH_ID_SDMMC0: + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; + func = S5P_GPIO_FUNC(0x2); + ext_func = S5P_GPIO_FUNC(0x3); + break; + case PERIPH_ID_SDMMC2: + start = EXYNOS4X12_GPIO_K20; + start_ext = EXYNOS4X12_GPIO_K33; + func = S5P_GPIO_FUNC(0x2); + ext_func = S5P_GPIO_FUNC(0x3); + break; + case PERIPH_ID_SDMMC4: + start = EXYNOS4X12_GPIO_K00; + start_ext = EXYNOS4X12_GPIO_K13; + func = S5P_GPIO_FUNC(0x3); + ext_func = S5P_GPIO_FUNC(0x4); + break; + default: + return -1; + } + for (i = start; i < (start + 7); i++) { + if (i == (start + 2)) + continue; + gpio_cfg_pin(i, func); + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + if (flags & PINMUX_FLAG_8BIT_MODE) { + for (i = start_ext; i < (start_ext + 4); i++) { + gpio_cfg_pin(i, ext_func); + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_set_drv(i, S5P_GPIO_DRV_4X); + } + } + + return 0; +} + +static void exynos4x12_uart_config(int peripheral) +{ + int i, start, count; + + switch (peripheral) { + case PERIPH_ID_UART0: + start = EXYNOS4X12_GPIO_A00; + count = 4; + break; + case PERIPH_ID_UART1: + start = EXYNOS4X12_GPIO_A04; + count = 4; + break; + case PERIPH_ID_UART2: + start = EXYNOS4X12_GPIO_A10; + count = 4; + break; + case PERIPH_ID_UART3: + start = EXYNOS4X12_GPIO_A14; + count = 2; + break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; + } + for (i = start; i < (start + count); i++) { + gpio_set_pull(i, S5P_GPIO_PULL_NONE); + gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2)); + } +} + +static int exynos4_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos4_uart_config(peripheral); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos4_i2c_config(peripheral, flags); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC4: + return exynos4_mmc_config(peripheral, flags); + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC3: + debug("SDMMC device %d not implemented\n", peripheral); + return -1; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +static int exynos4x12_pinmux_config(int peripheral, int flags) +{ + switch (peripheral) { + case PERIPH_ID_UART0: + case PERIPH_ID_UART1: + case PERIPH_ID_UART2: + case PERIPH_ID_UART3: + exynos4x12_uart_config(peripheral); + break; + case PERIPH_ID_I2C0: + case PERIPH_ID_I2C1: + case PERIPH_ID_I2C2: + case PERIPH_ID_I2C3: + case PERIPH_ID_I2C4: + case PERIPH_ID_I2C5: + case PERIPH_ID_I2C6: + case PERIPH_ID_I2C7: + exynos4x12_i2c_config(peripheral, flags); + break; + case PERIPH_ID_SDMMC0: + case PERIPH_ID_SDMMC2: + case PERIPH_ID_SDMMC4: + return exynos4x12_mmc_config(peripheral, flags); + case PERIPH_ID_SDMMC1: + case PERIPH_ID_SDMMC3: + debug("SDMMC device %d not implemented\n", peripheral); + return -1; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; + } + + return 0; +} + +int exynos_pinmux_config(int peripheral, int flags) +{ + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + return exynos5420_pinmux_config(peripheral, flags); + else if (proid_is_exynos5250()) + return exynos5_pinmux_config(peripheral, flags); + } else if (cpu_is_exynos4()) { + if (proid_is_exynos4412()) + return exynos4x12_pinmux_config(peripheral, flags); + else + return exynos4_pinmux_config(peripheral, flags); + } + + debug("pinmux functionality not supported\n"); + + return -1; +} + +#ifdef CONFIG_OF_CONTROL +static int exynos4_pinmux_decode_periph_id(const void *blob, int node) +{ + int err; + u32 cell[3]; + + err = fdtdec_get_int_array(blob, node, "interrupts", cell, + ARRAY_SIZE(cell)); + if (err) { + debug(" invalid peripheral id\n"); + return PERIPH_ID_NONE; + } + + return cell[1]; +} + +static int exynos5_pinmux_decode_periph_id(const void *blob, int node) +{ + int err; + u32 cell[3]; + + err = fdtdec_get_int_array(blob, node, "interrupts", cell, + ARRAY_SIZE(cell)); + if (err) + return PERIPH_ID_NONE; + + return cell[1]; +} + +int pinmux_decode_periph_id(const void *blob, int node) +{ + if (cpu_is_exynos5()) + return exynos5_pinmux_decode_periph_id(blob, node); + else if (cpu_is_exynos4()) + return exynos4_pinmux_decode_periph_id(blob, node); + + return PERIPH_ID_NONE; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/power.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/power.c new file mode 100644 index 0000000..1b12051 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/power.c
@@ -0,0 +1,262 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Donghwa Lee <dh09.lee@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/power.h> + +static void exynos4_mipi_phy_control(unsigned int dev_index, + unsigned int enable) +{ + struct exynos4_power *pmu = + (struct exynos4_power *)samsung_get_base_power(); + unsigned int addr, cfg = 0; + + if (dev_index == 0) + addr = (unsigned int)&pmu->mipi_phy0_control; + else + addr = (unsigned int)&pmu->mipi_phy1_control; + + + cfg = readl(addr); + if (enable) + cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE); + else + cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE); + + writel(cfg, addr); +} + +void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable) +{ + if (cpu_is_exynos4()) + exynos4_mipi_phy_control(dev_index, enable); +} + +void exynos5_set_usbhost_phy_ctrl(unsigned int enable) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + if (enable) { + /* Enabling USBHOST_PHY */ + setbits_le32(&power->usbhost_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + } else { + /* Disabling USBHOST_PHY */ + clrbits_le32(&power->usbhost_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + } +} + +void exynos4412_set_usbhost_phy_ctrl(unsigned int enable) +{ + struct exynos4412_power *power = + (struct exynos4412_power *)samsung_get_base_power(); + + if (enable) { + /* Enabling USBHOST_PHY */ + setbits_le32(&power->usbhost_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + setbits_le32(&power->hsic1_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + setbits_le32(&power->hsic2_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + } else { + /* Disabling USBHOST_PHY */ + clrbits_le32(&power->usbhost_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + clrbits_le32(&power->hsic1_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + clrbits_le32(&power->hsic2_phy_control, + POWER_USB_HOST_PHY_CTRL_EN); + } +} + +void set_usbhost_phy_ctrl(unsigned int enable) +{ + if (cpu_is_exynos5()) + exynos5_set_usbhost_phy_ctrl(enable); + else if (cpu_is_exynos4()) + if (proid_is_exynos4412()) + exynos4412_set_usbhost_phy_ctrl(enable); +} + +static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + if (enable) { + /* Enabling USBDRD_PHY */ + setbits_le32(&power->usbdrd_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } else { + /* Disabling USBDRD_PHY */ + clrbits_le32(&power->usbdrd_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } +} + +static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable) +{ + struct exynos5420_power *power = + (struct exynos5420_power *)samsung_get_base_power(); + + if (enable) { + /* Enabling USBDEV_PHY */ + setbits_le32(&power->usbdev_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + setbits_le32(&power->usbdev1_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } else { + /* Disabling USBDEV_PHY */ + clrbits_le32(&power->usbdev_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + clrbits_le32(&power->usbdev1_phy_control, + POWER_USB_DRD_PHY_CTRL_EN); + } +} + +void set_usbdrd_phy_ctrl(unsigned int enable) +{ + if (cpu_is_exynos5()) { + if (proid_is_exynos5420() || proid_is_exynos5800()) + exynos5420_set_usbdev_phy_ctrl(enable); + else + exynos5_set_usbdrd_phy_ctrl(enable); + } +} + +static void exynos5_dp_phy_control(unsigned int enable) +{ + unsigned int cfg; + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + cfg = readl(&power->dptx_phy_control); + if (enable) + cfg |= EXYNOS_DP_PHY_ENABLE; + else + cfg &= ~EXYNOS_DP_PHY_ENABLE; + + writel(cfg, &power->dptx_phy_control); +} + +void set_dp_phy_ctrl(unsigned int enable) +{ + if (cpu_is_exynos5()) + exynos5_dp_phy_control(enable); +} + +static void exynos5_set_ps_hold_ctrl(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* Set PS-Hold high */ + setbits_le32(&power->ps_hold_control, + EXYNOS_PS_HOLD_CONTROL_DATA_HIGH); +} + +/* + * Set ps_hold data driving value high + * This enables the machine to stay powered on + * after the initial power-on condition goes away + * (e.g. power button). + */ +void set_ps_hold_ctrl(void) +{ + if (cpu_is_exynos5()) + exynos5_set_ps_hold_ctrl(); +} + + +static void exynos5_set_xclkout(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* use xxti for xclk out */ + clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK, + PMU_DEBUG_XXTI); +} + +void set_xclkout(void) +{ + if (cpu_is_exynos5()) + exynos5_set_xclkout(); +} + +/* Enables hardware tripping to power off the system when TMU fails */ +void set_hw_thermal_trip(void) +{ + if (cpu_is_exynos5()) { + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/ + setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP); + } +} + +static uint32_t exynos5_get_reset_status(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + + return power->inform1; +} + +static uint32_t exynos4_get_reset_status(void) +{ + struct exynos4_power *power = + (struct exynos4_power *)samsung_get_base_power(); + + return power->inform1; +} + +uint32_t get_reset_status(void) +{ + if (cpu_is_exynos5()) + return exynos5_get_reset_status(); + else + return exynos4_get_reset_status(); +} + +static void exynos5_power_exit_wakeup(void) +{ + struct exynos5_power *power = + (struct exynos5_power *)samsung_get_base_power(); + typedef void (*resume_func)(void); + + ((resume_func)power->inform0)(); +} + +static void exynos4_power_exit_wakeup(void) +{ + struct exynos4_power *power = + (struct exynos4_power *)samsung_get_base_power(); + typedef void (*resume_func)(void); + + ((resume_func)power->inform0)(); +} + +void power_exit_wakeup(void) +{ + if (cpu_is_exynos5()) + exynos5_power_exit_wakeup(); + else + exynos4_power_exit_wakeup(); +} + +unsigned int get_boot_mode(void) +{ + unsigned int om_pin = samsung_get_base_power(); + + return readl(om_pin) & OM_PIN_MASK; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/sec_boot.S b/u-boot-imx/arch/arm/cpu/armv7/exynos/sec_boot.S new file mode 100644 index 0000000..dfc3455 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/sec_boot.S
@@ -0,0 +1,128 @@ +/* + * Copyright (C) 2013 Samsung Electronics + * Akshay Saraswat <akshay.s@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arch/cpu.h> + + .globl relocate_wait_code +relocate_wait_code: + adr r0, code_base @ r0: source address (start) + adr r1, code_end @ r1: source address (end) + ldr r2, =0x02073000 @ r2: target address +1: + ldmia r0!, {r3-r6} + stmia r2!, {r3-r6} + cmp r0, r1 + blt 1b + b code_end + .ltorg +/* + * Secondary core waits here until Primary wake it up. + * Below code is copied to CONFIG_EXYNOS_RELOCATE_CODE_BASE. + * This is a workaround code which is supposed to act as a + * substitute/supplement to the iROM code. + * + * This workaround code is relocated to the address 0x02073000 + * because that comes out to be the last 4KB of the iRAM + * (Base Address - 0x02020000, Limit Address - 0x020740000). + * + * U-boot and kernel are aware of this code and flags by the simple + * fact that we are implementing a workaround in the last 4KB + * of the iRAM and we have already defined these flag and address + * values in both kernel and U-boot for our use. + */ +code_base: + b 1f +/* + * These addresses are being used as flags in u-boot and kernel. + * + * Jump address for resume and flag to check for resume/reset: + * Resume address - 0x2073008 + * Resume flag - 0x207300C + * + * Jump address for cluster switching: + * Switch address - 0x2073018 + * + * Jump address for core hotplug: + * Hotplug address - 0x207301C + * + * Jump address for C2 state (Reserved for future not being used right now): + * C2 address - 0x2073024 + * + * Managed per core status for the active cluster: + * CPU0 state - 0x2073028 + * CPU1 state - 0x207302C + * CPU2 state - 0x2073030 + * CPU3 state - 0x2073034 + * + * Managed per core GIC status for the active cluster: + * CPU0 gic state - 0x2073038 + * CPU1 gic state - 0x207303C + * CPU2 gic state - 0x2073040 + * CPU3 gic state - 0x2073044 + * + * Logic of the code: + * Step-1: Read current CPU status. + * Step-2: If it's a resume then continue, else jump to step 4. + * Step-3: Clear inform1 PMU register and jump to inform0 value. + * Step-4: If it's a switch, C2 or reset, get the hotplug address. + * Step-5: If address is not available, enter WFE. + * Step-6: If address is available, jump to that address. + */ + nop @ for backward compatibility + .word 0x0 @ REG0: RESUME_ADDR + .word 0x0 @ REG1: RESUME_FLAG + .word 0x0 @ REG2 + .word 0x0 @ REG3 +_switch_addr: + .word 0x0 @ REG4: SWITCH_ADDR +_hotplug_addr: + .word 0x0 @ REG5: CPU1_BOOT_REG + .word 0x0 @ REG6 +_c2_addr: + .word 0x0 @ REG7: REG_C2_ADDR +_cpu_state: + .word 0x1 @ CPU0_STATE : RESET + .word 0x2 @ CPU1_STATE : SECONDARY RESET + .word 0x2 @ CPU2_STATE : SECONDARY RESET + .word 0x2 @ CPU3_STATE : SECONDARY RESET +_gic_state: + .word 0x0 @ CPU0 - GICD_IGROUPR0 + .word 0x0 @ CPU1 - GICD_IGROUPR0 + .word 0x0 @ CPU2 - GICD_IGROUPR0 + .word 0x0 @ CPU3 - GICD_IGROUPR0 +1: + adr r0, _cpu_state + mrc p15, 0, r7, c0, c0, 5 @ read MPIDR + and r7, r7, #0xf @ r7 = cpu id +/* Read the current cpu state */ + ldr r10, [r0, r7, lsl #2] +svc_entry: + tst r10, #(1 << 4) + adrne r0, _switch_addr + bne wait_for_addr +/* Clear INFORM1 */ + ldr r0, =(0x10040000 + 0x804) + ldr r1, [r0] + cmp r1, #0x0 + movne r1, #0x0 + strne r1, [r0] +/* Get INFORM0 */ + ldrne r1, =(0x10040000 + 0x800) + ldrne pc, [r1] + tst r10, #(1 << 0) + ldrne pc, =0x23e00000 + adr r0, _hotplug_addr +wait_for_addr: + ldr r1, [r0] + cmp r1, #0x0 + bxne r1 + wfe + b wait_for_addr + .ltorg +code_end: + mov pc, lr
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/soc.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/soc.c new file mode 100644 index 0000000..0f116b1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/soc.c
@@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010 Samsung Electronics. + * Minkyu Kang <mk7.kang@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/system.h> + +void reset_cpu(ulong addr) +{ + writel(0x1, samsung_get_base_swreset()); +} + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/spl_boot.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/spl_boot.c new file mode 100644 index 0000000..c7f943e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/spl_boot.c
@@ -0,0 +1,311 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> + +#include <asm/arch/clock.h> +#include <asm/arch/clk.h> +#include <asm/arch/dmc.h> +#include <asm/arch/periph.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/power.h> +#include <asm/arch/spl.h> +#include <asm/arch/spi.h> + +#include "common_setup.h" +#include "clock_init.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* Index into irom ptr table */ +enum index { + MMC_INDEX, + EMMC44_INDEX, + EMMC44_END_INDEX, + SPI_INDEX, + USB_INDEX, +}; + +/* IROM Function Pointers Table */ +u32 irom_ptr_table[] = { + [MMC_INDEX] = 0x02020030, /* iROM Function Pointer-SDMMC boot */ + [EMMC44_INDEX] = 0x02020044, /* iROM Function Pointer-EMMC4.4 boot*/ + [EMMC44_END_INDEX] = 0x02020048,/* iROM Function Pointer + -EMMC4.4 end boot operation */ + [SPI_INDEX] = 0x02020058, /* iROM Function Pointer-SPI boot */ + [USB_INDEX] = 0x02020070, /* iROM Function Pointer-USB boot*/ + }; + +void *get_irom_func(int index) +{ + return (void *)*(u32 *)irom_ptr_table[index]; +} + +#ifdef CONFIG_USB_BOOTING +/* + * Set/clear program flow prediction and return the previous state. + */ +static int config_branch_prediction(int set_cr_z) +{ + unsigned int cr; + + /* System Control Register: 11th bit Z Branch prediction enable */ + cr = get_cr(); + set_cr(set_cr_z ? cr | CR_Z : cr & ~CR_Z); + + return cr & CR_Z; +} +#endif + +#ifdef CONFIG_SPI_BOOTING +static void spi_rx_tx(struct exynos_spi *regs, int todo, + void *dinp, void const *doutp, int i) +{ + uint *rxp = (uint *)(dinp + (i * (32 * 1024))); + int rx_lvl, tx_lvl; + uint out_bytes, in_bytes; + + out_bytes = todo; + in_bytes = todo; + setbits_le32(®s->ch_cfg, SPI_CH_RST); + clrbits_le32(®s->ch_cfg, SPI_CH_RST); + writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, ®s->pkt_cnt); + + while (in_bytes) { + uint32_t spi_sts; + int temp; + + spi_sts = readl(®s->spi_sts); + rx_lvl = ((spi_sts >> 15) & 0x7f); + tx_lvl = ((spi_sts >> 6) & 0x7f); + while (tx_lvl < 32 && out_bytes) { + temp = 0xffffffff; + writel(temp, ®s->tx_data); + out_bytes -= 4; + tx_lvl += 4; + } + while (rx_lvl >= 4 && in_bytes) { + temp = readl(®s->rx_data); + if (rxp) + *rxp++ = temp; + in_bytes -= 4; + rx_lvl -= 4; + } + } +} + +/* + * Copy uboot from spi flash to RAM + * + * @parma uboot_size size of u-boot to copy + * @param uboot_addr address in u-boot to copy + */ +static void exynos_spi_copy(unsigned int uboot_size, unsigned int uboot_addr) +{ + int upto, todo; + int i, timeout = 100; + struct exynos_spi *regs = (struct exynos_spi *)CONFIG_ENV_SPI_BASE; + + set_spi_clk(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */ + /* set the spi1 GPIO */ + exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE); + + /* set pktcnt and enable it */ + writel(4 | SPI_PACKET_CNT_EN, ®s->pkt_cnt); + /* set FB_CLK_SEL */ + writel(SPI_FB_DELAY_180, ®s->fb_clk); + /* set CH_WIDTH and BUS_WIDTH as word */ + setbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD | + SPI_MODE_BUS_WIDTH_WORD); + clrbits_le32(®s->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */ + + /* clear rx and tx channel if set priveously */ + clrbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON); + + setbits_le32(®s->swap_cfg, SPI_RX_SWAP_EN | + SPI_RX_BYTE_SWAP | + SPI_RX_HWORD_SWAP); + + /* do a soft reset */ + setbits_le32(®s->ch_cfg, SPI_CH_RST); + clrbits_le32(®s->ch_cfg, SPI_CH_RST); + + /* now set rx and tx channel ON */ + setbits_le32(®s->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN); + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */ + + /* Send read instruction (0x3h) followed by a 24 bit addr */ + writel((SF_READ_DATA_CMD << 24) | SPI_FLASH_UBOOT_POS, ®s->tx_data); + + /* waiting for TX done */ + while (!(readl(®s->spi_sts) & SPI_ST_TX_DONE)) { + if (!timeout) { + debug("SPI TIMEOUT\n"); + break; + } + timeout--; + } + + for (upto = 0, i = 0; upto < uboot_size; upto += todo, i++) { + todo = min(uboot_size - upto, (unsigned int)(1 << 15)); + spi_rx_tx(regs, todo, (void *)(uboot_addr), + (void *)(SPI_FLASH_UBOOT_POS), i); + } + + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */ + + /* + * Let put controller mode to BYTE as + * SPI driver does not support WORD mode yet + */ + clrbits_le32(®s->mode_cfg, SPI_MODE_CH_WIDTH_WORD | + SPI_MODE_BUS_WIDTH_WORD); + writel(0, ®s->swap_cfg); + + /* + * Flush spi tx, rx fifos and reset the SPI controller + * and clear rx/tx channel + */ + clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST); + clrbits_le32(®s->ch_cfg, SPI_CH_RST); + clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON); +} +#endif + +/* +* Copy U-boot from mmc to RAM: +* COPY_BL2_FNPTR_ADDR: Address in iRAM, which Contains +* Pointer to API (Data transfer from mmc to ram) +*/ +void copy_uboot_to_ram(void) +{ + unsigned int bootmode = BOOT_MODE_OM; + + u32 (*copy_bl2)(u32 offset, u32 nblock, u32 dst) = NULL; + u32 offset = 0, size = 0; +#ifdef CONFIG_SPI_BOOTING + struct spl_machine_param *param = spl_get_machine_params(); +#endif +#ifdef CONFIG_SUPPORT_EMMC_BOOT + u32 (*copy_bl2_from_emmc)(u32 nblock, u32 dst); + void (*end_bootop_from_emmc)(void); +#endif +#ifdef CONFIG_USB_BOOTING + int is_cr_z_set; + unsigned int sec_boot_check; + + /* + * Note that older hardware (before Exynos5800) does not expect any + * arguments, but it does not hurt to pass them, so a common function + * prototype is used. + */ + u32 (*usb_copy)(u32 num_of_block, u32 *dst); + + /* Read iRAM location to check for secondary USB boot mode */ + sec_boot_check = readl(EXYNOS_IRAM_SECONDARY_BASE); + if (sec_boot_check == EXYNOS_USB_SECONDARY_BOOT) + bootmode = BOOT_MODE_USB; +#endif + + if (bootmode == BOOT_MODE_OM) + bootmode = get_boot_mode(); + + switch (bootmode) { +#ifdef CONFIG_SPI_BOOTING + case BOOT_MODE_SERIAL: + /* Customised function to copy u-boot from SF */ + exynos_spi_copy(param->uboot_size, CONFIG_SYS_TEXT_BASE); + break; +#endif + case BOOT_MODE_SD: + offset = BL2_START_OFFSET; + size = BL2_SIZE_BLOC_COUNT; + copy_bl2 = get_irom_func(MMC_INDEX); + break; +#ifdef CONFIG_SUPPORT_EMMC_BOOT + case BOOT_MODE_EMMC: + /* Set the FSYS1 clock divisor value for EMMC boot */ + emmc_boot_clk_div_set(); + + copy_bl2_from_emmc = get_irom_func(EMMC44_INDEX); + end_bootop_from_emmc = get_irom_func(EMMC44_END_INDEX); + + copy_bl2_from_emmc(BL2_SIZE_BLOC_COUNT, CONFIG_SYS_TEXT_BASE); + end_bootop_from_emmc(); + break; +#endif +#ifdef CONFIG_USB_BOOTING + case BOOT_MODE_USB: + /* + * iROM needs program flow prediction to be disabled + * before copy from USB device to RAM + */ + is_cr_z_set = config_branch_prediction(0); + usb_copy = get_irom_func(USB_INDEX); + usb_copy(0, (u32 *)CONFIG_SYS_TEXT_BASE); + config_branch_prediction(is_cr_z_set); + break; +#endif + default: + break; + } + + if (copy_bl2) + copy_bl2(offset, size, CONFIG_SYS_TEXT_BASE); +} + +void memzero(void *s, size_t n) +{ + char *ptr = s; + size_t i; + + for (i = 0; i < n; i++) + *ptr++ = '\0'; +} + +/** + * Set up the U-Boot global_data pointer + * + * This sets the address of the global data, and sets up basic values. + * + * @param gdp Value to give to gd + */ +static void setup_global_data(gd_t *gdp) +{ + gd = gdp; + memzero((void *)gd, sizeof(gd_t)); + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + gd->have_console = 1; +} + +void board_init_f(unsigned long bootflag) +{ + __aligned(8) gd_t local_gd; + __attribute__((noreturn)) void (*uboot)(void); + + setup_global_data(&local_gd); + + if (do_lowlevel_init()) + power_exit_wakeup(); + + copy_uboot_to_ram(); + + /* Jump to U-Boot image */ + uboot = (void *)CONFIG_SYS_TEXT_BASE; + (*uboot)(); + /* Never returns Here */ +} + +/* Place Holders */ +void board_init_r(gd_t *id, ulong dest_addr) +{ + /* Function attribute is no-return */ + /* This Function never executes */ + while (1) + ; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/system.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/system.c new file mode 100644 index 0000000..ad12445 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/system.c
@@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Donghwa Lee <dh09.lee@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/system.h> + +static void exynos5_set_usbhost_mode(unsigned int mode) +{ + struct exynos5_sysreg *sysreg = + (struct exynos5_sysreg *)samsung_get_base_sysreg(); + + /* Setting USB20PHY_CONFIG register to USB 2.0 HOST link */ + if (mode == USB20_PHY_CFG_HOST_LINK_EN) { + setbits_le32(&sysreg->usb20phy_cfg, + USB20_PHY_CFG_HOST_LINK_EN); + } else { + clrbits_le32(&sysreg->usb20phy_cfg, + USB20_PHY_CFG_HOST_LINK_EN); + } +} + +void set_usbhost_mode(unsigned int mode) +{ + if (cpu_is_exynos5()) + exynos5_set_usbhost_mode(mode); +} + +static void exynos4_set_system_display(void) +{ + struct exynos4_sysreg *sysreg = + (struct exynos4_sysreg *)samsung_get_base_sysreg(); + unsigned int cfg = 0; + + /* + * system register path set + * 0: MIE/MDNIE + * 1: FIMD Bypass + */ + cfg = readl(&sysreg->display_ctrl); + cfg |= (1 << 1); + writel(cfg, &sysreg->display_ctrl); +} + +static void exynos5_set_system_display(void) +{ + struct exynos5_sysreg *sysreg = + (struct exynos5_sysreg *)samsung_get_base_sysreg(); + unsigned int cfg = 0; + + /* + * system register path set + * 0: MIE/MDNIE + * 1: FIMD Bypass + */ + cfg = readl(&sysreg->disp1blk_cfg); + cfg |= (1 << 15); + writel(cfg, &sysreg->disp1blk_cfg); +} + +void set_system_display_ctrl(void) +{ + if (cpu_is_exynos4()) + exynos4_set_system_display(); + else + exynos5_set_system_display(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/exynos/tzpc.c b/u-boot-imx/arch/arm/cpu/armv7/exynos/tzpc.c new file mode 100644 index 0000000..395077c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/exynos/tzpc.c
@@ -0,0 +1,41 @@ +/* + * Lowlevel setup for SMDK5250 board based on S5PC520 + * + * Copyright (C) 2012 Samsung Electronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/tzpc.h> +#include <asm/io.h> + +/* Setting TZPC[TrustZone Protection Controller] */ +void tzpc_init(void) +{ + struct exynos_tzpc *tzpc; + unsigned int addr, start = 0, end = 0; + + start = samsung_get_base_tzpc(); + + if (cpu_is_exynos5()) + end = start + ((EXYNOS5_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET); + else if (cpu_is_exynos4()) + end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET); + + for (addr = start; addr <= end; addr += TZPC_BASE_OFFSET) { + tzpc = (struct exynos_tzpc *)addr; + + if (addr == start) + writel(R0SIZE, &tzpc->r0size); + + writel(DECPROTXSET, &tzpc->decprot0set); + writel(DECPROTXSET, &tzpc->decprot1set); + + if (cpu_is_exynos5() && (addr == end)) + break; + + writel(DECPROTXSET, &tzpc->decprot2set); + writel(DECPROTXSET, &tzpc->decprot3set); + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/iproc-common/Makefile b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/Makefile new file mode 100644 index 0000000..c071a17 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/Makefile
@@ -0,0 +1,9 @@ +# +# Copyright 2014 Broadcom Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += armpll.o +obj-y += hwinit-common.o +obj-y += timer.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/iproc-common/armpll.c b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/armpll.c new file mode 100644 index 0000000..49b61bf --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/armpll.c
@@ -0,0 +1,170 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/iproc-common/armpll.h> +#include <asm/iproc-common/sysmap.h> + +#define NELEMS(x) (sizeof(x) / sizeof(x[0])) + +struct armpll_parameters { + unsigned int mode; + unsigned int ndiv_int; + unsigned int ndiv_frac; + unsigned int pdiv; + unsigned int freqid; +}; + +struct armpll_parameters armpll_clk_tab[] = { + { 25, 64, 1, 1, 0}, + { 100, 64, 1, 1, 2}, + { 400, 64, 1, 1, 6}, + { 448, 71, 713050, 1, 6}, + { 500, 80, 1, 1, 6}, + { 560, 89, 629145, 1, 6}, + { 600, 96, 1, 1, 6}, + { 800, 64, 1, 1, 7}, + { 896, 71, 713050, 1, 7}, + { 1000, 80, 1, 1, 7}, + { 1100, 88, 1, 1, 7}, + { 1120, 89, 629145, 1, 7}, + { 1200, 96, 1, 1, 7}, +}; + +uint32_t armpll_config(uint32_t clkmhz) +{ + uint32_t freqid; + uint32_t ndiv_frac; + uint32_t pll; + uint32_t status = 1; + uint32_t timeout_countdown; + int i; + + for (i = 0; i < NELEMS(armpll_clk_tab); i++) { + if (armpll_clk_tab[i].mode == clkmhz) { + status = 0; + break; + } + } + + if (status) { + printf("Error: Clock configuration not supported\n"); + goto armpll_config_done; + } + + /* Enable write access */ + writel(IPROC_REG_WRITE_ACCESS, IHOST_PROC_CLK_WR_ACCESS); + + if (clkmhz == 25) + freqid = 0; + else + freqid = 2; + + /* Bypass ARM clock and run on sysclk */ + writel(1 << IHOST_PROC_CLK_POLICY_FREQ__PRIV_ACCESS_MODE | + freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY3_FREQ_R | + freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY2_FREQ_R | + freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY1_FREQ_R | + freqid << IHOST_PROC_CLK_POLICY_FREQ__POLICY0_FREQ_R, + IHOST_PROC_CLK_POLICY_FREQ); + + writel(1 << IHOST_PROC_CLK_POLICY_CTL__GO | + 1 << IHOST_PROC_CLK_POLICY_CTL__GO_AC, + IHOST_PROC_CLK_POLICY_CTL); + + /* Poll CCU until operation complete */ + timeout_countdown = 0x100000; + while (readl(IHOST_PROC_CLK_POLICY_CTL) & + (1 << IHOST_PROC_CLK_POLICY_CTL__GO)) { + timeout_countdown--; + if (timeout_countdown == 0) { + printf("CCU polling timedout\n"); + status = 1; + goto armpll_config_done; + } + } + + if (clkmhz == 25 || clkmhz == 100) { + status = 0; + goto armpll_config_done; + } + + /* Now it is safe to program the PLL */ + pll = readl(IHOST_PROC_CLK_PLLARMB); + pll &= ~((1 << IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_WIDTH) - 1); + ndiv_frac = + ((1 << IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_WIDTH) - 1) & + (armpll_clk_tab[i].ndiv_frac << + IHOST_PROC_CLK_PLLARMB__PLLARM_NDIV_FRAC_R); + pll |= ndiv_frac; + writel(pll, IHOST_PROC_CLK_PLLARMB); + + writel(1 << IHOST_PROC_CLK_PLLARMA__PLLARM_LOCK | + armpll_clk_tab[i].ndiv_int << + IHOST_PROC_CLK_PLLARMA__PLLARM_NDIV_INT_R | + armpll_clk_tab[i].pdiv << + IHOST_PROC_CLK_PLLARMA__PLLARM_PDIV_R | + 1 << IHOST_PROC_CLK_PLLARMA__PLLARM_SOFT_RESETB, + IHOST_PROC_CLK_PLLARMA); + + /* Poll ARM PLL Lock until operation complete */ + timeout_countdown = 0x100000; + while (readl(IHOST_PROC_CLK_PLLARMA) & + (1 << IHOST_PROC_CLK_PLLARMA__PLLARM_LOCK)) { + timeout_countdown--; + if (timeout_countdown == 0) { + printf("ARM PLL lock failed\n"); + status = 1; + goto armpll_config_done; + } + } + + pll = readl(IHOST_PROC_CLK_PLLARMA); + pll |= (1 << IHOST_PROC_CLK_PLLARMA__PLLARM_SOFT_POST_RESETB); + writel(pll, IHOST_PROC_CLK_PLLARMA); + + /* Set the policy */ + writel(1 << IHOST_PROC_CLK_POLICY_FREQ__PRIV_ACCESS_MODE | + armpll_clk_tab[i].freqid << + IHOST_PROC_CLK_POLICY_FREQ__POLICY3_FREQ_R | + armpll_clk_tab[i].freqid << + IHOST_PROC_CLK_POLICY_FREQ__POLICY2_FREQ_R | + armpll_clk_tab[i].freqid << + IHOST_PROC_CLK_POLICY_FREQ__POLICY1_FREQ_R | + armpll_clk_tab[i+4].freqid << + IHOST_PROC_CLK_POLICY_FREQ__POLICY0_FREQ_R, + IHOST_PROC_CLK_POLICY_FREQ); + + writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_CORE0_CLKGATE); + writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_CORE1_CLKGATE); + writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_ARM_SWITCH_CLKGATE); + writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_ARM_PERIPH_CLKGATE); + writel(IPROC_CLKCT_HDELAY_SW_EN, IHOST_PROC_CLK_APB0_CLKGATE); + + writel(1 << IHOST_PROC_CLK_POLICY_CTL__GO | + 1 << IHOST_PROC_CLK_POLICY_CTL__GO_AC, + IHOST_PROC_CLK_POLICY_CTL); + + /* Poll CCU until operation complete */ + timeout_countdown = 0x100000; + while (readl(IHOST_PROC_CLK_POLICY_CTL) & + (1 << IHOST_PROC_CLK_POLICY_CTL__GO)) { + timeout_countdown--; + if (timeout_countdown == 0) { + printf("CCU polling failed\n"); + status = 1; + goto armpll_config_done; + } + } + + status = 0; +armpll_config_done: + /* Disable access to PLL registers */ + writel(0, IHOST_PROC_CLK_WR_ACCESS); + + return status; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/iproc-common/hwinit-common.c b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/hwinit-common.c new file mode 100644 index 0000000..7131524 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/hwinit-common.c
@@ -0,0 +1,15 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/iproc-common/timer.c b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/timer.c new file mode 100644 index 0000000..373d8ec --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/iproc-common/timer.c
@@ -0,0 +1,130 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/iproc-common/timer.h> +#include <asm/iproc-common/sysmap.h> + +static inline uint64_t timer_global_read(void) +{ + uint64_t cur_tick; + uint32_t count_h; + uint32_t count_l; + + do { + count_h = readl(IPROC_PERIPH_GLB_TIM_REG_BASE + + TIMER_GLB_HI_OFFSET); + count_l = readl(IPROC_PERIPH_GLB_TIM_REG_BASE + + TIMER_GLB_LOW_OFFSET); + cur_tick = readl(IPROC_PERIPH_GLB_TIM_REG_BASE + + TIMER_GLB_HI_OFFSET); + } while (cur_tick != count_h); + + return (cur_tick << 32) + count_l; +} + +void timer_global_init(void) +{ + writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_CTRL_OFFSET); + writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_LOW_OFFSET); + writel(0, IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_HI_OFFSET); + writel(TIMER_GLB_TIM_CTRL_TIM_EN, + IPROC_PERIPH_GLB_TIM_REG_BASE + TIMER_GLB_CTRL_OFFSET); +} + +int timer_init(void) +{ + timer_global_init(); + return 0; +} + +unsigned long get_timer(unsigned long base) +{ + uint64_t count; + uint64_t ret; + uint64_t tim_clk; + uint64_t periph_clk; + + count = timer_global_read(); + + /* default arm clk is 1GHz, periph_clk=arm_clk/2, tick per msec */ + periph_clk = 500000; + tim_clk = lldiv(periph_clk, + (((readl(IPROC_PERIPH_GLB_TIM_REG_BASE + + TIMER_GLB_CTRL_OFFSET) & + TIMER_GLB_TIM_CTRL_PRESC_MASK) >> 8) + 1)); + + ret = lldiv(count, (uint32_t)tim_clk); + + /* returns msec */ + return ret - base; +} + +void __udelay(unsigned long usec) +{ + uint64_t cur_tick, end_tick; + uint64_t tim_clk; + uint64_t periph_clk; + + /* default arm clk is 1GHz, periph_clk=arm_clk/2, tick per usec */ + periph_clk = 500; + + tim_clk = lldiv(periph_clk, + (((readl(IPROC_PERIPH_GLB_TIM_REG_BASE + + TIMER_GLB_CTRL_OFFSET) & + TIMER_GLB_TIM_CTRL_PRESC_MASK) >> 8) + 1)); + + cur_tick = timer_global_read(); + + end_tick = tim_clk; + end_tick *= usec; + end_tick += cur_tick; + + do { + cur_tick = timer_global_read(); + + } while (cur_tick < end_tick); +} + +void timer_systick_init(uint32_t tick_ms) +{ + /* Disable timer and clear interrupt status*/ + writel(0, IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_CTRL_OFFSET); + writel(TIMER_PVT_TIM_INT_STATUS_SET, + IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_STATUS_OFFSET); + writel((PLL_AXI_CLK/1000) * tick_ms, + IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_LOAD_OFFSET); + writel(TIMER_PVT_TIM_CTRL_INT_EN | + TIMER_PVT_TIM_CTRL_AUTO_RELD | + TIMER_PVT_TIM_CTRL_TIM_EN, + IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_CTRL_OFFSET); +} + +void timer_systick_isr(void *data) +{ + writel(TIMER_PVT_TIM_INT_STATUS_SET, + IPROC_PERIPH_PVT_TIM_REG_BASE + TIMER_PVT_STATUS_OFFSET); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value in msec. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This is used in conjuction with get_ticks, which returns msec as ticks. + * Here we just return ticks/sec = msec/sec = 1000 + */ +ulong get_tbclk(void) +{ + return 1000; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/kona-common/Makefile b/u-boot-imx/arch/arm/cpu/armv7/kona-common/Makefile new file mode 100644 index 0000000..da225cb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/kona-common/Makefile
@@ -0,0 +1,9 @@ +# +# Copyright 2013 Broadcom Corporation. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += s_init.o +obj-y += hwinit-common.o +obj-y += clk-stubs.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/kona-common/clk-stubs.c b/u-boot-imx/arch/arm/cpu/armv7/kona-common/clk-stubs.c new file mode 100644 index 0000000..fa10802 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/kona-common/clk-stubs.c
@@ -0,0 +1,26 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +/* + * These weak functions are available to kona architectures that don't + * require clock enables from the driver code. + */ +int __weak clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep) +{ + return 0; +} + +int __weak clk_bsc_enable(void *base, u32 rate, u32 *actual_ratep) +{ + return 0; +} + +int __weak clk_usb_otg_enable(void *base) +{ + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/kona-common/hwinit-common.c b/u-boot-imx/arch/arm/cpu/armv7/kona-common/hwinit-common.c new file mode 100644 index 0000000..2b3a840 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/kona-common/hwinit-common.c
@@ -0,0 +1,16 @@ +/* + * Copyright 2013 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/sizes.h> + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/kona-common/s_init.c b/u-boot-imx/arch/arm/cpu/armv7/kona-common/s_init.c new file mode 100644 index 0000000..6066a73 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/kona-common/s_init.c
@@ -0,0 +1,12 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Early system init. Currently empty. + */ +void s_init(void) +{ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/lowlevel_init.S new file mode 100644 index 0000000..427b0b1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/lowlevel_init.S
@@ -0,0 +1,59 @@ +/* + * A lowlevel_init function that sets up the stack to call a C function to + * perform further init. + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + /* + * Setup a temporary stack. Global data is not available yet. + */ + ldr sp, =CONFIG_SYS_INIT_SP_ADDR + bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ +#ifdef CONFIG_DM + mov r9, #0 +#else + /* + * Set up global data for boards that still need it. This will be + * removed soon. + */ +#ifdef CONFIG_SPL_BUILD + ldr r9, =gdata +#else + sub sp, sp, #GD_SIZE + bic sp, sp, #7 + mov r9, sp +#endif +#endif + /* + * Save the old lr(passed in ip) and the current lr to stack + */ + push {ip, lr} + + /* + * Call the very early init function. This should do only the + * absolute bare minimum to get started. It should not: + * + * - set up DRAM + * - use global_data + * - clear BSS + * - try to start a console + * + * For boards with SPL this should be empty since SPL can do all of + * this init in the SPL board_init_f() function which is called + * immediately after this. + */ + bl s_init + pop {ip, pc} +ENDPROC(lowlevel_init)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/Makefile b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/Makefile new file mode 100644 index 0000000..2e6a207 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/Makefile
@@ -0,0 +1,14 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o +obj-y += clock.o +obj-y += timer.o +obj-y += fsl_epu.o + +obj-$(CONFIG_OF_LIBFDT) += fdt.o +obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o +obj-$(CONFIG_SPL) += spl.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/clock.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/clock.c new file mode 100644 index 0000000..8f80c61 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/clock.c
@@ -0,0 +1,130 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h> +#include <fsl_ifc.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS +#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 +#endif + +void get_sys_info(struct sys_info *sys_info) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); +#ifdef CONFIG_FSL_IFC + struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + u32 ccr; +#endif + struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR); + unsigned int cpu; + const u8 core_cplx_pll[6] = { + [0] = 0, /* CC1 PPL / 1 */ + [1] = 0, /* CC1 PPL / 2 */ + [4] = 1, /* CC2 PPL / 1 */ + [5] = 1, /* CC2 PPL / 2 */ + }; + + const u8 core_cplx_pll_div[6] = { + [0] = 1, /* CC1 PPL / 1 */ + [1] = 2, /* CC1 PPL / 2 */ + [4] = 1, /* CC2 PPL / 1 */ + [5] = 2, /* CC2 PPL / 2 */ + }; + + uint i; + uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; + uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; + unsigned long sysclk = CONFIG_SYS_CLK_FREQ; + + sys_info->freq_systembus = sysclk; +#ifdef CONFIG_DDR_CLK_FREQ + sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; +#else + sys_info->freq_ddrbus = sysclk; +#endif + + sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> + RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK; + sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >> + RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK; + + for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { + ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f; + if (ratio[i] > 4) + freq_c_pll[i] = sysclk * ratio[i]; + else + freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; + } + + for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) { + u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27) + & 0xf; + u32 cplx_pll = core_cplx_pll[c_pll_sel]; + + sys_info->freq_processor[cpu] = + freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; + } + +#if defined(CONFIG_FSL_IFC) + ccr = in_be32(&ifc_regs->ifc_ccr); + ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; + + sys_info->freq_localbus = sys_info->freq_systembus / ccr; +#endif +} + +int get_clocks(void) +{ + struct sys_info sys_info; + + get_sys_info(&sys_info); + gd->cpu_clk = sys_info.freq_processor[0]; + gd->bus_clk = sys_info.freq_systembus; + gd->mem_clk = sys_info.freq_ddrbus * 2; + +#if defined(CONFIG_FSL_ESDHC) + gd->arch.sdhc_clk = gd->bus_clk; +#endif + + return 0; +} + +ulong get_bus_freq(ulong dummy) +{ + return gd->bus_clk; +} + +ulong get_ddr_freq(ulong dummy) +{ + return gd->mem_clk; +} + +int get_serial_clock(void) +{ + return gd->bus_clk / 2; +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_I2C_CLK: + return get_bus_freq(0) / 2; + case MXC_ESDHC_CLK: + return get_bus_freq(0); + case MXC_DSPI_CLK: + return get_bus_freq(0) / 2; + case MXC_UART_CLK: + return get_bus_freq(0) / 2; + default: + printf("Unsupported clock\n"); + } + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/cpu.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/cpu.c new file mode 100644 index 0000000..1a640bb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/cpu.c
@@ -0,0 +1,348 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/cache.h> +#include <asm/system.h> +#include <tsec.h> +#include <netdev.h> +#include <fsl_esdhc.h> + +#include "fsl_epu.h" + +#define DCSR_RCPM2_BLOCK_OFFSET 0x223000 +#define DCSR_RCPM2_CPMFSMCR0 0x400 +#define DCSR_RCPM2_CPMFSMSR0 0x404 +#define DCSR_RCPM2_CPMFSMCR1 0x414 +#define DCSR_RCPM2_CPMFSMSR1 0x418 +#define CPMFSMSR_FSM_STATE_MASK 0x7f + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_DCACHE_OFF + +/* + * Bit[1] of the descriptor indicates the descriptor type, + * and bit[0] indicates whether the descriptor is valid. + */ +#define PMD_TYPE_TABLE 0x3 +#define PMD_TYPE_SECT 0x1 + +/* AttrIndx[2:0] */ +#define PMD_ATTRINDX(t) ((t) << 2) + +/* Section */ +#define PMD_SECT_AF (1 << 10) + +#define BLOCK_SIZE_L1 (1UL << 30) +#define BLOCK_SIZE_L2 (1UL << 21) + +/* TTBCR flags */ +#define TTBCR_EAE (1 << 31) +#define TTBCR_T0SZ(x) ((x) << 0) +#define TTBCR_T1SZ(x) ((x) << 16) +#define TTBCR_USING_TTBR0 (TTBCR_T0SZ(0) | TTBCR_T1SZ(0)) +#define TTBCR_IRGN0_NC (0 << 8) +#define TTBCR_IRGN0_WBWA (1 << 8) +#define TTBCR_IRGN0_WT (2 << 8) +#define TTBCR_IRGN0_WBNWA (3 << 8) +#define TTBCR_IRGN0_MASK (3 << 8) +#define TTBCR_ORGN0_NC (0 << 10) +#define TTBCR_ORGN0_WBWA (1 << 10) +#define TTBCR_ORGN0_WT (2 << 10) +#define TTBCR_ORGN0_WBNWA (3 << 10) +#define TTBCR_ORGN0_MASK (3 << 10) +#define TTBCR_SHARED_NON (0 << 12) +#define TTBCR_SHARED_OUTER (2 << 12) +#define TTBCR_SHARED_INNER (3 << 12) +#define TTBCR_EPD0 (0 << 7) +#define TTBCR (TTBCR_SHARED_NON | \ + TTBCR_ORGN0_NC | \ + TTBCR_IRGN0_NC | \ + TTBCR_USING_TTBR0 | \ + TTBCR_EAE) + +/* + * Memory region attributes for LPAE (defined in pgtable): + * + * n = AttrIndx[2:0] + * + * n MAIR + * UNCACHED 000 00000000 + * BUFFERABLE 001 01000100 + * DEV_WC 001 01000100 + * WRITETHROUGH 010 10101010 + * WRITEBACK 011 11101110 + * DEV_CACHED 011 11101110 + * DEV_SHARED 100 00000100 + * DEV_NONSHARED 100 00000100 + * unused 101 + * unused 110 + * WRITEALLOC 111 11111111 + */ +#define MT_MAIR0 0xeeaa4400 +#define MT_MAIR1 0xff000004 +#define MT_STRONLY_ORDER 0 +#define MT_NORMAL_NC 1 +#define MT_DEVICE_MEM 4 +#define MT_NORMAL 7 + +/* The phy_addr must be aligned to 4KB */ +static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr) +{ + u32 value = phy_addr | PMD_TYPE_TABLE; + + page_table[2 * index] = value; + page_table[2 * index + 1] = 0; +} + +/* The phy_addr must be aligned to 4KB */ +static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr, + u32 memory_type) +{ + u64 value; + + value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF; + value |= PMD_ATTRINDX(memory_type); + page_table[2 * index] = value & 0xFFFFFFFF; + page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF; +} + +/* + * Start MMU after DDR is available, we create MMU table in DRAM. + * The base address of TTLB is gd->arch.tlb_addr. We use two + * levels of translation tables here to cover 40-bit address space. + * + * The TTLBs are located at PHY 2G~4G. + * + * VA mapping: + * + * ------- <---- 0GB + * | | + * | | + * |-------| <---- 0x24000000 + * |///////| ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000 + * |-------| <---- 0x300000000 + * | | + * |-------| <---- 0x34000000 + * |///////| ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000 + * |-------| <---- 0x40000000 + * | | + * |-------| <---- 0x80000000 DDR0 space start + * |\\\\\\\| + *.|\\\\\\\| ===> 2GB VA map for 2GB DDR0 Memory space + * |\\\\\\\| + * ------- <---- 4GB DDR0 space end + */ +static void mmu_setup(void) +{ + u32 *level0_table = (u32 *)gd->arch.tlb_addr; + u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000); + u64 va_start = 0; + u32 reg; + int i; + + /* Level 0 Table 2-3 are used to map DDR */ + set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL); + set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL); + /* Level 0 Table 1 is used to map device */ + set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM); + /* Level 0 Table 0 is used to map device including PCIe MEM */ + set_pgtable(level0_table, 0, (u32)level1_table); + + /* Level 1 has 512 entries */ + for (i = 0; i < 512; i++) { + /* Mapping for PCIe 1 */ + if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR && + va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR + + CONFIG_SYS_PCIE_MMAP_SIZE)) + set_pgsection(level1_table, i, + CONFIG_SYS_PCIE1_PHYS_BASE + va_start, + MT_DEVICE_MEM); + /* Mapping for PCIe 2 */ + else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR && + va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR + + CONFIG_SYS_PCIE_MMAP_SIZE)) + set_pgsection(level1_table, i, + CONFIG_SYS_PCIE2_PHYS_BASE + va_start, + MT_DEVICE_MEM); + else + set_pgsection(level1_table, i, + va_start, + MT_DEVICE_MEM); + va_start += BLOCK_SIZE_L2; + } + + asm volatile("dsb sy;isb"); + asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */ + : : "r" (TTBCR) : "memory"); + asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */ + : : "r" ((u32)level0_table), "r" (0) : "memory"); + asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */ + : : "r" (MT_MAIR0) : "memory"); + asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */ + : : "r" (MT_MAIR1) : "memory"); + + /* Set the access control to all-supervisor */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + : : "r" (~0)); + + /* Enable the mmu */ + reg = get_cr(); + set_cr(reg | CR_M); +} + +/* + * This function is called from lib/board.c. It recreates MMU + * table in main memory. MMU and i/d-cache are enabled here. + */ +void enable_caches(void) +{ + /* Invalidate all TLB */ + mmu_page_table_flush(gd->arch.tlb_addr, + gd->arch.tlb_addr + gd->arch.tlb_size); + /* Set up and enable mmu */ + mmu_setup(); + + /* Invalidate & Enable d-cache */ + invalidate_dcache_all(); + set_cr(get_cr() | CR_C); +} +#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */ + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf1[32], buf2[32]; + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major, minor, ver, i; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + minor = SVR_MIN(svr); + + puts("CPU: Freescale LayerScape "); + + ver = SVR_SOC_VER(svr); + switch (ver) { + case SOC_VER_SLS1020: + puts("SLS1020"); + break; + case SOC_VER_LS1020: + puts("LS1020"); + break; + case SOC_VER_LS1021: + puts("LS1021"); + break; + case SOC_VER_LS1022: + puts("LS1022"); + break; + default: + puts("Unknown"); + break; + } + + if (IS_E_PROCESSOR(svr) && (ver != SOC_VER_SLS1020)) + puts("E"); + + printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); + + puts("Clock Configuration:"); + + printf("\n CPU0(ARMV7):%-4s MHz, ", strmhz(buf1, gd->cpu_clk)); + printf("\n Bus:%-4s MHz, ", strmhz(buf1, gd->bus_clk)); + printf("DDR:%-4s MHz (%s MT/s data rate), ", + strmhz(buf1, gd->mem_clk/2), strmhz(buf2, gd->mem_clk)); + puts("\n"); + + /* Display the RCW, so that no one gets confused as to what RCW + * we're actually using for this boot. + */ + puts("Reset Configuration Word (RCW):"); + for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { + u32 rcw = in_be32(&gur->rcwsr[i]); + + if ((i % 4) == 0) + printf("\n %08x:", i * 4); + printf(" %08x", rcw); + } + puts("\n"); + + return 0; +} +#endif + +#ifdef CONFIG_FSL_ESDHC +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +int cpu_eth_init(bd_t *bis) +{ +#ifdef CONFIG_TSEC_ENET + tsec_standard_init(bis); +#endif + + return 0; +} + +int arch_cpu_init(void) +{ + void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *rcpm2_base = + (void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET); + u32 state; + + /* + * The RCPM FSM state may not be reset after power-on. + * So, reset them. + */ + state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) & + CPMFSMSR_FSM_STATE_MASK; + if (state != 0) { + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80); + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0); + } + + state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) & + CPMFSMSR_FSM_STATE_MASK; + if (state != 0) { + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80); + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0); + } + + /* + * After wakeup from deep sleep, Clear EPU registers + * as early as possible to prevent from possible issue. + * It's also safe to clear at normal boot. + */ + fsl_epu_clean(epu_base); + + return 0; +} + +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +/* Set the address at which the secondary core starts from.*/ +void smp_set_core_boot_addr(unsigned long addr, int corenr) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + out_be32(&gur->scratchrw[0], addr); +} + +/* Release the secondary core from holdoff state and kick it */ +void smp_kick_all_cpus(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + out_be32(&gur->brrl, 0x2); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fdt.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fdt.c new file mode 100644 index 0000000..71a1753 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fdt.c
@@ -0,0 +1,185 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/arch/clock.h> +#include <linux/ctype.h> +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> +#endif +#include <tsec.h> +#include <asm/arch/immap_ls102xa.h> +#include <fsl_sec.h> + +DECLARE_GLOBAL_DATA_PTR; + +void ft_fixup_enet_phy_connect_type(void *fdt) +{ + struct eth_device *dev; + struct tsec_private *priv; + const char *enet_path, *phy_path; + char enet[16]; + char phy[16]; + int phy_node; + int i = 0; + int enet_id = 0; + uint32_t ph; + + while ((dev = eth_get_dev_by_index(i++)) != NULL) { + if (strstr(dev->name, "eTSEC1")) + enet_id = 0; + else if (strstr(dev->name, "eTSEC2")) + enet_id = 1; + else if (strstr(dev->name, "eTSEC3")) + enet_id = 2; + else + continue; + + priv = dev->priv; + if (priv->flags & TSEC_SGMII) + continue; + + sprintf(enet, "ethernet%d", enet_id); + enet_path = fdt_get_alias(fdt, enet); + if (!enet_path) + continue; + + sprintf(phy, "enet%d_rgmii_phy", enet_id); + phy_path = fdt_get_alias(fdt, phy); + if (!phy_path) + continue; + + phy_node = fdt_path_offset(fdt, phy_path); + if (phy_node < 0) + continue; + + ph = fdt_create_phandle(fdt, phy_node); + if (ph) + do_fixup_by_path_u32(fdt, enet_path, + "phy-handle", ph, 1); + + do_fixup_by_path(fdt, enet_path, "phy-connection-type", + phy_string_for_interface( + PHY_INTERFACE_MODE_RGMII_ID), + sizeof(phy_string_for_interface( + PHY_INTERFACE_MODE_RGMII_ID)), + 1); + } +} + +void ft_cpu_setup(void *blob, bd_t *bd) +{ + int off; + int val; + const char *sysclk_path; + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr; + svr = in_be32(&gur->svr); + + unsigned long busclk = get_bus_freq(0); + + /* delete crypto node if not on an E-processor */ + if (!IS_E_PROCESSOR(svr)) + fdt_fixup_crypto_node(blob, 0); +#if CONFIG_SYS_FSL_SEC_COMPAT >= 4 + else { + ccsr_sec_t __iomem *sec; + + sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; + fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms)); + } +#endif + + fdt_fixup_ethernet(blob); + + off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); + while (off != -FDT_ERR_NOTFOUND) { + val = gd->cpu_clk; + fdt_setprop(blob, off, "clock-frequency", &val, 4); + off = fdt_node_offset_by_prop_value(blob, off, + "device_type", "cpu", 4); + } + + do_fixup_by_prop_u32(blob, "device_type", "soc", + 4, "bus-frequency", busclk, 1); + + ft_fixup_enet_phy_connect_type(blob); + +#ifdef CONFIG_SYS_NS16550 + do_fixup_by_compat_u32(blob, "fsl,16550-FIFO64", + "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); +#endif + + sysclk_path = fdt_get_alias(blob, "sysclk"); + if (sysclk_path) + do_fixup_by_path_u32(blob, sysclk_path, "clock-frequency", + CONFIG_SYS_CLK_FREQ, 1); + do_fixup_by_compat_u32(blob, "fsl,qoriq-sysclk-2.0", + "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); + +#if defined(CONFIG_DEEP_SLEEP) && defined(CONFIG_SD_BOOT) +#define UBOOT_HEAD_LEN 0x1000 + /* + * Reserved memory in SD boot deep sleep case. + * Second stage uboot binary and malloc space should be reserved. + * If the memory they occupied has not been reserved, then this + * space would be used by kernel and overwritten in uboot when + * deep sleep resume, which cause deep sleep failed. + * Since second uboot binary has a head, that space need to be + * reserved either(assuming its size is less than 0x1000). + */ + off = fdt_add_mem_rsv(blob, CONFIG_SYS_TEXT_BASE - UBOOT_HEAD_LEN, + CONFIG_SYS_MONITOR_LEN + CONFIG_SYS_SPL_MALLOC_SIZE + + UBOOT_HEAD_LEN); + if (off < 0) + printf("Failed to reserve memory for SD boot deep sleep: %s\n", + fdt_strerror(off)); +#endif + +#if defined(CONFIG_FSL_ESDHC) + fdt_fixup_esdhc(blob, bd); +#endif + + /* + * platform bus clock = system bus clock/2 + * Here busclk = system bus clock + * We are using the platform bus clock as 1588 Timer reference + * clock source select + */ + do_fixup_by_compat_u32(blob, "fsl, gianfar-ptp-timer", + "timer-frequency", busclk / 2, 1); + + /* + * clock-freq should change to clock-frequency and + * flexcan-v1.0 should change to p1010-flexcan respectively + * in the future. + */ + do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0", + "clock_freq", busclk / 2, 1); + + do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0", + "clock-frequency", busclk / 2, 1); + + do_fixup_by_compat_u32(blob, "fsl, ls1021a-flexcan", + "clock-frequency", busclk / 2, 1); + +#ifdef CONFIG_QSPI_BOOT + off = fdt_node_offset_by_compat_reg(blob, FSL_IFC_COMPAT, + CONFIG_SYS_IFC_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); +#else + off = fdt_node_offset_by_compat_reg(blob, FSL_QSPI_COMPAT, + QSPI0_BASE_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); + off = fdt_node_offset_by_compat_reg(blob, FSL_DSPI_COMPAT, + DSPI1_BASE_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); +#endif +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.c new file mode 100644 index 0000000..6212640 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.c
@@ -0,0 +1,57 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#include "fsl_epu.h" + +/** + * fsl_epu_clean - Clear EPU registers + */ +void fsl_epu_clean(void *epu_base) +{ + u32 offset; + + /* follow the exact sequence to clear the registers */ + /* Clear EPACRn */ + for (offset = EPACR0; offset <= EPACR15; offset += EPACR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPEVTCRn */ + for (offset = EPEVTCR0; offset <= EPEVTCR9; offset += EPEVTCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPGCR */ + out_be32(epu_base + EPGCR, 0); + + /* Clear EPSMCRn */ + for (offset = EPSMCR0; offset <= EPSMCR15; offset += EPSMCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCCRn */ + for (offset = EPCCR0; offset <= EPCCR31; offset += EPCCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCMPRn */ + for (offset = EPCMPR0; offset <= EPCMPR31; offset += EPCMPR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCTRn */ + for (offset = EPCTR0; offset <= EPCTR31; offset += EPCTR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPIMCRn */ + for (offset = EPIMCR0; offset <= EPIMCR31; offset += EPIMCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPXTRIGCRn */ + out_be32(epu_base + EPXTRIGCR, 0); + + /* Clear EPECRn */ + for (offset = EPECR0; offset <= EPECR15; offset += EPECR_STRIDE) + out_be32(epu_base + offset, 0); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.h b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.h new file mode 100644 index 0000000..d658aad --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_epu.h
@@ -0,0 +1,68 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_EPU_H +#define __FSL_EPU_H + +#include <asm/types.h> + +#define FSL_STRIDE_4B 4 +#define FSL_STRIDE_8B 8 + +/* Block offsets */ +#define EPU_BLOCK_OFFSET 0x00000000 + +/* EPGCR (Event Processor Global Control Register) */ +#define EPGCR 0x000 + +/* EPEVTCR0-9 (Event Processor EVT Pin Control Registers) */ +#define EPEVTCR0 0x050 +#define EPEVTCR9 0x074 +#define EPEVTCR_STRIDE FSL_STRIDE_4B + +/* EPXTRIGCR (Event Processor Crosstrigger Control Register) */ +#define EPXTRIGCR 0x090 + +/* EPIMCR0-31 (Event Processor Input Mux Control Registers) */ +#define EPIMCR0 0x100 +#define EPIMCR31 0x17C +#define EPIMCR_STRIDE FSL_STRIDE_4B + +/* EPSMCR0-15 (Event Processor SCU Mux Control Registers) */ +#define EPSMCR0 0x200 +#define EPSMCR15 0x278 +#define EPSMCR_STRIDE FSL_STRIDE_8B + +/* EPECR0-15 (Event Processor Event Control Registers) */ +#define EPECR0 0x300 +#define EPECR15 0x33C +#define EPECR_STRIDE FSL_STRIDE_4B + +/* EPACR0-15 (Event Processor Action Control Registers) */ +#define EPACR0 0x400 +#define EPACR15 0x43C +#define EPACR_STRIDE FSL_STRIDE_4B + +/* EPCCRi0-15 (Event Processor Counter Control Registers) */ +#define EPCCR0 0x800 +#define EPCCR15 0x83C +#define EPCCR31 0x87C +#define EPCCR_STRIDE FSL_STRIDE_4B + +/* EPCMPR0-15 (Event Processor Counter Compare Registers) */ +#define EPCMPR0 0x900 +#define EPCMPR15 0x93C +#define EPCMPR31 0x97C +#define EPCMPR_STRIDE FSL_STRIDE_4B + +/* EPCTR0-31 (Event Processor Counter Register) */ +#define EPCTR0 0xA00 +#define EPCTR31 0xA7C +#define EPCTR_STRIDE FSL_STRIDE_4B + +void fsl_epu_clean(void *epu_base); + +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c new file mode 100644 index 0000000..9b78acb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
@@ -0,0 +1,120 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/errno.h> +#include <asm/io.h> +#include "fsl_ls1_serdes.h" + +#ifdef CONFIG_SYS_FSL_SRDS_1 +static u64 serdes1_prtcl_map; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 +static u64 serdes2_prtcl_map; +#endif + +int is_serdes_configured(enum srds_prtcl device) +{ + u64 ret = 0; + +#ifdef CONFIG_SYS_FSL_SRDS_1 + ret |= (1ULL << device) & serdes1_prtcl_map; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + ret |= (1ULL << device) & serdes2_prtcl_map; +#endif + + return !!ret; +} + +int serdes_get_first_lane(u32 sd, enum srds_prtcl device) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 cfg = in_be32(&gur->rcwsr[4]); + int i; + + switch (sd) { +#ifdef CONFIG_SYS_FSL_SRDS_1 + case FSL_SRDS_1: + cfg &= RCWSR4_SRDS1_PRTCL_MASK; + cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT; + break; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + case FSL_SRDS_2: + cfg &= RCWSR4_SRDS2_PRTCL_MASK; + cfg >>= RCWSR4_SRDS2_PRTCL_SHIFT; + break; +#endif + default: + printf("invalid SerDes%d\n", sd); + break; + } + /* Is serdes enabled at all? */ + if (unlikely(cfg == 0)) + return -ENODEV; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_get_prtcl(sd, cfg, i) == device) + return i; + } + + return -ENODEV; +} + +u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u64 serdes_prtcl_map = 0; + u32 cfg; + int lane; + + cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask; + cfg >>= sd_prctl_shift; + printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg); + + if (!is_serdes_prtcl_valid(sd, cfg)) + printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg); + + for (lane = 0; lane < SRDS_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane); + + serdes_prtcl_map |= (1ULL << lane_prtcl); + } + + return serdes_prtcl_map; +} + +void fsl_serdes_init(void) +{ +#ifdef CONFIG_SYS_FSL_SRDS_1 + serdes1_prtcl_map = serdes_init(FSL_SRDS_1, + CONFIG_SYS_FSL_SERDES_ADDR, + RCWSR4_SRDS1_PRTCL_MASK, + RCWSR4_SRDS1_PRTCL_SHIFT); +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + serdes2_prtcl_map = serdes_init(FSL_SRDS_2, + CONFIG_SYS_FSL_SERDES_ADDR + + FSL_SRDS_2 * 0x1000, + RCWSR4_SRDS2_PRTCL_MASK, + RCWSR4_SRDS2_PRTCL_SHIFT); +#endif +} + +const char *serdes_clock_to_string(u32 clock) +{ + switch (clock) { + case SRDS_PLLCR0_RFCK_SEL_100: + return "100"; + case SRDS_PLLCR0_RFCK_SEL_125: + return "125"; + default: + return "100"; + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h new file mode 100644 index 0000000..834aa53 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h
@@ -0,0 +1,12 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_LS1_SERDES_H +#define __FSL_LS1_SERDES_H + +int is_serdes_prtcl_valid(int serdes, u32 prtcl); +int serdes_lane_enabled(int lane); +#endif /* __FSL_LS1_SERDES_H */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c new file mode 100644 index 0000000..cc53910 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c
@@ -0,0 +1,41 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/immap_ls102xa.h> + +static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { + [0x00] = {PCIE1, PCIE1, PCIE1, PCIE1}, + [0x10] = {PCIE1, SATA1, PCIE2, PCIE2}, + [0x20] = {PCIE1, SGMII_TSEC1, PCIE2, SGMII_TSEC2}, + [0x30] = {PCIE1, SATA1, SGMII_TSEC1, SGMII_TSEC2}, + [0x40] = {PCIE1, PCIE1, SATA1, SGMII_TSEC2}, + [0x50] = {PCIE1, PCIE1, PCIE2, SGMII_TSEC2}, + [0x60] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2}, + [0x70] = {PCIE1, SATA1, PCIE2, SGMII_TSEC2}, + [0x80] = {PCIE2, PCIE2, PCIE2, PCIE2}, +}; + +enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane) +{ + return serdes_cfg_tbl[cfg][lane]; +} + +int is_serdes_prtcl_valid(int serdes, u32 prtcl) +{ + int i; + + if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl)) + return 0; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_cfg_tbl[prtcl][i] != NONE) + return 1; + } + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/spl.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/spl.c new file mode 100644 index 0000000..1dfbf54 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/spl.c
@@ -0,0 +1,33 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <spl.h> + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_MMC_SUPPORT + return BOOT_DEVICE_MMC1; +#endif + return BOOT_DEVICE_NAND; +} + +u32 spl_boot_mode(void) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: +#ifdef CONFIG_SPL_FAT_SUPPORT + return MMCSD_MODE_FAT; +#else + return MMCSD_MODE_RAW; +#endif + case BOOT_DEVICE_NAND: + return 0; + default: + puts("spl: error: unsupported device\n"); + hang(); + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/ls102xa/timer.c b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/timer.c new file mode 100644 index 0000000..11b17b2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/ls102xa/timer.c
@@ -0,0 +1,127 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <div64.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * This function is intended for SHORT delays only. + * It will overflow at around 10 seconds @ 400MHz, + * or 20 seconds @ 200MHz. + */ +unsigned long usec2ticks(unsigned long usec) +{ + ulong ticks; + + if (usec < 1000) + ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; + else + ticks = ((usec / 10) * (get_tbclk() / 100000)); + + return ticks; +} + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + tick *= CONFIG_SYS_HZ; + do_div(tick, freq); + + return tick; +} + +static inline unsigned long long us_to_tick(unsigned long long usec) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + usec = usec * freq + 999999; + do_div(usec, 1000000); + + return usec; +} + +int timer_init(void) +{ + struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR; + unsigned long ctrl, val, freq; + + /* Enable System Counter */ + writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr); + + freq = GENERIC_TIMER_CLK; + asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* Set PL1 Physical Timer Ctrl */ + ctrl = ARCH_TIMER_CTRL_ENABLE; + asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl)); + + /* Set PL1 Physical Comp Value */ + val = TIMER_COMP_VAL; + asm("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val)); + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + return 0; +} + +unsigned long long get_ticks(void) +{ + unsigned long long now; + + asm("mrrc p15, 0, %Q0, %R0, c14" : "=r" (now)); + + gd->arch.tbl = (unsigned long)(now & 0xffffffff); + gd->arch.tbu = (unsigned long)(now >> 32); + + return now; +} + +unsigned long get_timer_masked(void) +{ + return tick_to_time(get_ticks()); +} + +unsigned long get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds and preserve advance timstamp value */ +void __udelay(unsigned long usec) +{ + unsigned long long start; + unsigned long tmo; + + start = get_ticks(); /* get current timestamp */ + tmo = us_to_tick(usec); /* convert usecs to ticks */ + + while ((get_ticks() - start) < tmo) + ; /* loop till time has passed */ +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + return freq; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx5/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/mx5/Kconfig new file mode 100644 index 0000000..2d6c0ce --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx5/Kconfig
@@ -0,0 +1,27 @@ +if ARCH_MX5 + +config MX5 + bool + default y + +config MX51 + bool + +config MX53 + bool + +choice + prompt "MX5 board select" + +config TARGET_USBARMORY + bool "Support USB armory" + select CPU_V7 + +endchoice + +config SYS_SOC + default "mx5" + +source "board/inversepath/usbarmory/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx5/Makefile b/u-boot-imx/arch/arm/cpu/armv7/mx5/Makefile new file mode 100644 index 0000000..d021842 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx5/Makefile
@@ -0,0 +1,11 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2009 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := soc.o clock.o +obj-y += lowlevel_init.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx5/clock.c b/u-boot-imx/arch/arm/cpu/armv7/mx5/clock.c new file mode 100644 index 0000000..bf52f0d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx5/clock.c
@@ -0,0 +1,949 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <div64.h> +#include <asm/arch/sys_proto.h> + +enum pll_clocks { + PLL1_CLOCK = 0, + PLL2_CLOCK, + PLL3_CLOCK, +#ifdef CONFIG_MX53 + PLL4_CLOCK, +#endif + PLL_CLOCKS, +}; + +struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { + [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, + [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, + [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, +#ifdef CONFIG_MX53 + [PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR, +#endif +}; + +#define AHB_CLK_ROOT 133333333 +#define SZ_DEC_1M 1000000 +#define PLL_PD_MAX 16 /* Actual pd+1 */ +#define PLL_MFI_MAX 15 +#define PLL_MFI_MIN 5 +#define ARM_DIV_MAX 8 +#define IPG_DIV_MAX 4 +#define AHB_DIV_MAX 8 +#define EMI_DIV_MAX 8 +#define NFC_DIV_MAX 8 + +#define MX5_CBCMR 0x00015154 +#define MX5_CBCDR 0x02888945 + +struct fixed_pll_mfd { + u32 ref_clk_hz; + u32 mfd; +}; + +const struct fixed_pll_mfd fixed_mfd[] = { + {MXC_HCLK, 24 * 16}, +}; + +struct pll_param { + u32 pd; + u32 mfi; + u32 mfn; + u32 mfd; +}; + +#define PLL_FREQ_MAX(ref_clk) (4 * (ref_clk) * PLL_MFI_MAX) +#define PLL_FREQ_MIN(ref_clk) \ + ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX) +#define MAX_DDR_CLK 420000000 +#define NFC_CLK_MAX 34000000 + +struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; + +void set_usboh3_clk(void) +{ + clrsetbits_le32(&mxc_ccm->cscmr1, + MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK, + MXC_CCM_CSCMR1_USBOH3_CLK_SEL(1)); + clrsetbits_le32(&mxc_ccm->cscdr1, + MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK | + MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK, + MXC_CCM_CSCDR1_USBOH3_CLK_PRED(4) | + MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1)); +} + +void enable_usboh3_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR2, + MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR2_USBOH3_60M(cg)); +} + +#ifdef CONFIG_SYS_I2C_MXC +/* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */ +int enable_i2c_clk(unsigned char enable, unsigned i2c_num) +{ + u32 mask; + +#if defined(CONFIG_MX51) + if (i2c_num > 1) +#elif defined(CONFIG_MX53) + if (i2c_num > 2) +#endif + return -EINVAL; + mask = MXC_CCM_CCGR_CG_MASK << + (MXC_CCM_CCGR1_I2C1_OFFSET + (i2c_num << 1)); + if (enable) + setbits_le32(&mxc_ccm->CCGR1, mask); + else + clrbits_le32(&mxc_ccm->CCGR1, mask); + return 0; +} +#endif + +void set_usb_phy_clk(void) +{ + clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL); +} + +#if defined(CONFIG_MX51) +void enable_usb_phy1_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR2, + MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR2_USB_PHY(cg)); +} + +void enable_usb_phy2_clk(bool enable) +{ + /* i.MX51 has a single USB PHY clock, so do nothing here. */ +} +#elif defined(CONFIG_MX53) +void enable_usb_phy1_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_USB_PHY1(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR4_USB_PHY1(cg)); +} + +void enable_usb_phy2_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_USB_PHY2(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR4_USB_PHY2(cg)); +} +#endif + +/* + * Calculate the frequency of PLLn. + */ +static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) +{ + uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret; + uint64_t refclk, temp; + int32_t mfn_abs; + + ctrl = readl(&pll->ctrl); + + if (ctrl & MXC_DPLLC_CTL_HFSM) { + mfn = readl(&pll->hfs_mfn); + mfd = readl(&pll->hfs_mfd); + op = readl(&pll->hfs_op); + } else { + mfn = readl(&pll->mfn); + mfd = readl(&pll->mfd); + op = readl(&pll->op); + } + + mfd &= MXC_DPLLC_MFD_MFD_MASK; + mfn &= MXC_DPLLC_MFN_MFN_MASK; + pdf = op & MXC_DPLLC_OP_PDF_MASK; + mfi = MXC_DPLLC_OP_MFI_RD(op); + + /* 21.2.3 */ + if (mfi < 5) + mfi = 5; + + /* Sign extend */ + if (mfn >= 0x04000000) { + mfn |= 0xfc000000; + mfn_abs = -mfn; + } else + mfn_abs = mfn; + + refclk = infreq * 2; + if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN) + refclk *= 2; + + do_div(refclk, pdf + 1); + temp = refclk * mfn_abs; + do_div(temp, mfd + 1); + ret = refclk * mfi; + + if ((int)mfn < 0) + ret -= temp; + else + ret += temp; + + return ret; +} + +#ifdef CONFIG_MX51 +/* + * This function returns the Frequency Pre-Multiplier clock. + */ +static u32 get_fpm(void) +{ + u32 mult; + u32 ccr = readl(&mxc_ccm->ccr); + + if (ccr & MXC_CCM_CCR_FPM_MULT) + mult = 1024; + else + mult = 512; + + return MXC_CLK32 * mult; +} +#endif + +/* + * This function returns the low power audio clock. + */ +static u32 get_lp_apm(void) +{ + u32 ret_val = 0; + u32 ccsr = readl(&mxc_ccm->ccsr); + + if (ccsr & MXC_CCM_CCSR_LP_APM) +#if defined(CONFIG_MX51) + ret_val = get_fpm(); +#elif defined(CONFIG_MX53) + ret_val = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); +#endif + else + ret_val = MXC_HCLK; + + return ret_val; +} + +/* + * Get mcu main rate + */ +u32 get_mcu_main_clk(void) +{ + u32 reg, freq; + + reg = MXC_CCM_CACRR_ARM_PODF_RD(readl(&mxc_ccm->cacrr)); + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); + return freq / (reg + 1); +} + +/* + * Get the rate of peripheral's root clock. + */ +u32 get_periph_clk(void) +{ + u32 reg; + + reg = readl(&mxc_ccm->cbcdr); + if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) + return decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); + reg = readl(&mxc_ccm->cbcmr); + switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD(reg)) { + case 0: + return decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); + case 1: + return decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); + case 2: + return get_lp_apm(); + default: + return 0; + } + /* NOTREACHED */ +} + +/* + * Get the rate of ipg clock. + */ +static u32 get_ipg_clk(void) +{ + uint32_t freq, reg, div; + + freq = get_ahb_clk(); + + reg = readl(&mxc_ccm->cbcdr); + div = MXC_CCM_CBCDR_IPG_PODF_RD(reg) + 1; + + return freq / div; +} + +/* + * Get the rate of ipg_per clock. + */ +static u32 get_ipg_per_clk(void) +{ + u32 freq, pred1, pred2, podf; + + if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) + return get_ipg_clk(); + + if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) + freq = get_lp_apm(); + else + freq = get_periph_clk(); + podf = readl(&mxc_ccm->cbcdr); + pred1 = MXC_CCM_CBCDR_PERCLK_PRED1_RD(podf); + pred2 = MXC_CCM_CBCDR_PERCLK_PRED2_RD(podf); + podf = MXC_CCM_CBCDR_PERCLK_PODF_RD(podf); + return freq / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); +} + +/* Get the output clock rate of a standard PLL MUX for peripherals. */ +static u32 get_standard_pll_sel_clk(u32 clk_sel) +{ + u32 freq = 0; + + switch (clk_sel & 0x3) { + case 0: + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); + break; + case 1: + freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); + break; + case 2: + freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); + break; + case 3: + freq = get_lp_apm(); + break; + } + + return freq; +} + +/* + * Get the rate of uart clk. + */ +static u32 get_uart_clk(void) +{ + unsigned int clk_sel, freq, reg, pred, podf; + + reg = readl(&mxc_ccm->cscmr1); + clk_sel = MXC_CCM_CSCMR1_UART_CLK_SEL_RD(reg); + freq = get_standard_pll_sel_clk(clk_sel); + + reg = readl(&mxc_ccm->cscdr1); + pred = MXC_CCM_CSCDR1_UART_CLK_PRED_RD(reg); + podf = MXC_CCM_CSCDR1_UART_CLK_PODF_RD(reg); + freq /= (pred + 1) * (podf + 1); + + return freq; +} + +/* + * get cspi clock rate. + */ +static u32 imx_get_cspiclk(void) +{ + u32 ret_val = 0, pdf, pre_pdf, clk_sel, freq; + u32 cscmr1 = readl(&mxc_ccm->cscmr1); + u32 cscdr2 = readl(&mxc_ccm->cscdr2); + + pre_pdf = MXC_CCM_CSCDR2_CSPI_CLK_PRED_RD(cscdr2); + pdf = MXC_CCM_CSCDR2_CSPI_CLK_PODF_RD(cscdr2); + clk_sel = MXC_CCM_CSCMR1_CSPI_CLK_SEL_RD(cscmr1); + freq = get_standard_pll_sel_clk(clk_sel); + ret_val = freq / ((pre_pdf + 1) * (pdf + 1)); + return ret_val; +} + +/* + * get esdhc clock rate. + */ +static u32 get_esdhc_clk(u32 port) +{ + u32 clk_sel = 0, pred = 0, podf = 0, freq = 0; + u32 cscmr1 = readl(&mxc_ccm->cscmr1); + u32 cscdr1 = readl(&mxc_ccm->cscdr1); + + switch (port) { + case 0: + clk_sel = MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_RD(cscmr1); + pred = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_RD(cscdr1); + podf = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_RD(cscdr1); + break; + case 1: + clk_sel = MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_RD(cscmr1); + pred = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_RD(cscdr1); + podf = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_RD(cscdr1); + break; + case 2: + if (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_CLK_SEL) + return get_esdhc_clk(1); + else + return get_esdhc_clk(0); + case 3: + if (cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL) + return get_esdhc_clk(1); + else + return get_esdhc_clk(0); + default: + break; + } + + freq = get_standard_pll_sel_clk(clk_sel) / ((pred + 1) * (podf + 1)); + return freq; +} + +static u32 get_axi_a_clk(void) +{ + u32 cbcdr = readl(&mxc_ccm->cbcdr); + u32 pdf = MXC_CCM_CBCDR_AXI_A_PODF_RD(cbcdr); + + return get_periph_clk() / (pdf + 1); +} + +static u32 get_axi_b_clk(void) +{ + u32 cbcdr = readl(&mxc_ccm->cbcdr); + u32 pdf = MXC_CCM_CBCDR_AXI_B_PODF_RD(cbcdr); + + return get_periph_clk() / (pdf + 1); +} + +static u32 get_emi_slow_clk(void) +{ + u32 cbcdr = readl(&mxc_ccm->cbcdr); + u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL; + u32 pdf = MXC_CCM_CBCDR_EMI_PODF_RD(cbcdr); + + if (emi_clk_sel) + return get_ahb_clk() / (pdf + 1); + + return get_periph_clk() / (pdf + 1); +} + +static u32 get_ddr_clk(void) +{ + u32 ret_val = 0; + u32 cbcmr = readl(&mxc_ccm->cbcmr); + u32 ddr_clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); +#ifdef CONFIG_MX51 + u32 cbcdr = readl(&mxc_ccm->cbcdr); + if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) { + u32 ddr_clk_podf = MXC_CCM_CBCDR_DDR_PODF_RD(cbcdr); + + ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); + ret_val /= ddr_clk_podf + 1; + + return ret_val; + } +#endif + switch (ddr_clk_sel) { + case 0: + ret_val = get_axi_a_clk(); + break; + case 1: + ret_val = get_axi_b_clk(); + break; + case 2: + ret_val = get_emi_slow_clk(); + break; + case 3: + ret_val = get_ahb_clk(); + break; + default: + break; + } + + return ret_val; +} + +/* + * The API of get mxc clocks. + */ +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_mcu_main_clk(); + case MXC_AHB_CLK: + return get_ahb_clk(); + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_IPG_PERCLK: + case MXC_I2C_CLK: + return get_ipg_per_clk(); + case MXC_UART_CLK: + return get_uart_clk(); + case MXC_CSPI_CLK: + return imx_get_cspiclk(); + case MXC_ESDHC_CLK: + return get_esdhc_clk(0); + case MXC_ESDHC2_CLK: + return get_esdhc_clk(1); + case MXC_ESDHC3_CLK: + return get_esdhc_clk(2); + case MXC_ESDHC4_CLK: + return get_esdhc_clk(3); + case MXC_FEC_CLK: + return get_ipg_clk(); + case MXC_SATA_CLK: + return get_ahb_clk(); + case MXC_DDR_CLK: + return get_ddr_clk(); + default: + break; + } + return -EINVAL; +} + +u32 imx_get_uartclk(void) +{ + return get_uart_clk(); +} + +u32 imx_get_fecclk(void) +{ + return get_ipg_clk(); +} + +static int gcd(int m, int n) +{ + int t; + while (m > 0) { + if (n > m) { + t = m; + m = n; + n = t; + } /* swap */ + m -= n; + } + return n; +} + +/* + * This is to calculate various parameters based on reference clock and + * targeted clock based on the equation: + * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1) + * This calculation is based on a fixed MFD value for simplicity. + */ +static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll) +{ + u64 pd, mfi = 1, mfn, mfd, t1; + u32 n_target = target; + u32 n_ref = ref, i; + + /* + * Make sure targeted freq is in the valid range. + * Otherwise the following calculation might be wrong!!! + */ + if (n_target < PLL_FREQ_MIN(ref) || + n_target > PLL_FREQ_MAX(ref)) { + printf("Targeted peripheral clock should be" + "within [%d - %d]\n", + PLL_FREQ_MIN(ref) / SZ_DEC_1M, + PLL_FREQ_MAX(ref) / SZ_DEC_1M); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) { + if (fixed_mfd[i].ref_clk_hz == ref) { + mfd = fixed_mfd[i].mfd; + break; + } + } + + if (i == ARRAY_SIZE(fixed_mfd)) + return -EINVAL; + + /* Use n_target and n_ref to avoid overflow */ + for (pd = 1; pd <= PLL_PD_MAX; pd++) { + t1 = n_target * pd; + do_div(t1, (4 * n_ref)); + mfi = t1; + if (mfi > PLL_MFI_MAX) + return -EINVAL; + else if (mfi < 5) + continue; + break; + } + /* + * Now got pd and mfi already + * + * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref; + */ + t1 = n_target * pd; + do_div(t1, 4); + t1 -= n_ref * mfi; + t1 *= mfd; + do_div(t1, n_ref); + mfn = t1; + debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n", + ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd); + i = 1; + if (mfn != 0) + i = gcd(mfd, mfn); + pll->pd = (u32)pd; + pll->mfi = (u32)mfi; + do_div(mfn, i); + pll->mfn = (u32)mfn; + do_div(mfd, i); + pll->mfd = (u32)mfd; + + return 0; +} + +#define calc_div(tgt_clk, src_clk, limit) ({ \ + u32 v = 0; \ + if (((src_clk) % (tgt_clk)) <= 100) \ + v = (src_clk) / (tgt_clk); \ + else \ + v = ((src_clk) / (tgt_clk)) + 1;\ + if (v > limit) \ + v = limit; \ + (v - 1); \ + }) + +#define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \ + { \ + writel(0x1232, &pll->ctrl); \ + writel(0x2, &pll->config); \ + writel((((pd) - 1) << 0) | ((fi) << 4), \ + &pll->op); \ + writel(fn, &(pll->mfn)); \ + writel((fd) - 1, &pll->mfd); \ + writel((((pd) - 1) << 0) | ((fi) << 4), \ + &pll->hfs_op); \ + writel(fn, &pll->hfs_mfn); \ + writel((fd) - 1, &pll->hfs_mfd); \ + writel(0x1232, &pll->ctrl); \ + while (!readl(&pll->ctrl) & 0x1) \ + ;\ + } + +static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param) +{ + u32 ccsr = readl(&mxc_ccm->ccsr); + struct mxc_pll_reg *pll = mxc_plls[index]; + + switch (index) { + case PLL1_CLOCK: + /* Switch ARM to PLL2 clock */ + writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL, + &mxc_ccm->ccsr); + CHANGE_PLL_SETTINGS(pll, pll_param->pd, + pll_param->mfi, pll_param->mfn, + pll_param->mfd); + /* Switch back */ + writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL, + &mxc_ccm->ccsr); + break; + case PLL2_CLOCK: + /* Switch to pll2 bypass clock */ + writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL, + &mxc_ccm->ccsr); + CHANGE_PLL_SETTINGS(pll, pll_param->pd, + pll_param->mfi, pll_param->mfn, + pll_param->mfd); + /* Switch back */ + writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL, + &mxc_ccm->ccsr); + break; + case PLL3_CLOCK: + /* Switch to pll3 bypass clock */ + writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL, + &mxc_ccm->ccsr); + CHANGE_PLL_SETTINGS(pll, pll_param->pd, + pll_param->mfi, pll_param->mfn, + pll_param->mfd); + /* Switch back */ + writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL, + &mxc_ccm->ccsr); + break; +#ifdef CONFIG_MX53 + case PLL4_CLOCK: + /* Switch to pll4 bypass clock */ + writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL, + &mxc_ccm->ccsr); + CHANGE_PLL_SETTINGS(pll, pll_param->pd, + pll_param->mfi, pll_param->mfn, + pll_param->mfd); + /* Switch back */ + writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL, + &mxc_ccm->ccsr); + break; +#endif + default: + return -EINVAL; + } + + return 0; +} + +/* Config CPU clock */ +static int config_core_clk(u32 ref, u32 freq) +{ + int ret = 0; + struct pll_param pll_param; + + memset(&pll_param, 0, sizeof(struct pll_param)); + + /* The case that periph uses PLL1 is not considered here */ + ret = calc_pll_params(ref, freq, &pll_param); + if (ret != 0) { + printf("Error:Can't find pll parameters: %d\n", ret); + return ret; + } + + return config_pll_clk(PLL1_CLOCK, &pll_param); +} + +static int config_nfc_clk(u32 nfc_clk) +{ + u32 parent_rate = get_emi_slow_clk(); + u32 div; + + if (nfc_clk == 0) + return -EINVAL; + div = parent_rate / nfc_clk; + if (div == 0) + div++; + if (parent_rate / div > NFC_CLK_MAX) + div++; + clrsetbits_le32(&mxc_ccm->cbcdr, + MXC_CCM_CBCDR_NFC_PODF_MASK, + MXC_CCM_CBCDR_NFC_PODF(div - 1)); + while (readl(&mxc_ccm->cdhipr) != 0) + ; + return 0; +} + +void enable_nfc_clk(unsigned char enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR5, + MXC_CCM_CCGR5_EMI_ENFC(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR5_EMI_ENFC(cg)); +} + +#ifdef CONFIG_FSL_IIM +void enable_efuse_prog_supply(bool enable) +{ + if (enable) + setbits_le32(&mxc_ccm->cgpr, + MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); + else + clrbits_le32(&mxc_ccm->cgpr, + MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); +} +#endif + +/* Config main_bus_clock for periphs */ +static int config_periph_clk(u32 ref, u32 freq) +{ + int ret = 0; + struct pll_param pll_param; + + memset(&pll_param, 0, sizeof(struct pll_param)); + + if (readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { + ret = calc_pll_params(ref, freq, &pll_param); + if (ret != 0) { + printf("Error:Can't find pll parameters: %d\n", + ret); + return ret; + } + switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD( + readl(&mxc_ccm->cbcmr))) { + case 0: + return config_pll_clk(PLL1_CLOCK, &pll_param); + break; + case 1: + return config_pll_clk(PLL3_CLOCK, &pll_param); + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int config_ddr_clk(u32 emi_clk) +{ + u32 clk_src; + s32 shift = 0, clk_sel, div = 1; + u32 cbcmr = readl(&mxc_ccm->cbcmr); + + if (emi_clk > MAX_DDR_CLK) { + printf("Warning:DDR clock should not exceed %d MHz\n", + MAX_DDR_CLK / SZ_DEC_1M); + emi_clk = MAX_DDR_CLK; + } + + clk_src = get_periph_clk(); + /* Find DDR clock input */ + clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); + switch (clk_sel) { + case 0: + shift = 16; + break; + case 1: + shift = 19; + break; + case 2: + shift = 22; + break; + case 3: + shift = 10; + break; + default: + return -EINVAL; + } + + if ((clk_src % emi_clk) < 10000000) + div = clk_src / emi_clk; + else + div = (clk_src / emi_clk) + 1; + if (div > 8) + div = 8; + + clrsetbits_le32(&mxc_ccm->cbcdr, 0x7 << shift, (div - 1) << shift); + while (readl(&mxc_ccm->cdhipr) != 0) + ; + writel(0x0, &mxc_ccm->ccdr); + + return 0; +} + +/* + * This function assumes the expected core clock has to be changed by + * modifying the PLL. This is NOT true always but for most of the times, + * it is. So it assumes the PLL output freq is the same as the expected + * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN. + * In the latter case, it will try to increase the presc value until + * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to + * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based + * on the targeted PLL and reference input clock to the PLL. Lastly, + * it sets the register based on these values along with the dividers. + * Note 1) There is no value checking for the passed-in divider values + * so the caller has to make sure those values are sensible. + * 2) Also adjust the NFC divider such that the NFC clock doesn't + * exceed NFC_CLK_MAX. + * 3) IPU HSP clock is independent of AHB clock. Even it can go up to + * 177MHz for higher voltage, this function fixes the max to 133MHz. + * 4) This function should not have allowed diag_printf() calls since + * the serial driver has been stoped. But leave then here to allow + * easy debugging by NOT calling the cyg_hal_plf_serial_stop(). + */ +int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk) +{ + freq *= SZ_DEC_1M; + + switch (clk) { + case MXC_ARM_CLK: + if (config_core_clk(ref, freq)) + return -EINVAL; + break; + case MXC_PERIPH_CLK: + if (config_periph_clk(ref, freq)) + return -EINVAL; + break; + case MXC_DDR_CLK: + if (config_ddr_clk(freq)) + return -EINVAL; + break; + case MXC_NFC_CLK: + if (config_nfc_clk(freq)) + return -EINVAL; + break; + default: + printf("Warning:Unsupported or invalid clock type\n"); + } + + return 0; +} + +#ifdef CONFIG_MX53 +/* + * The clock for the external interface can be set to use internal clock + * if fuse bank 4, row 3, bit 2 is set. + * This is an undocumented feature and it was confirmed by Freescale's support: + * Fuses (but not pins) may be used to configure SATA clocks. + * Particularly the i.MX53 Fuse_Map contains the next information + * about configuring SATA clocks : SATA_ALT_REF_CLK[1:0] (offset 0x180C) + * '00' - 100MHz (External) + * '01' - 50MHz (External) + * '10' - 120MHz, internal (USB PHY) + * '11' - Reserved +*/ +void mxc_set_sata_internal_clock(void) +{ + u32 *tmp_base = + (u32 *)(IIM_BASE_ADDR + 0x180c); + + set_usb_phy_clk(); + + clrsetbits_le32(tmp_base, 0x6, 0x4); +} +#endif + +/* + * Dump some core clockes. + */ +int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 freq; + + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); + printf("PLL1 %8d MHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); + printf("PLL2 %8d MHz\n", freq / 1000000); + freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); + printf("PLL3 %8d MHz\n", freq / 1000000); +#ifdef CONFIG_MX53 + freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); + printf("PLL4 %8d MHz\n", freq / 1000000); +#endif + + printf("\n"); + printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); + printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); + printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); + printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); +#ifdef CONFIG_MXC_SPI + printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); +#endif + return 0; +} + +/***************************************************/ + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks, + "display clocks", + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/mx5/lowlevel_init.S new file mode 100644 index 0000000..f5bc672 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx5/lowlevel_init.S
@@ -0,0 +1,429 @@ +/* + * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arch/imx-regs.h> +#include <generated/asm-offsets.h> +#include <linux/linkage.h> + +.section ".text.init", "x" + +.macro init_arm_erratum + /* ARM erratum ID #468414 */ + mrc 15, 0, r1, c1, c0, 1 + orr r1, r1, #(1 << 5) /* enable L1NEON bit */ + mcr 15, 0, r1, c1, c0, 1 +.endm + +/* + * L2CC Cache setup/invalidation/disable + */ +.macro init_l2cc + /* explicitly disable L2 cache */ + mrc 15, 0, r0, c1, c0, 1 + bic r0, r0, #0x2 + mcr 15, 0, r0, c1, c0, 1 + + /* reconfigure L2 cache aux control reg */ + ldr r0, =0xC0 | /* tag RAM */ \ + 0x4 | /* data RAM */ \ + 1 << 24 | /* disable write allocate delay */ \ + 1 << 23 | /* disable write allocate combine */ \ + 1 << 22 /* disable write allocate */ + +#if defined(CONFIG_MX51) + ldr r3, [r4, #ROM_SI_REV] + cmp r3, #0x10 + + /* disable write combine for TO 2 and lower revs */ + orrls r0, r0, #1 << 25 +#endif + + mcr 15, 1, r0, c9, c0, 2 + + /* enable L2 cache */ + mrc 15, 0, r0, c1, c0, 1 + orr r0, r0, #2 + mcr 15, 0, r0, c1, c0, 1 + +.endm /* init_l2cc */ + +/* AIPS setup - Only setup MPROTx registers. + * The PACR default values are good.*/ +.macro init_aips + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + ldr r0, =AIPS1_BASE_ADDR + ldr r1, =0x77777777 + str r1, [r0, #0x0] + str r1, [r0, #0x4] + ldr r0, =AIPS2_BASE_ADDR + str r1, [r0, #0x0] + str r1, [r0, #0x4] + /* + * Clear the on and off peripheral modules Supervisor Protect bit + * for SDMA to access them. Did not change the AIPS control registers + * (offset 0x20) access type + */ +.endm /* init_aips */ + +/* M4IF setup */ +.macro init_m4if +#ifdef CONFIG_MX51 + /* VPU and IPU given higher priority (0x4) + * IPU accesses with ID=0x1 given highest priority (=0xA) + */ + ldr r0, =M4IF_BASE_ADDR + + ldr r1, =0x00000203 + str r1, [r0, #0x40] + + str r4, [r0, #0x44] + + ldr r1, =0x00120125 + str r1, [r0, #0x9C] + + ldr r1, =0x001901A3 + str r1, [r0, #0x48] + +#endif +.endm /* init_m4if */ + +.macro setup_pll pll, freq + ldr r0, =\pll + adr r2, W_DP_\freq + bl setup_pll_func +.endm + +#define W_DP_OP 0 +#define W_DP_MFD 4 +#define W_DP_MFN 8 + +setup_pll_func: + ldr r1, =0x00001232 + str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ + mov r1, #0x2 + str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ + + ldr r1, [r2, #W_DP_OP] + str r1, [r0, #PLL_DP_OP] + str r1, [r0, #PLL_DP_HFS_OP] + + ldr r1, [r2, #W_DP_MFD] + str r1, [r0, #PLL_DP_MFD] + str r1, [r0, #PLL_DP_HFS_MFD] + + ldr r1, [r2, #W_DP_MFN] + str r1, [r0, #PLL_DP_MFN] + str r1, [r0, #PLL_DP_HFS_MFN] + + ldr r1, =0x00001232 + str r1, [r0, #PLL_DP_CTL] +1: ldr r1, [r0, #PLL_DP_CTL] + ands r1, r1, #0x1 + beq 1b + + /* r10 saved upper lr */ + mov pc, lr + +.macro setup_pll_errata pll, freq + ldr r2, =\pll + str r4, [r2, #PLL_DP_CONFIG] /* Disable auto-restart AREN bit */ + ldr r1, =0x00001236 + str r1, [r2, #PLL_DP_CTL] /* Restart PLL with PLM=1 */ +1: ldr r1, [r2, #PLL_DP_CTL] /* Wait for lock */ + ands r1, r1, #0x1 + beq 1b + + ldr r5, \freq + str r5, [r2, #PLL_DP_MFN] /* Modify MFN value */ + str r5, [r2, #PLL_DP_HFS_MFN] + + mov r1, #0x1 + str r1, [r2, #PLL_DP_CONFIG] /* Reload MFN value */ + +2: ldr r1, [r2, #PLL_DP_CONFIG] + tst r1, #1 + bne 2b + + ldr r1, =100 /* Wait at least 4 us */ +3: subs r1, r1, #1 + bge 3b + + mov r1, #0x2 + str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ +.endm + +.macro init_clock +#if defined (CONFIG_MX51) + ldr r0, =CCM_BASE_ADDR + + /* Gate of clocks to the peripherals first */ + ldr r1, =0x3FFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r4, [r0, #CLKCTL_CCGR1] + str r4, [r0, #CLKCTL_CCGR2] + str r4, [r0, #CLKCTL_CCGR3] + + ldr r1, =0x00030000 + str r1, [r0, #CLKCTL_CCGR4] + ldr r1, =0x00FFF030 + str r1, [r0, #CLKCTL_CCGR5] + ldr r1, =0x00000300 + str r1, [r0, #CLKCTL_CCGR6] + + /* Disable IPU and HSC dividers */ + mov r1, #0x60000 + str r1, [r0, #CLKCTL_CCDR] + + /* Make sure to switch the DDR away from PLL 1 */ + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + /* Switch ARM to step clock */ + mov r1, #0x4 + str r1, [r0, #CLKCTL_CCSR] + +#if defined(CONFIG_MX51_PLL_ERRATA) + setup_pll PLL1_BASE_ADDR, 864 + setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT +#else + setup_pll PLL1_BASE_ADDR, 800 +#endif + + setup_pll PLL3_BASE_ADDR, 665 + + /* Switch peripheral to PLL 3 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x000010C0 | CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + ldr r1, =0x13239145 + str r1, [r0, #CLKCTL_CBCDR] + setup_pll PLL2_BASE_ADDR, 665 + + /* Switch peripheral to PLL2 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x19239145 + str r1, [r0, #CLKCTL_CBCDR] + ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + + setup_pll PLL3_BASE_ADDR, 216 + + /* Set the platform clock dividers */ + ldr r0, =ARM_BASE_ADDR + ldr r1, =0x00000725 + str r1, [r0, #0x14] + + ldr r0, =CCM_BASE_ADDR + + /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ + ldr r3, [r4, #ROM_SI_REV] + cmp r3, #0x10 + movls r1, #0x1 + movhi r1, #0 + + str r1, [r0, #CLKCTL_CACRR] + + /* Switch ARM back to PLL 1 */ + str r4, [r0, #CLKCTL_CCSR] + + /* setup the rest */ + /* Use lp_apm (24MHz) source for perclk */ + ldr r1, =0x000020C2 | CONFIG_SYS_DDR_CLKSEL + str r1, [r0, #CLKCTL_CBCMR] + /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ + ldr r1, =CONFIG_SYS_CLKTL_CBCDR + str r1, [r0, #CLKCTL_CBCDR] + + /* Restore the default values in the Gate registers */ + ldr r1, =0xFFFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + str r1, [r0, #CLKCTL_CCGR4] + str r1, [r0, #CLKCTL_CCGR5] + str r1, [r0, #CLKCTL_CCGR6] + + /* Use PLL 2 for UART's, get 66.5MHz from it */ + ldr r1, =0xA5A2A020 + str r1, [r0, #CLKCTL_CSCMR1] + ldr r1, =0x00C30321 + str r1, [r0, #CLKCTL_CSCDR1] + /* make sure divider effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + str r4, [r0, #CLKCTL_CCDR] + + /* for cko - for ARM div by 8 */ + mov r1, #0x000A0000 + add r1, r1, #0x00000F0 + str r1, [r0, #CLKCTL_CCOSR] +#else /* CONFIG_MX53 */ + ldr r0, =CCM_BASE_ADDR + + /* Gate of clocks to the peripherals first */ + ldr r1, =0x3FFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r4, [r0, #CLKCTL_CCGR1] + str r4, [r0, #CLKCTL_CCGR2] + str r4, [r0, #CLKCTL_CCGR3] + str r4, [r0, #CLKCTL_CCGR7] + ldr r1, =0x00030000 + str r1, [r0, #CLKCTL_CCGR4] + ldr r1, =0x00FFF030 + str r1, [r0, #CLKCTL_CCGR5] + ldr r1, =0x0F00030F + str r1, [r0, #CLKCTL_CCGR6] + + /* Switch ARM to step clock */ + mov r1, #0x4 + str r1, [r0, #CLKCTL_CCSR] + + setup_pll PLL1_BASE_ADDR, 800 + + setup_pll PLL3_BASE_ADDR, 400 + + /* Switch peripheral to PLL3 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x00015154 + str r1, [r0, #CLKCTL_CBCMR] + ldr r1, =0x02898945 + str r1, [r0, #CLKCTL_CBCDR] + /* make sure change is effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + setup_pll PLL2_BASE_ADDR, 400 + + /* Switch peripheral to PLL2 */ + ldr r0, =CCM_BASE_ADDR + ldr r1, =0x00888945 + str r1, [r0, #CLKCTL_CBCDR] + + ldr r1, =0x00016154 + str r1, [r0, #CLKCTL_CBCMR] + + /*change uart clk parent to pll2*/ + ldr r1, [r0, #CLKCTL_CSCMR1] + and r1, r1, #0xfcffffff + orr r1, r1, #0x01000000 + str r1, [r0, #CLKCTL_CSCMR1] + + /* make sure change is effective */ +1: ldr r1, [r0, #CLKCTL_CDHIPR] + cmp r1, #0x0 + bne 1b + + setup_pll PLL3_BASE_ADDR, 216 + + setup_pll PLL4_BASE_ADDR, 455 + + /* Set the platform clock dividers */ + ldr r0, =ARM_BASE_ADDR + ldr r1, =0x00000124 + str r1, [r0, #0x14] + + ldr r0, =CCM_BASE_ADDR + mov r1, #0 + str r1, [r0, #CLKCTL_CACRR] + + /* Switch ARM back to PLL 1. */ + mov r1, #0x0 + str r1, [r0, #CLKCTL_CCSR] + + /* make uart div=6 */ + ldr r1, [r0, #CLKCTL_CSCDR1] + and r1, r1, #0xffffffc0 + orr r1, r1, #0x0a + str r1, [r0, #CLKCTL_CSCDR1] + + /* Restore the default values in the Gate registers */ + ldr r1, =0xFFFFFFFF + str r1, [r0, #CLKCTL_CCGR0] + str r1, [r0, #CLKCTL_CCGR1] + str r1, [r0, #CLKCTL_CCGR2] + str r1, [r0, #CLKCTL_CCGR3] + str r1, [r0, #CLKCTL_CCGR4] + str r1, [r0, #CLKCTL_CCGR5] + str r1, [r0, #CLKCTL_CCGR6] + str r1, [r0, #CLKCTL_CCGR7] + + mov r1, #0x00000 + str r1, [r0, #CLKCTL_CCDR] + + /* for cko - for ARM div by 8 */ + mov r1, #0x000A0000 + add r1, r1, #0x00000F0 + str r1, [r0, #CLKCTL_CCOSR] + +#endif /* CONFIG_MX53 */ +.endm + +ENTRY(lowlevel_init) + mov r10, lr + mov r4, #0 /* Fix R4 to 0 */ + +#if defined(CONFIG_SYS_MAIN_PWR_ON) + ldr r0, =GPIO1_BASE_ADDR + ldr r1, [r0, #0x0] + orr r1, r1, #1 << 23 + str r1, [r0, #0x0] + ldr r1, [r0, #0x4] + orr r1, r1, #1 << 23 + str r1, [r0, #0x4] +#endif + + init_arm_erratum + + init_l2cc + + init_aips + + init_m4if + + init_clock + + mov pc, r10 +ENDPROC(lowlevel_init) + +/* Board level setting value */ +#if defined(CONFIG_MX51_PLL_ERRATA) +W_DP_864: .word DP_OP_864 + .word DP_MFD_864 + .word DP_MFN_864 +W_DP_MFN_800_DIT: .word DP_MFN_800_DIT +#else +W_DP_800: .word DP_OP_800 + .word DP_MFD_800 + .word DP_MFN_800 +#endif +#if defined(CONFIG_MX51) +W_DP_665: .word DP_OP_665 + .word DP_MFD_665 + .word DP_MFN_665 +#endif +W_DP_216: .word DP_OP_216 + .word DP_MFD_216 + .word DP_MFN_216 +W_DP_400: .word DP_OP_400 + .word DP_MFD_400 + .word DP_MFN_400 +W_DP_455: .word DP_OP_455 + .word DP_MFD_455 + .word DP_MFN_455
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx5/soc.c b/u-boot-imx/arch/arm/cpu/armv7/mx5/soc.c new file mode 100644 index 0000000..3753c14 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx5/soc.c
@@ -0,0 +1,116 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/imx-common/boot_mode.h> + +#if !(defined(CONFIG_MX51) || defined(CONFIG_MX53)) +#error "CPU_TYPE not defined" +#endif + +u32 get_cpu_rev(void) +{ +#ifdef CONFIG_MX51 + int system_rev = 0x51000; +#else + int system_rev = 0x53000; +#endif + int reg = __raw_readl(ROM_SI_REV); + +#if defined(CONFIG_MX51) + switch (reg) { + case 0x02: + system_rev |= CHIP_REV_1_1; + break; + case 0x10: + if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) + system_rev |= CHIP_REV_2_5; + else + system_rev |= CHIP_REV_2_0; + break; + case 0x20: + system_rev |= CHIP_REV_3_0; + break; + default: + system_rev |= CHIP_REV_1_0; + break; + } +#else + if (reg < 0x20) + system_rev |= CHIP_REV_1_0; + else + system_rev |= reg; +#endif + return system_rev; +} + +#ifdef CONFIG_REVISION_TAG +u32 __weak get_board_rev(void) +{ + return get_cpu_rev(); +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif + +#if defined(CONFIG_FEC_MXC) +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + int i; + struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; + struct fuse_bank *bank = &iim->bank[1]; + struct fuse_bank1_regs *fuse = + (struct fuse_bank1_regs *)bank->fuse_regs; + + for (i = 0; i < 6; i++) + mac[i] = readl(&fuse->mac_addr[i]) & 0xff; +} +#endif + +#ifdef CONFIG_MX53 +void boot_mode_apply(unsigned cfg_val) +{ + writel(cfg_val, &((struct srtc_regs *)SRTC_BASE_ADDR)->lpgr); +} +/* + * cfg_val will be used for + * Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] + * + * If bit 28 of LPGR is set upon watchdog reset, + * bits[25:0] of LPGR will move to SBMR. + */ +const struct boot_mode soc_boot_modes[] = { + {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, + /* usb or serial download */ + {"usb", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x13)}, + {"sata", MAKE_CFGVAL(0x28, 0x00, 0x00, 0x12)}, + {"escpi1:0", MAKE_CFGVAL(0x38, 0x20, 0x00, 0x12)}, + {"escpi1:1", MAKE_CFGVAL(0x38, 0x20, 0x04, 0x12)}, + {"escpi1:2", MAKE_CFGVAL(0x38, 0x20, 0x08, 0x12)}, + {"escpi1:3", MAKE_CFGVAL(0x38, 0x20, 0x0c, 0x12)}, + /* 4 bit bus width */ + {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x12)}, + {"esdhc2", MAKE_CFGVAL(0x40, 0x20, 0x08, 0x12)}, + {"esdhc3", MAKE_CFGVAL(0x40, 0x20, 0x10, 0x12)}, + {"esdhc4", MAKE_CFGVAL(0x40, 0x20, 0x18, 0x12)}, + {NULL, 0}, +}; +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/mx6/Kconfig new file mode 100644 index 0000000..2161a5e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/Kconfig
@@ -0,0 +1,45 @@ +if ARCH_MX6 + +config MX6 + bool + default y + +config MX6D + bool + +config MX6DL + bool + +config MX6Q + bool + +config MX6QDL + bool + +config MX6S + bool + +config MX6SL + bool + +config MX6SX + bool + +config MX6UL + bool + +choice + prompt "MX6 board select" + +config TARGET_SECOMX6 + bool "Support secomx6 boards" + select CPU_V7 + +endchoice + +config SYS_SOC + default "mx6" + +source "board/seco/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/Makefile b/u-boot-imx/arch/arm/cpu/armv7/mx6/Makefile new file mode 100644 index 0000000..96126a3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/Makefile
@@ -0,0 +1,16 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2011-2015 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := soc.o clock.o +obj-$(CONFIG_SPL_BUILD) += ddr.o +obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o +ifdef CONFIG_MX6UL +obj-$(CONFIG_CMD_BEE) += bee.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/bee.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/bee.c new file mode 100644 index 0000000..d40b584 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/bee.c
@@ -0,0 +1,463 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/mx6_bee.h> +#include <asm-generic/errno.h> +#include <asm/system.h> +#include <common.h> +#include <command.h> +#include <fuse.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if (defined(CONFIG_SYS_DCACHE_OFF) || defined(CONFIG_SYS_ICACHE_OFF)) +#error "Bee needs Cache Open" +#endif + +struct bee_parameters { + int key_method; + int mode; + u32 start1; + u32 size1; + u32 start2; + u32 size2; +}; + +#define SOFT_KEY 0 +#define SNVS_KEY 1 + +#define ECB_MODE 0 +#define CTR_MODE 1 + +#define AES_REGION0_ADDR 0x10000000 +#define AES_REGION1_ADDR 0x30000000 + +static struct bee_parameters para; +static int bee_inited; + +union key_soft { + u8 s_key[16]; + u32 b_key[4]; +}; + +union key_soft key_bad; + +/* software version */ +u8 hw_get_random_byte(void) +{ + static u32 lcg_state; + static u32 nb_soft = 9876543; +#define MAX_SOFT_RNG 1024 + static const u32 a = 1664525; + static const u32 c = 1013904223; + nb_soft = (nb_soft + 1) % MAX_SOFT_RNG; + lcg_state = (a * lcg_state + c); + return (u8) (lcg_state >> 24); +} + +/* + * Lock bee GPR0 bits + * Only reset can release these bits. + */ +static int bee_lock(void) +{ + int val; + + val = readl(BEE_BASE_ADDR + GPR0); + val |= (GPR0_CTRL_CLK_EN_LOCK | GPR0_CTRL_SFTRST_N_LOCK | + GPR0_CTRL_AES_MODE_LOCK | GPR0_SEC_LEVEL_LOCK | + GPR0_AES_KEY_SEL_LOCK | GPR0_BEE_ENABLE_LOCK); + writel(val, BEE_BASE_ADDR + GPR0); + + return 0; +} + +/* Only check bee enable lock is enough */ +static int bee_locked(void) +{ + int val; + + val = readl(BEE_BASE_ADDR + GPR0); + + return val & GPR0_BEE_ENABLE_LOCK ? 1 : 0; +} + +int bee_init(struct bee_parameters *p) +{ + int i; + union key_soft *key = &key_bad; + u32 value; + + if (bee_locked()) { + printf("BEE already enabled and locked.\n"); + return CMD_RET_FAILURE; + } + + /* CLKGATE, SFTRST */ + writel(GPR0_CTRL_CLK_EN | GPR0_CTRL_SFTRST_N, BEE_BASE_ADDR + GPR0); + /* OFFSET_ADDR0 */ + writel(p->start1 >> 16, BEE_BASE_ADDR + GPR1); + /* + * OFFSET_ADDR1 + * Default protect IRAM region, if what you want to protect + * bigger that 512M which is the max size that one AES region + * can protect, we need AES region 1 to cover. + */ + writel(p->start2 >> 16, BEE_BASE_ADDR + GPR2); + + if (p->key_method == SOFT_KEY) { + for (i = 0; i < 16; i++) + key->s_key[i] = hw_get_random_byte(); + /* AES 128 key from software */ + /* aes0_key0_w0 */ + writel(key->b_key[0], BEE_BASE_ADDR + GPR3); + /* aes0_key0_w1 */ + writel(key->b_key[1], BEE_BASE_ADDR + GPR4); + /* aes0_key0_w2 */ + writel(key->b_key[2], BEE_BASE_ADDR + GPR5); + /* aes0_key0_w3 */ + writel(key->b_key[3], BEE_BASE_ADDR + GPR6); + } + + if (p->mode == ECB_MODE) { + value = GPR0_CTRL_CLK_EN | GPR0_CTRL_SFTRST_N | + GPR0_SEC_LEVEL_3 | GPR0_AES_KEY_SEL_SNVS | + GPR0_BEE_ENABLE | GPR0_CTRL_AES_MODE_ECB; + if (p->key_method == SOFT_KEY) + value = GPR0_CTRL_CLK_EN | GPR0_CTRL_SFTRST_N | + GPR0_SEC_LEVEL_3 | GPR0_AES_KEY_SEL_SOFT | + GPR0_BEE_ENABLE | GPR0_CTRL_AES_MODE_ECB; + writel(value, BEE_BASE_ADDR + GPR0); + } else { + for (i = 0; i < 16; i++) + key->s_key[i] = hw_get_random_byte(); + /* aes_key1_w0 */ + writel(key->b_key[0], BEE_BASE_ADDR + GPR8); + /* aes_key1_w1 */ + writel(key->b_key[1], BEE_BASE_ADDR + GPR9); + /* aes_key1_w2 */ + writel(key->b_key[2], BEE_BASE_ADDR + GPR10); + /* aes_key1_w3 */ + writel(key->b_key[3], BEE_BASE_ADDR + GPR11); + + value = GPR0_CTRL_CLK_EN | GPR0_CTRL_SFTRST_N | + GPR0_SEC_LEVEL_3 | GPR0_AES_KEY_SEL_SNVS | + GPR0_BEE_ENABLE | GPR0_CTRL_AES_MODE_CTR; + if (p->key_method == SOFT_KEY) + value = GPR0_CTRL_CLK_EN | GPR0_CTRL_SFTRST_N | + GPR0_SEC_LEVEL_3 | GPR0_AES_KEY_SEL_SOFT | + GPR0_BEE_ENABLE | GPR0_CTRL_AES_MODE_CTR; + writel(value, BEE_BASE_ADDR + GPR0); + } + + bee_lock(); + + printf("BEE is settings as: %s mode, %s %d key\n", + (p->mode == ECB_MODE) ? "ECB" : "CTR", + (p->key_method == SOFT_KEY) ? "SOFT" : "SNVS HW", + (p->mode == ECB_MODE) ? 128 : 256); + + return CMD_RET_SUCCESS; +} + +int bee_test(struct bee_parameters *p, int region) +{ + u32 result = 0, range, address; + int i, val; + /* + * Test instruction running in AES Region: + * int test(void) + * { + * return 0x55aa55aa; + * } + * Assemble: + * 0xe59f0000: ldr r0, [pc] + * 0xe12fff1e: bx lr + * 0x55aa55aa: 0x55aa55aa + */ + u32 inst[3] = {0xe59f0000, 0xe12fff1e, 0x55aa55aa}; + + /* Cache enabled? */ + if ((get_cr() & (CR_I | CR_C)) != (CR_I | CR_C)) { + printf("Enable dcache and icache first!\n"); + return CMD_RET_FAILURE; + } + + printf("Test Region %d\nBegin Data test: Writing... ", region); + + range = (region == 0) ? p->size1 : p->size2; + address = (region == 0) ? AES_REGION0_ADDR : AES_REGION1_ADDR; + for (i = 0; i < range; i = i + 4) + writel(i, address + i); + + printf("Finshed Write!\n"); + + flush_dcache_range(address, address + range); + + printf("Reading... "); + for (i = 0; i < range; i = i + 4) { + val = readl(address + i); + if (val != i) + result++; + } + printf("Finshed Read!\n"); + + if (result > 0) + printf("BEE Data Test check Failed!\n"); + else + printf("BEE Data Test Check Passed!\n"); + + for (i = 0; i < ARRAY_SIZE(inst); i++) + writel(inst[i], address + (i * 4)); + + flush_dcache_range(address, address + sizeof(inst)); + + val = ((int (*)(void))address)(); + + printf("\nBee Instruction test, Program:\n" + "int test(void)\n" + "{\n" + " return 0x55aa55aa;\n" + "}\n" + "Assemble:\n" + "0xe59f0000: ldr r0, [pc]\n" + "0xe12fff1e: bx lr\n" + "0x55aa55aa: 0x55aa55aa\n" + "Runnint at 0x%x\n", address); + if (val == 0x55aa55aa) + printf("Bee Instruction Test Passed!\n"); + else + printf("Bee Instruction Test Failed!\n"); + + return CMD_RET_SUCCESS; +} + +static int region_valid(u32 start, u32 size) +{ + if ((start < PHYS_SDRAM) || (start >= (start + size - 1)) || + (start >= (PHYS_SDRAM + PHYS_SDRAM_SIZE - 1))) { + printf("Invalid start 0x%x, size 0x%x\n", start, size); + return -EINVAL; + } + + if (size > SZ_512M) { + printf("The region size exceeds SZ_512M\n"); + return -EINVAL; + } + + if ((start & 0xFFFF) && (size & 0xFFFF)) { + printf("start or size not 64KB aligned!\n"); + return -EINVAL; + } + + if ((start + size - 1) >= (gd->start_addr_sp - CONFIG_STACKSIZE)) { + printf("Overlap with uboot execution environment!\n" + "Decrease size or start\n"); + return -EINVAL; + } + + return 0; +} + +static int do_bee_init(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 start, size, val; + int ret; + struct bee_parameters *p = ¶ + +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) + enum dcache_option option = DCACHE_WRITETHROUGH; +#else + enum dcache_option option = DCACHE_WRITEBACK; +#endif + + if (argc > 5) + return CMD_RET_USAGE; + + if (fuse_read(0, 4, &val)) { + puts("Can not get fuse bank 0, word 4\n"); + } else { + if (val & (1 << 25)) { + puts("BEE disabed in fuse!\n"); + return CMD_RET_FAILURE; + } + } + + /* Cache enabled? */ + if ((get_cr() & (CR_I | CR_C)) != (CR_I | CR_C)) { + /* + * Here we need icache and dcache both enabled, because + * we may take the protected region for instruction and + * data usage. And icache and dcache both enabled are + * better for performance. + */ + printf("Please enable dcache and icache first!\n"); + return CMD_RET_FAILURE; + } + + p->key_method = SOFT_KEY; + p->mode = ECB_MODE; + p->start1 = PHYS_SDRAM; + p->size1 = SZ_512M; + p->start2 = IRAM_BASE_ADDR; + p->size2 = IRAM_SIZE; + + if (argc == 2) { + p->key_method = (int)simple_strtoul(argv[1], NULL, 16); + p->mode = ECB_MODE; + p->start1 = PHYS_SDRAM; + p->size1 = SZ_512M; + } else if (argc == 3) { + p->key_method = (int)simple_strtoul(argv[1], NULL, 16); + p->mode = (int)simple_strtoul(argv[2], NULL, 10); + p->start1 = PHYS_SDRAM; + p->size1 = SZ_512M; + } else if ((argc == 4) || (argc == 5)) { + p->key_method = (int)simple_strtoul(argv[1], NULL, 16); + p->mode = (int)simple_strtoul(argv[2], NULL, 10); + start = (u32)simple_strtoul(argv[3], NULL, 16); + /* Default size that AES Region0 can protected */ + size = SZ_512M; + if (argc == 5) + size = (u32)simple_strtoul(argv[4], NULL, 16); + p->start1 = start; + p->size1 = size; + } + + if ((p->key_method != SOFT_KEY) && (p->key_method != SNVS_KEY)) + return CMD_RET_USAGE; + + if ((p->mode != ECB_MODE) && (p->mode != CTR_MODE)) + return CMD_RET_USAGE; + + /* + * No need to check region valid for IRAM, since it is fixed. + * Only check DRAM region here. + */ + if (region_valid(p->start1, p->size1)) + return CMD_RET_FAILURE; + + ret = bee_init(p); + if (ret) + return CMD_RET_FAILURE; + + /* + * Set DCACHE OFF to AES REGION0 and AES REGION1 first + * to avoid possible unexcepted cache settings. + */ + mmu_set_region_dcache_behaviour(AES_REGION0_ADDR, SZ_1G, DCACHE_OFF); + + mmu_set_region_dcache_behaviour(AES_REGION0_ADDR, p->size1, option); + + mmu_set_region_dcache_behaviour(AES_REGION1_ADDR, p->size2, option); + + printf("Access Region 0x%x - 0x%x to protect 0x%x - 0x%x\n" + "Do not directly access 0x%x - 0x%x\n" + "Access Region 0x%x - 0x%x to protect 0x%x - 0x%x\n" + "Do not directly access 0x%x - 0x%x\n", + AES_REGION0_ADDR, AES_REGION0_ADDR + p->size1 - 1, + p->start1, p->start1 + p->size1 - 1, + p->start1, p->start1 + p->size1 - 1, + AES_REGION1_ADDR, AES_REGION1_ADDR + p->size2 - 1, + p->start2, p->start2 + p->size2 - 1, + p->start2, p->start2 + p->size2 - 1); + + bee_inited = 1; + + return CMD_RET_SUCCESS; +} + +static int do_bee_test(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int ret; + int region; + + if (bee_inited == 0) { + printf("Bee not initialized, run bee init first!\n"); + return CMD_RET_FAILURE; + } + if (argc > 2) + return CMD_RET_USAGE; + + region = 0; + if (argc == 2) + region = (int)simple_strtoul(argv[1], NULL, 16); + /* Only two regions are supported, 0 and 1 */ + if (region >= 2) + return CMD_RET_USAGE; + + ret = bee_test(¶, region); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static cmd_tbl_t cmd_bmp_sub[] = { + U_BOOT_CMD_MKENT(init, 5, 0, do_bee_init, "", ""), + U_BOOT_CMD_MKENT(test, 2, 0, do_bee_test, "", ""), +}; + +static int do_bee_ops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *c; + + c = find_cmd_tbl(argv[1], &cmd_bmp_sub[0], ARRAY_SIZE(cmd_bmp_sub)); + + /* Drop off the 'bee' command argument */ + argc--; + argv++; + + if (c) + return c->cmd(cmdtp, flag, argc, argv); + else + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + bee, CONFIG_SYS_MAXARGS, 1, do_bee_ops, + "BEE function test", + "init [key] [mode] [start] [size] - BEE block initial\n" + " key: 0 | 1, 0 means software key, 1 means SNVS random key\n" + " mode: 0 | 1, 0 means ECB mode, 1 means CTR mode\n" + " start: start address that you want to protect\n" + " size: The size of the area that you want to protect\n" + " start and end(start + size) addr both should be 64KB aligned.\n" + "\n" + " After initialization, the mapping:\n" + " 1. [0x10000000 - (0x10000000 + size - 1)] <--->\n" + " [start - (start + size - 1)]\n" + " Here [start - (start + size -1)] is fixed mapping to\n" + " [0x10000000 - (0x10000000 + size - 1)], whatever start is.\n" + " 2. [0x30000000 - (0x30000000 + IRAM_SIZE - 1)] <--->\n" + " [IRAM_BASE_ADDR - (IRAM_BASE_ADDR + IRAM_SIZE - 1)]\n" + "\n" + " Note: Here we only use AES region 0 to protect the DRAM\n" + " area that you specified, max size SZ_512M.\n" + " AES region 1 is used to protect IRAM area.\n" + " Example:\n" + " 1. bee init 1 1 0xa0000000 0x10000\n" + " Access 0x10000000 - 0x10010000 to protect 0xa0000000 - 0xa0010000\n" + " 2. bee init 1 1 0x80000000 0x20000\n" + " Access 0x10000000 - 0x10020000 to protect 0x80000000 - 0x80020000\n" + "\n" + " Default configuration if only `bee init` without any args:\n" + " 1. software key\n" + " 2. ECB mode\n" + " 3. Address protected:\n" + " Remapped Region0: PHYS_SDRAM - PHYS_SDRAM + SZ_512M\n" + " Remapped Region1: IRAM_BASE_ADDR - IRAM_BASE_ADDR + IRAM_SIZE\n" + " 4. Default Mapping for 6UL:\n" + " [0x10000000 - 0x2FFFFFFF] <-> [0x80000000 - 0x9FFFFFFF]\n" + " [0x30000000 - 0x3001FFFF] <-> [0x00900000 - 0x0091FFFF]\n" + "\n" + "bee test [region] - BEE function test\n" + " region: 0 | 1, 0 means region0, 1 means regions1\n" +); +
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/clock.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/clock.c new file mode 100644 index 0000000..1ef307a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/clock.c
@@ -0,0 +1,1301 @@ +/* + * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +enum pll_clocks { + PLL_SYS, /* System PLL */ + PLL_BUS, /* System Bus PLL*/ + PLL_USBOTG, /* OTG USB PLL */ + PLL_ENET, /* ENET PLL */ +}; + +struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + +#ifdef CONFIG_MXC_OCOTP +void enable_ocotp_clk(unsigned char enable) +{ + u32 reg; + + reg = __raw_readl(&imx_ccm->CCGR2); + if (enable) + reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK; + else + reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK; + __raw_writel(reg, &imx_ccm->CCGR2); +} +#endif + +#ifdef CONFIG_NAND_MXS +void setup_gpmi_io_clk(u32 cfg) +{ + /* Disable clocks per ERR007177 from MX6 errata */ + clrbits_le32(&imx_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); + +#if defined(CONFIG_MX6SX) + clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK); + + clrsetbits_le32(&imx_ccm->cs2cdr, + MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | + MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | + MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK, + cfg); + + setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK); +#else + + clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); + + clrsetbits_le32(&imx_ccm->cs2cdr, + MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | + MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, + cfg); + + setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); +#endif + setbits_le32(&imx_ccm->CCGR4, + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); +} +#endif + +void enable_usboh3_clk(unsigned char enable) +{ + u32 reg; + + reg = __raw_readl(&imx_ccm->CCGR6); + if (enable) + reg |= MXC_CCM_CCGR6_USBOH3_MASK; + else + reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK); + __raw_writel(reg, &imx_ccm->CCGR6); + +} + +#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX) +void enable_enet_clk(unsigned char enable) +{ +#ifdef CONFIG_MX6UL + u32 mask = MXC_CCM_CCGR3_ENET_CLK_ENABLE_MASK; + /* Set AHB clk, since enet clock is sourced from AHB and IPG */ + /* ROM has set AHB, just leave here empty */ + /* Enable enet system clock */ + if (enable) + setbits_le32(&imx_ccm->CCGR3, mask); + else + clrbits_le32(&imx_ccm->CCGR3, mask); +#else + u32 mask = MXC_CCM_CCGR1_ENET_CLK_ENABLE_MASK; + + if (enable) + setbits_le32(&imx_ccm->CCGR1, mask); + else + clrbits_le32(&imx_ccm->CCGR1, mask); +#endif +} +#endif + +#if defined(CONFIG_MXC_UART) && !defined(CONFIG_MX6UL) +void enable_uart_clk(unsigned char enable) +{ + u32 mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK; + + if (enable) + setbits_le32(&imx_ccm->CCGR5, mask); + else + clrbits_le32(&imx_ccm->CCGR5, mask); +} +#endif + +#ifdef CONFIG_SPI +/* spi_num can be from 0 - 4 */ +int enable_cspi_clock(unsigned char enable, unsigned spi_num) +{ + u32 mask; + + if (spi_num > 4) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK << (spi_num * 2); + if (enable) + setbits_le32(&imx_ccm->CCGR1, mask); + else + clrbits_le32(&imx_ccm->CCGR1, mask); + + return 0; +} +#endif + +#ifdef CONFIG_MMC +int enable_usdhc_clk(unsigned char enable, unsigned bus_num) +{ + u32 mask; + + if (bus_num > 3) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2); + if (enable) + setbits_le32(&imx_ccm->CCGR6, mask); + else + clrbits_le32(&imx_ccm->CCGR6, mask); + + return 0; +} +#endif + +#ifdef CONFIG_SYS_I2C_MXC +/* i2c_num can be from 0 - 2 */ +int enable_i2c_clk(unsigned char enable, unsigned i2c_num) +{ + u32 reg; + u32 mask; + +#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) + if (i2c_num > 3) + return -EINVAL; + if (i2c_num == 3) { + mask = MXC_CCM_CCGR6_I2C4_SERIAL_MASK; + reg = __raw_readl(&imx_ccm->CCGR6); + } else +#endif + { + if (i2c_num > 2) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK + << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1)); + reg = __raw_readl(&imx_ccm->CCGR2); + } + if (enable) + reg |= mask; + else + reg &= ~mask; + +#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) + if (i2c_num == 3) + __raw_writel(reg, &imx_ccm->CCGR6); + else +#endif + __raw_writel(reg, &imx_ccm->CCGR2); + + return 0; +} +#endif + +/* spi_num can be from 0 - SPI_MAX_NUM */ +int enable_spi_clk(unsigned char enable, unsigned spi_num) +{ + u32 reg; + u32 mask; + + if (spi_num > SPI_MAX_NUM) + return -EINVAL; + + mask = MXC_CCM_CCGR_CG_MASK << (spi_num << 1); + reg = __raw_readl(&imx_ccm->CCGR1); + if (enable) + reg |= mask; + else + reg &= ~mask; + __raw_writel(reg, &imx_ccm->CCGR1); + return 0; +} +static u32 decode_pll(enum pll_clocks pll, u32 infreq) +{ + u32 div; + + switch (pll) { + case PLL_SYS: + div = __raw_readl(&imx_ccm->analog_pll_sys); + div &= BM_ANADIG_PLL_SYS_DIV_SELECT; + + return (infreq * div) >> 1; + case PLL_BUS: + div = __raw_readl(&imx_ccm->analog_pll_528); + div &= BM_ANADIG_PLL_528_DIV_SELECT; + + return infreq * (20 + (div << 1)); + case PLL_USBOTG: + div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl); + div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT; + + return infreq * (20 + (div << 1)); + case PLL_ENET: + div = __raw_readl(&imx_ccm->analog_pll_enet); + div &= BM_ANADIG_PLL_ENET_DIV_SELECT; + + return 25000000 * (div + (div >> 1) + 1); + default: + return 0; + } + /* NOTREACHED */ +} +static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num) +{ + u32 div; + u64 freq; + + switch (pll) { + case PLL_BUS: +#if !defined(CONFIG_MX6UL) && !defined(CONFIG_MX6UL) + if (pfd_num == 3) { + /* No PFD3 on PPL2 */ + return 0; + } +#endif + div = __raw_readl(&imx_ccm->analog_pfd_528); + freq = (u64)decode_pll(PLL_BUS, MXC_HCLK); + break; + case PLL_USBOTG: + div = __raw_readl(&imx_ccm->analog_pfd_480); + freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK); + break; + default: + /* No PFD on other PLL */ + return 0; + } + + return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >> + ANATOP_PFD_FRAC_SHIFT(pfd_num)); +} + +static u32 get_mcu_main_clk(void) +{ + u32 reg, freq; + + reg = __raw_readl(&imx_ccm->cacrr); + reg &= MXC_CCM_CACRR_ARM_PODF_MASK; + reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET; + freq = decode_pll(PLL_SYS, MXC_HCLK); + + return freq / (reg + 1); +} + +u32 get_periph_clk(void) +{ + u32 reg, freq = 0; + u32 div; + + reg = __raw_readl(&imx_ccm->cbcdr); + if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { + div = (reg & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> + MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET; + reg = __raw_readl(&imx_ccm->cbcmr); + reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK; + reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET; + + switch (reg) { + case 0: + freq = decode_pll(PLL_USBOTG, MXC_HCLK); + break; + case 1: + case 2: + freq = MXC_HCLK; + break; + default: + break; + } + } else { + reg = __raw_readl(&imx_ccm->cbcmr); + reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK; + reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET; + + switch (reg) { + case 0: + freq = decode_pll(PLL_BUS, MXC_HCLK); + break; + case 1: + freq = mxc_get_pll_pfd(PLL_BUS, 2); + break; + case 2: + freq = mxc_get_pll_pfd(PLL_BUS, 0); + break; + case 3: + /* static / 2 divider */ + freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2; + break; + default: + break; + } + div = 0; + } + + return freq / (div + 1); +} + +static u32 get_ipg_clk(void) +{ + u32 reg, ipg_podf; + + reg = __raw_readl(&imx_ccm->cbcdr); + reg &= MXC_CCM_CBCDR_IPG_PODF_MASK; + ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET; + + return get_ahb_clk() / (ipg_podf + 1); +} + +static u32 get_ipg_per_clk(void) +{ + u32 reg, perclk_podf; + + reg = __raw_readl(&imx_ccm->cscmr1); +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \ + defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL)) + if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK) + return MXC_HCLK; /* OSC 24Mhz */ +#endif + perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK; + + return get_ipg_clk() / (perclk_podf + 1); +} + +static u32 get_uart_clk(void) +{ + u32 reg, uart_podf; + u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */ + reg = __raw_readl(&imx_ccm->cscdr1); +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \ + defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL)) + if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL) + freq = MXC_HCLK; +#endif + reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK; + uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; + + return freq / (uart_podf + 1); +} + +static u32 get_cspi_clk(void) +{ + u32 reg, cspi_podf; + + reg = __raw_readl(&imx_ccm->cscdr2); + cspi_podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK) + >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET; + +#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX) || \ + defined(CONFIG_MX6QP) || defined(CONFIG_MX6UL)) + if (reg & MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK) + return MXC_HCLK / (cspi_podf + 1); +#endif + + return decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1)); +} + +static u32 get_axi_clk(void) +{ + u32 root_freq, axi_podf; + u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); + + axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK; + axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET; + + if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) { + if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL) + root_freq = mxc_get_pll_pfd(PLL_BUS, 2); + else + root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1); + } else + root_freq = get_periph_clk(); + + return root_freq / (axi_podf + 1); +} + +static u32 get_emi_slow_clk(void) +{ + u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0; + + cscmr1 = __raw_readl(&imx_ccm->cscmr1); + emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK; + emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET; + emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK; + emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET; + + switch (emi_clk_sel) { + case 0: + root_freq = get_axi_clk(); + break; + case 1: + root_freq = decode_pll(PLL_USBOTG, MXC_HCLK); + break; + case 2: + root_freq = mxc_get_pll_pfd(PLL_BUS, 2); + break; + case 3: + root_freq = mxc_get_pll_pfd(PLL_BUS, 0); + break; + } + + return root_freq / (emi_slow_podf + 1); +} + +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6SX) +static u32 get_mmdc_ch0_clk(void) +{ + u32 cbcmr = __raw_readl(&imx_ccm->cbcmr); + u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); + u32 freq, mmdc_podf, per2_clk2_podf; + + mmdc_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) + >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET; + if (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK_SEL) { + per2_clk2_podf = (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK) + >> MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET; + if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL) + freq = MXC_HCLK; + else + freq = decode_pll(PLL_USBOTG, MXC_HCLK); + } else { + per2_clk2_podf = 0; + switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >> + MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) { + case 0: + freq = decode_pll(PLL_BUS, MXC_HCLK); + break; + case 1: + freq = mxc_get_pll_pfd(PLL_BUS, 2); + break; + case 2: + freq = mxc_get_pll_pfd(PLL_BUS, 0); + break; + case 3: + /* static / 2 divider */ + freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2; + break; + } + } + + + return freq / (mmdc_podf + 1) / (per2_clk2_podf + 1); +} +#elif defined(CONFIG_MX6SL) +static u32 get_mmdc_ch0_clk(void) +{ + u32 cbcmr = __raw_readl(&imx_ccm->cbcmr); + u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); + u32 freq, podf; + + podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) \ + >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET; + + switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >> + MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) { + case 0: + freq = decode_pll(PLL_BUS, MXC_HCLK); + break; + case 1: + freq = mxc_get_pll_pfd(PLL_BUS, 2); + break; + case 2: + freq = mxc_get_pll_pfd(PLL_BUS, 0); + break; + case 3: + /* static / 2 divider */ + freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2; + } + + return freq / (podf + 1); + +} +#else +static u32 get_mmdc_ch0_clk(void) +{ + u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); + u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >> + MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET; + + return get_periph_clk() / (mmdc_ch0_podf + 1); +} +#endif + +#ifdef CONFIG_MX6SX +void enable_lvds(uint32_t lcdif_base) +{ + u32 reg = 0; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* Turn on LDB DI0 clocks */ + reg = readl(&imx_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_LDB_DI0_MASK; + writel(reg, &imx_ccm->CCGR3); + + /* set LDB DI0 clk select to 011 PLL2 PFD3 200M*/ + reg = readl(&imx_ccm->cs2cdr); + reg &= ~MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK; + reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET); + writel(reg, &imx_ccm->cs2cdr); + + reg = readl(&imx_ccm->cscmr2); + reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; + writel(reg, &imx_ccm->cscmr2); + + /* set LDB DI0 clock for LCDIF PIX clock */ + reg = readl(&imx_ccm->cscdr2); + if (lcdif_base == LCDIF1_BASE_ADDR) { + reg &= ~MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK; + reg |= (0x3 << MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_OFFSET); + } else { + reg &= ~MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK; + reg |= (0x3 << MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_OFFSET); + } + writel(reg, &imx_ccm->cscdr2); + + reg = IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW + | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG + | IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT + | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; + writel(reg, &iomux->gpr[6]); + + reg = readl(&iomux->gpr[5]); + if (lcdif_base == LCDIF1_BASE_ADDR) + reg &= ~0x8; /* MUX LVDS to LCDIF1 */ + else + reg |= 0x8; /* MUX LVDS to LCDIF2 */ + writel(reg, &iomux->gpr[5]); +} + +void enable_lcdif_clock(uint32_t base_addr) +{ + u32 reg = 0; + + /* Set to pre-mux clock at default */ + reg = readl(&imx_ccm->cscdr2); + if (base_addr == LCDIF1_BASE_ADDR) + reg &= ~MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK; + else + reg &= ~MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK; + writel(reg, &imx_ccm->cscdr2); + + /* Enable the LCDIF pix clock, axi clock, disp axi clock */ + reg = readl(&imx_ccm->CCGR3); + if (base_addr == LCDIF1_BASE_ADDR) + reg |= (MXC_CCM_CCGR3_LCDIF1_PIX_MASK | MXC_CCM_CCGR3_DISP_AXI_MASK); + else + reg |= (MXC_CCM_CCGR3_LCDIF2_PIX_MASK | MXC_CCM_CCGR3_DISP_AXI_MASK); + writel(reg, &imx_ccm->CCGR3); + + reg = readl(&imx_ccm->CCGR2); + reg |= (MXC_CCM_CCGR2_LCD_MASK); + writel(reg, &imx_ccm->CCGR2); +} +#endif + +#ifdef CONFIG_MX6UL +void enable_lcdif_clock(uint32_t base_addr) +{ + u32 reg = 0; + + /* Set to pre-mux clock at default */ + reg = readl(&imx_ccm->cscdr2); + reg &= ~MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK; + writel(reg, &imx_ccm->cscdr2); + + /* Enable the LCDIF pix clock */ + reg = readl(&imx_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_LCDIF1_PIX_MASK; + writel(reg, &imx_ccm->CCGR3); + + reg = readl(&imx_ccm->CCGR2); + reg |= MXC_CCM_CCGR2_LCD_MASK; + writel(reg, &imx_ccm->CCGR2); +} +#endif + +#if defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) +static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom, + u32 test_div) +{ + u32 reg = 0; + ulong start; + + debug("pll5 div = %d, num = %d, denom = %d\n", + pll_div, pll_num, pll_denom); + + /* Power up PLL5 video */ + writel(BM_ANADIG_PLL_VIDEO_POWERDOWN | BM_ANADIG_PLL_VIDEO_BYPASS | + BM_ANADIG_PLL_VIDEO_DIV_SELECT | BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT, + &imx_ccm->analog_pll_video_clr); + + /* Set div, num and denom */ + switch (test_div) { + case 1: + writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | + BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x1), + &imx_ccm->analog_pll_video_set); + break; + case 2: + writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | + BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x0), + &imx_ccm->analog_pll_video_set); + break; + default: + writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | + BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(0x2), + &imx_ccm->analog_pll_video_set); + break; + } + + writel(BF_ANADIG_PLL_VIDEO_NUM_A(pll_num), + &imx_ccm->analog_pll_video_num); + + writel(BF_ANADIG_PLL_VIDEO_DENOM_B(pll_denom), + &imx_ccm->analog_pll_video_denom); + + /* Wait PLL5 lock */ + start = get_timer(0); /* Get current timestamp */ + + do { + reg = readl(&imx_ccm->analog_pll_video); + if (reg & BM_ANADIG_PLL_VIDEO_LOCK) { + /* Enable PLL out */ + writel(BM_ANADIG_PLL_VIDEO_ENABLE, + &imx_ccm->analog_pll_video_set); + return 0; + } + } while (get_timer(0) < (start + 10)); /* Wait 10ms */ + + printf("Lock PLL5 timeout\n"); + return 1; + +} + +void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq) +{ + u32 reg = 0; + u32 hck = MXC_HCLK/1000; + u32 min = hck * 27; + u32 max = hck * 54; + u32 temp, best = 0; + u32 i, j, pred = 1, postd = 1; + u32 pll_div, pll_num, pll_denom, post_div = 0; + + debug("mxs_set_lcdclk, freq = %d\n", freq); + + if (base_addr == LCDIF1_BASE_ADDR) { + reg = readl(&imx_ccm->cscdr2); + if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0) + return; /*Can't change clocks when clock not from pre-mux */ + } +#ifdef CONFIG_MX6SX + else { + reg = readl(&imx_ccm->cscdr2); + if ((reg & MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK) != 0) + return; /*Can't change clocks when clock not from pre-mux */ + } +#endif + + temp = (freq * 8 * 8); + if (temp < min) { + for (i = 1; i <= 2; i++) { + if ((temp * (1 << i)) > min) { + post_div = i; + freq = (freq * (1 << i)); + break; + } + } + + if (3 == i) { + printf("Fail to set rate to %dkhz", freq); + return; + } + } + + for (i = 1; i <= 8; i++) { + for (j = 1; j <= 8; j++) { + temp = freq * i * j; + if (temp > max || temp < min) + continue; + + if (best == 0 || temp < best) { + best = temp; + pred = i; + postd = j; + } + } + } + + if (best == 0) { + printf("Fail to set rate to %dkhz", freq); + return; + } + + debug("best %d, pred = %d, postd = %d\n", best, pred, postd); + + pll_div = best / hck; + pll_denom = 1000000; + pll_num = (best - hck * pll_div) * pll_denom / hck; + + if (base_addr == LCDIF1_BASE_ADDR) { + if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) + return; + + /* Select pre-lcd clock to PLL5 */ + reg = readl(&imx_ccm->cscdr2); + reg &= ~MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK; + reg |= (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET); + /* Set the pre divider */ + reg &= ~MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK; + reg |= ((pred - 1) << MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET); + writel(reg, &imx_ccm->cscdr2); + + /* Set the post divider */ + reg = readl(&imx_ccm->cbcmr); + reg &= ~MXC_CCM_CBCMR_LCDIF1_PODF_MASK; + reg |= ((postd - 1) << MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET); + writel(reg, &imx_ccm->cbcmr); + } +#ifdef CONFIG_MX6SX + else { + if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) + return; + + /* Select pre-lcd clock to PLL5 */ + reg = readl(&imx_ccm->cscdr2); + reg &= ~MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_MASK; + reg |= (0x2 << MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_OFFSET); + /* Set the pre divider */ + reg &= ~MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_MASK; + reg |= ((pred - 1) << MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_OFFSET); + writel(reg, &imx_ccm->cscdr2); + + /* Set the post divider */ + reg = readl(&imx_ccm->cscmr1); + reg &= ~MXC_CCM_CSCMR1_LCDIF2_PODF_MASK; + reg |= ((postd - 1) << MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET); + writel(reg, &imx_ccm->cscmr1); + } +#endif +} + +/* qspi_num can be from 0 - 1 */ +void enable_qspi_clk(int qspi_num) +{ + u32 reg = 0; + /* Enable QuadSPI clock */ + switch (qspi_num) { + case 0: + /* disable the clock gate */ + clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); + + /* set 50M : (50 = 396 / 2 / 4) */ + reg = readl(&imx_ccm->cscmr1); + reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK | + MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK); + reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) | + (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET)); + writel(reg, &imx_ccm->cscmr1); + + /* enable the clock gate */ + setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); + break; +#ifdef CONFIG_MX6SX + case 1: + /* + * disable the clock gate + * QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate, + * disable both of them. + */ + clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); + + /* set 50M : (50 = 396 / 2 / 4) */ + reg = readl(&imx_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | + MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | + MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK); + reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) | + MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3)); + writel(reg, &imx_ccm->cs2cdr); + + /*enable the clock gate*/ + setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK | + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); + break; +#endif + default: + break; + } +} + +void mxs_set_vadcclk(void) +{ + u32 reg = 0; + + reg = readl(&imx_ccm->cscmr2); + reg &= ~MXC_CCM_CSCMR2_VID_CLK_SEL_MASK; + reg |= 0x19 << MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET; + writel(reg, &imx_ccm->cscmr2); +} +#endif + +#ifdef CONFIG_FEC_MXC +int enable_fec_anatop_clock(int fec_id, enum enet_freq freq) +{ + u32 reg = 0; + s32 timeout = 100000; + + struct anatop_regs __iomem *anatop = + (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; + + if (freq < ENET_25MHZ || freq > ENET_125MHZ) + return -EINVAL; + + reg = readl(&anatop->pll_enet); + reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT; + + if (0 == fec_id) { + reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT; + reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq); + } else { + reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT; + reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(freq); + } + + if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) || + (!(reg & BM_ANADIG_PLL_ENET_LOCK))) { + reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN; + writel(reg, &anatop->pll_enet); + while (timeout--) { + if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK) + break; + } + if (timeout < 0) + return -ETIMEDOUT; + } + + /* Enable FEC clock */ + if (0 == fec_id) + reg |= BM_ANADIG_PLL_ENET_ENABLE; + else + reg |= BM_ANADIG_PLL_ENET2_ENABLE; + reg &= ~BM_ANADIG_PLL_ENET_BYPASS; +#ifdef CONFIG_FEC_MXC_25M_REF_CLK + reg |= BM_ANADIG_PLL_ENET_REF_25M_ENABLE; +#endif + writel(reg, &anatop->pll_enet); + +#if defined(CONFIG_MX6SX) + /* + * Set enet ahb clock to 200MHz + * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB + */ + reg = readl(&imx_ccm->chsccdr); + reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK + | MXC_CCM_CHSCCDR_ENET_PODF_MASK + | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK); + /* PLL2 PFD2 */ + reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET); + /* Div = 2*/ + reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET); + reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET); + writel(reg, &imx_ccm->chsccdr); + + /* Enable enet system clock */ + reg = readl(&imx_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_ENET_MASK; + writel(reg, &imx_ccm->CCGR3); +#endif + return 0; +} +#endif + +static u32 get_usdhc_clk(u32 port) +{ + u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0; + u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1); + u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1); + + switch (port) { + case 0: + usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >> + MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET; + clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL; + + break; + case 1: + usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >> + MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET; + clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL; + + break; +#ifndef CONFIG_MX6UL + case 2: + usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >> + MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET; + clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL; + + break; + case 3: + usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >> + MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET; + clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL; + + break; +#endif + default: + break; + } + + if (clk_sel) + root_freq = mxc_get_pll_pfd(PLL_BUS, 0); + else + root_freq = mxc_get_pll_pfd(PLL_BUS, 2); + + return root_freq / (usdhc_podf + 1); +} + +u32 imx_get_uartclk(void) +{ + return get_uart_clk(); +} + +u32 imx_get_fecclk(void) +{ + return mxc_get_clock(MXC_IPG_CLK); +} + +#ifndef CONFIG_MX6UL +static int enable_enet_pll(uint32_t en) +{ + struct mxc_ccm_reg *const imx_ccm + = (struct mxc_ccm_reg *) CCM_BASE_ADDR; + s32 timeout = 100000; + u32 reg = 0; + + /* Enable PLLs */ + reg = readl(&imx_ccm->analog_pll_enet); + reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN; + writel(reg, &imx_ccm->analog_pll_enet); + reg |= BM_ANADIG_PLL_SYS_ENABLE; + while (timeout--) { + if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK) + break; + } + if (timeout <= 0) + return -EIO; + reg &= ~BM_ANADIG_PLL_SYS_BYPASS; + writel(reg, &imx_ccm->analog_pll_enet); + reg |= en; + writel(reg, &imx_ccm->analog_pll_enet); + return 0; +} + +#ifndef CONFIG_MX6SX +static void ungate_sata_clock(void) +{ + struct mxc_ccm_reg *const imx_ccm = + (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* Enable SATA clock. */ + setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK); +} +#else +static void ungate_disp_axi_clock(void) +{ + struct mxc_ccm_reg *const imx_ccm = + (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* Enable display axi clock. */ + setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_DISP_AXI_MASK); +} +#endif + +static void ungate_pcie_clock(void) +{ + struct mxc_ccm_reg *const imx_ccm = + (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* Enable PCIe clock. */ + setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK); +} + +#ifndef CONFIG_MX6SX +int enable_sata_clock(void) +{ + ungate_sata_clock(); + return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA); +} + +void disable_sata_clock(void) +{ + struct mxc_ccm_reg *const imx_ccm = + (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + clrbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK); +} +#endif + +int enable_pcie_clock(void) +{ + struct anatop_regs *anatop_regs = + (struct anatop_regs *)ANATOP_BASE_ADDR; + struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 lvds1_clk_sel; + + /* PCIe reference clock sourced from AXI. */ + clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL); + + /* + * Here be dragons! + * + * The register ANATOP_MISC1 is not documented in the Freescale + * MX6RM. The register that is mapped in the ANATOP space and + * marked as ANATOP_MISC1 is actually documented in the PMU section + * of the datasheet as PMU_MISC1. + * + * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on + * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important + * for PCI express link that is clocked from the i.MX6. + */ +#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12) +#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10) +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa +#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb + + if (is_cpu_type(MXC_CPU_MX6SX)) + lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF; + else + lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF; + +#ifndef CONFIG_MX6SX + /* lvds_clk1 is sourced from sata ref on imx6q/dl/solo */ + clrsetbits_le32(&anatop_regs->ana_misc1, + ANADIG_ANA_MISC1_LVDSCLK1_IBEN | + ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK, + ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel); + + /* Party time! Ungate the clock to the PCIe. */ + ungate_sata_clock(); + ungate_pcie_clock(); + + return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA | + BM_ANADIG_PLL_ENET_ENABLE_PCIE); +#else + /* lvds_clk1 is sourced from pcie ref on imx6sx */ + clrsetbits_le32(&anatop_regs->ana_misc1, + ANADIG_ANA_MISC1_LVDSCLK1_IBEN | + ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK, + ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel); + + ungate_disp_axi_clock(); + ungate_pcie_clock(); + return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_PCIE); +#endif +} +#endif + +#ifdef CONFIG_SECURE_BOOT +void hab_caam_clock_enable(unsigned char enable) +{ + u32 reg; + + /* CG4 ~ CG6, CAAM clocks */ + reg = __raw_readl(&imx_ccm->CCGR0); + if (enable) + reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); + else + reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); + __raw_writel(reg, &imx_ccm->CCGR0); + + /* EMI slow clk */ + reg = __raw_readl(&imx_ccm->CCGR6); + if (enable) + reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; + else + reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK; + __raw_writel(reg, &imx_ccm->CCGR6); +} +#endif + +static void enable_pll3(void) +{ + struct anatop_regs __iomem *anatop = + (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; + + /* make sure pll3 is enabled */ + if ((readl(&anatop->usb1_pll_480_ctrl) & + BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) { + /* enable pll's power */ + writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER, + &anatop->usb1_pll_480_ctrl_set); + writel(0x80, &anatop->ana_misc2_clr); + /* wait for pll lock */ + while ((readl(&anatop->usb1_pll_480_ctrl) & + BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) + ; + /* disable bypass */ + writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS, + &anatop->usb1_pll_480_ctrl_clr); + /* enable pll output */ + writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE, + &anatop->usb1_pll_480_ctrl_set); + } +} + +void enable_thermal_clk(void) +{ + enable_pll3(); +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_mcu_main_clk(); + case MXC_PER_CLK: + return get_periph_clk(); + case MXC_AHB_CLK: + return get_ahb_clk(); + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_IPG_PERCLK: + case MXC_I2C_CLK: + return get_ipg_per_clk(); + case MXC_UART_CLK: + return get_uart_clk(); + case MXC_CSPI_CLK: + return get_cspi_clk(); + case MXC_AXI_CLK: + return get_axi_clk(); + case MXC_EMI_SLOW_CLK: + return get_emi_slow_clk(); + case MXC_DDR_CLK: + return get_mmdc_ch0_clk(); + case MXC_ESDHC_CLK: + return get_usdhc_clk(0); + case MXC_ESDHC2_CLK: + return get_usdhc_clk(1); + case MXC_ESDHC3_CLK: + return get_usdhc_clk(2); + case MXC_ESDHC4_CLK: + return get_usdhc_clk(3); + case MXC_SATA_CLK: + return get_ahb_clk(); + default: + printf("Unsupported MXC CLK: %d\n", clk); + break; + } + + return 0; +} + +/* + * Dump some core clockes. + */ +int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 freq; + freq = decode_pll(PLL_SYS, MXC_HCLK); + printf("PLL_SYS %8d MHz\n", freq / 1000000); + freq = decode_pll(PLL_BUS, MXC_HCLK); + printf("PLL_BUS %8d MHz\n", freq / 1000000); + freq = decode_pll(PLL_USBOTG, MXC_HCLK); + printf("PLL_OTG %8d MHz\n", freq / 1000000); + freq = decode_pll(PLL_ENET, MXC_HCLK); + printf("PLL_NET %8d MHz\n", freq / 1000000); + + printf("\n"); + printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); + printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); +#ifdef CONFIG_MXC_SPI + printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); +#endif + printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); + printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000); + printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); + printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); + printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); + printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); + printf("USDHC4 %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000); + printf("EMI SLOW %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000); + printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); + + return 0; +} + +#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX6UL) +#ifdef CONFIG_MX6QP +static void pre_misc_setting(void) +{ + /* Bypass IPU1 QoS generator */ + writel(0x00000002, 0x00bb048c); + /* Bypass IPU2 QoS generator */ + writel(0x00000002, 0x00bb050c); + /* Bandwidth THR for of PRE0 */ + writel(0x00000200, 0x00bb0690); + /* Bandwidth THR for of PRE1 */ + writel(0x00000200, 0x00bb0710); + /* Bandwidth THR for of PRE2 */ + writel(0x00000200, 0x00bb0790); + /* Bandwidth THR for of PRE3 */ + writel(0x00000200, 0x00bb0810); + /* Saturation THR for of PRE0 */ + writel(0x00000010, 0x00bb0694); + /* Saturation THR for of PRE1 */ + writel(0x00000010, 0x00bb0714); + /* Saturation THR for of PRE2 */ + writel(0x00000010, 0x00bb0794); + /* Saturation THR for of PRE */ + writel(0x00000010, 0x00bb0814); +} +#endif + +void enable_ipu_clock(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + int reg; + reg = readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK; + writel(reg, &mxc_ccm->CCGR3); + +#ifdef CONFIG_MX6QP + reg = readl(&mxc_ccm->CCGR6); + reg |= MXC_CCM_CCGR6_PRG_CLK0_MASK; + writel(reg, &mxc_ccm->CCGR6); + + reg = readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_IPU2_IPU_MASK; + writel(reg, &mxc_ccm->CCGR3); + + /* + * Since CONFIG_VIDEO_IPUV3 is always set in mx6sabre_common.h and + * this misc setting is a must for mx6qp, this position is ok + * to do such settings. + */ + pre_misc_setting(); +#endif +} + +#endif +/***************************************************/ + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks, + "display clocks", + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/ddr.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/ddr.c new file mode 100644 index 0000000..fef2231 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/ddr.c
@@ -0,0 +1,559 @@ +/* + * Copyright (C) 2014 Gateworks Corporation + * Author: Tim Harvey <tharvey@gateworks.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/types.h> +#include <asm/arch/mx6-ddr.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/types.h> + +#if defined(CONFIG_MX6SX) +/* Configure MX6SX mmdc iomux */ +void mx6sx_dram_iocfg(unsigned width, + const struct mx6sx_iomux_ddr_regs *ddr, + const struct mx6sx_iomux_grp_regs *grp) +{ + struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux; + struct mx6sx_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE; + + /* DDR IO TYPE */ + writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type); + writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke); + + /* CLOCK */ + writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0); + + /* ADDRESS */ + writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas); + writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras); + writel(grp->grp_addds, &mx6_grp_iomux->grp_addds); + + /* Control */ + writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset); + writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2); + writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0); + writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1); + writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0); + writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1); + writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds); + + /* Data Strobes */ + writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl); + writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0); + writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1); + if (width >= 32) { + writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2); + writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3); + } + + /* Data */ + writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode); + writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds); + writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds); + if (width >= 32) { + writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds); + writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds); + } + writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0); + writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1); + if (width >= 32) { + writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2); + writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3); + } +} +#endif + +#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) +/* Configure MX6DQ mmdc iomux */ +void mx6dq_dram_iocfg(unsigned width, + const struct mx6dq_iomux_ddr_regs *ddr, + const struct mx6dq_iomux_grp_regs *grp) +{ + volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux; + volatile struct mx6dq_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6dq_iomux_ddr_regs *)MX6DQ_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6dq_iomux_grp_regs *)MX6DQ_IOM_GRP_BASE; + + /* DDR IO Type */ + mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; + mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; + + /* Clock */ + mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; + mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; + + /* Address */ + mx6_ddr_iomux->dram_cas = ddr->dram_cas; + mx6_ddr_iomux->dram_ras = ddr->dram_ras; + mx6_grp_iomux->grp_addds = grp->grp_addds; + + /* Control */ + mx6_ddr_iomux->dram_reset = ddr->dram_reset; + mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; + mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; + mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; + mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; + mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; + mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; + + /* Data Strobes */ + mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; + mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; + mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; + if (width >= 32) { + mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; + mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; + mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; + mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; + mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; + } + + /* Data */ + mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; + mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; + mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; + if (width >= 32) { + mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; + mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; + } + if (width >= 64) { + mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; + mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; + mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; + mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; + } + mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; + mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; + if (width >= 32) { + mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; + mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; + mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; + mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; + mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; + } +} +#endif + +#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6DL) || defined(CONFIG_MX6S) +/* Configure MX6SDL mmdc iomux */ +void mx6sdl_dram_iocfg(unsigned width, + const struct mx6sdl_iomux_ddr_regs *ddr, + const struct mx6sdl_iomux_grp_regs *grp) +{ + volatile struct mx6sdl_iomux_ddr_regs *mx6_ddr_iomux; + volatile struct mx6sdl_iomux_grp_regs *mx6_grp_iomux; + + mx6_ddr_iomux = (struct mx6sdl_iomux_ddr_regs *)MX6SDL_IOM_DDR_BASE; + mx6_grp_iomux = (struct mx6sdl_iomux_grp_regs *)MX6SDL_IOM_GRP_BASE; + + /* DDR IO Type */ + mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; + mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; + + /* Clock */ + mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; + mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; + + /* Address */ + mx6_ddr_iomux->dram_cas = ddr->dram_cas; + mx6_ddr_iomux->dram_ras = ddr->dram_ras; + mx6_grp_iomux->grp_addds = grp->grp_addds; + + /* Control */ + mx6_ddr_iomux->dram_reset = ddr->dram_reset; + mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; + mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; + mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; + mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; + mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; + mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; + + /* Data Strobes */ + mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; + mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; + mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; + if (width >= 32) { + mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; + mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; + mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; + mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; + mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; + } + + /* Data */ + mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; + mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; + mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; + if (width >= 32) { + mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; + mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; + } + if (width >= 64) { + mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; + mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; + mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; + mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; + } + mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; + mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; + if (width >= 32) { + mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; + mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; + } + if (width >= 64) { + mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; + mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; + mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; + mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; + } +} +#endif + +/* + * Configure mx6 mmdc registers based on: + * - board-specific memory configuration + * - board-specific calibration data + * - ddr3 chip details + * + * The various calculations here are derived from the Freescale + * i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate MMDC + * configuration registers based on memory system and memory chip parameters. + * + * The defaults here are those which were specified in the spreadsheet. + * For details on each register, refer to the IMX6DQRM and/or IMX6SDLRM + * section titled MMDC initialization + */ +#define MR(val, ba, cmd, cs1) \ + ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) +#ifdef CONFIG_MX6SX +#define MMDC1(entry, value) do {} while (0) +#else +#define MMDC1(entry, value) do { mmdc1->entry = value; } while (0) +#endif +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, + const struct mx6_mmdc_calibration *calib, + const struct mx6_ddr3_cfg *ddr3_cfg) +{ + volatile struct mmdc_p_regs *mmdc0; +#ifndef CONFIG_MX6SX + volatile struct mmdc_p_regs *mmdc1; +#endif + u32 val; + u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd; + u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl; + u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */ + u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr; + u16 cs0_end; + u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */ + u8 coladdr; + int clkper; /* clock period in picoseconds */ + int clock; /* clock freq in mHz */ + int cs; + + mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; +#ifndef CONFIG_MX6SX + mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; +#endif + + /* MX6D/MX6Q: 1066 MHz memory clock, clkper = 1.894ns = 1894ps */ + if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) { + clock = 528; + tcwl = 4; + } + /* MX6S/MX6DL: 800 MHz memory clock, clkper = 2.5ns = 2500ps */ + else { + clock = 400; + tcwl = 3; + } + clkper = (1000 * 1000) / clock; /* pico seconds */ + todtlon = tcwl; + taxpd = tcwl; + tanpd = tcwl; + + switch (ddr3_cfg->density) { + case 1: /* 1Gb per chip */ + trfc = DIV_ROUND_UP(110000, clkper) - 1; + txs = DIV_ROUND_UP(120000, clkper) - 1; + break; + case 2: /* 2Gb per chip */ + trfc = DIV_ROUND_UP(160000, clkper) - 1; + txs = DIV_ROUND_UP(170000, clkper) - 1; + break; + case 4: /* 4Gb per chip */ + trfc = DIV_ROUND_UP(260000, clkper) - 1; + txs = DIV_ROUND_UP(270000, clkper) - 1; + break; + case 8: /* 8Gb per chip */ + trfc = DIV_ROUND_UP(350000, clkper) - 1; + txs = DIV_ROUND_UP(360000, clkper) - 1; + break; + default: + /* invalid density */ + puts("invalid chip density\n"); + hang(); + break; + } + txpr = txs; + + switch (ddr3_cfg->mem_speed) { + case 800: + txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(40000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(50000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } + break; + case 1066: + txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 5625), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(37500, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 7500), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(50000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; + } + break; + case 1333: + txp = DIV_ROUND_UP(max(3 * clkper, 6000), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 5625), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(30000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 6000), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(45000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 7500), clkper) - 1; + } + break; + case 1600: + txp = DIV_ROUND_UP(max(3 * clkper, 6000), clkper) - 1; + tcke = DIV_ROUND_UP(max(3 * clkper, 5000), clkper) - 1; + if (ddr3_cfg->pagesz == 1) { + tfaw = DIV_ROUND_UP(30000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 6000), clkper) - 1; + } else { + tfaw = DIV_ROUND_UP(40000, clkper) - 1; + trrd = DIV_ROUND_UP(max(4 * clkper, 7500), clkper) - 1; + } + break; + default: + puts("invalid memory speed\n"); + hang(); + break; + } + txpdll = DIV_ROUND_UP(max(10 * clkper, 24000), clkper) - 1; + tcksre = DIV_ROUND_UP(max(5 * clkper, 10000), clkper); + taonpd = DIV_ROUND_UP(2000, clkper) - 1; + tcksrx = tcksre; + taofpd = taonpd; + twr = DIV_ROUND_UP(15000, clkper) - 1; + tmrd = DIV_ROUND_UP(max(12 * clkper, 15000), clkper) - 1; + trc = DIV_ROUND_UP(ddr3_cfg->trcmin, clkper / 10) - 1; + tras = DIV_ROUND_UP(ddr3_cfg->trasmin, clkper / 10) - 1; + tcl = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 3; + trp = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 1; + twtr = ROUND(max(4 * clkper, 7500) / clkper, 1) - 1; + trcd = trp; + trtp = twtr; + cs0_end = 4 * sysinfo->cs_density - 1; + + debug("density:%d Gb (%d Gb per chip)\n", + sysinfo->cs_density, ddr3_cfg->density); + debug("clock: %dMHz (%d ps)\n", clock, clkper); + debug("memspd:%d\n", ddr3_cfg->mem_speed); + debug("tcke=%d\n", tcke); + debug("tcksrx=%d\n", tcksrx); + debug("tcksre=%d\n", tcksre); + debug("taofpd=%d\n", taofpd); + debug("taonpd=%d\n", taonpd); + debug("todtlon=%d\n", todtlon); + debug("tanpd=%d\n", tanpd); + debug("taxpd=%d\n", taxpd); + debug("trfc=%d\n", trfc); + debug("txs=%d\n", txs); + debug("txp=%d\n", txp); + debug("txpdll=%d\n", txpdll); + debug("tfaw=%d\n", tfaw); + debug("tcl=%d\n", tcl); + debug("trcd=%d\n", trcd); + debug("trp=%d\n", trp); + debug("trc=%d\n", trc); + debug("tras=%d\n", tras); + debug("twr=%d\n", twr); + debug("tmrd=%d\n", tmrd); + debug("tcwl=%d\n", tcwl); + debug("tdllk=%d\n", tdllk); + debug("trtp=%d\n", trtp); + debug("twtr=%d\n", twtr); + debug("trrd=%d\n", trrd); + debug("txpr=%d\n", txpr); + debug("cs0_end=%d\n", cs0_end); + debug("ncs=%d\n", sysinfo->ncs); + debug("Rtt_wr=%d\n", sysinfo->rtt_wr); + debug("Rtt_nom=%d\n", sysinfo->rtt_nom); + debug("SRT=%d\n", ddr3_cfg->SRT); + debug("tcl=%d\n", tcl); + debug("twr=%d\n", twr); + + /* + * board-specific configuration: + * These values are determined empirically and vary per board layout + * see: + * appnote, ddr3 spreadsheet + */ + mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0; + mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1; + mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0; + mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; + mmdc0->mprddlctl = calib->p0_mprddlctl; + mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; + if (sysinfo->dsize > 1) { + MMDC1(mpwldectrl0, calib->p1_mpwldectrl0); + MMDC1(mpwldectrl1, calib->p1_mpwldectrl1); + MMDC1(mpdgctrl0, calib->p1_mpdgctrl0); + MMDC1(mpdgctrl1, calib->p1_mpdgctrl1); + MMDC1(mprddlctl, calib->p1_mprddlctl); + MMDC1(mpwrdlctl, calib->p1_mpwrdlctl); + } + + /* Read data DQ Byte0-3 delay */ + mmdc0->mprddqby0dl = 0x33333333; + mmdc0->mprddqby1dl = 0x33333333; + if (sysinfo->dsize > 0) { + mmdc0->mprddqby2dl = 0x33333333; + mmdc0->mprddqby3dl = 0x33333333; + } + + if (sysinfo->dsize > 1) { + MMDC1(mprddqby0dl, 0x33333333); + MMDC1(mprddqby1dl, 0x33333333); + MMDC1(mprddqby2dl, 0x33333333); + MMDC1(mprddqby3dl, 0x33333333); + } + + /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ + val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; + mmdc0->mpodtctrl = val; + if (sysinfo->dsize > 1) + MMDC1(mpodtctrl, val); + + /* complete calibration */ + val = (1 << 11); /* Force measurement on delay-lines */ + mmdc0->mpmur0 = val; + if (sysinfo->dsize > 1) + MMDC1(mpmur0, val); + + /* Step 1: configuration request */ + mmdc0->mdscr = (u32)(1 << 15); /* config request */ + + /* Step 2: Timing configuration */ + mmdc0->mdcfg0 = (trfc << 24) | (txs << 16) | (txp << 13) | + (txpdll << 9) | (tfaw << 4) | tcl; + mmdc0->mdcfg1 = (trcd << 29) | (trp << 26) | (trc << 21) | + (tras << 16) | (1 << 15) /* trpa */ | + (twr << 9) | (tmrd << 5) | tcwl; + mmdc0->mdcfg2 = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd; + mmdc0->mdotc = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | + (taxpd << 16) | (todtlon << 12) | (todt_idle_off << 4); + mmdc0->mdasp = cs0_end; /* CS addressing */ + + /* Step 3: Configure DDR type */ + mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | + (sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | + (sysinfo->ralat << 6); + + /* Step 4: Configure delay while leaving reset */ + mmdc0->mdor = (txpr << 16) | (sysinfo->sde_to_rst << 8) | + (sysinfo->rst_to_cke << 0); + + /* Step 5: Configure DDR physical parameters (density and burst len) */ + coladdr = ddr3_cfg->coladdr; + if (ddr3_cfg->coladdr == 8) /* 8-bit COL is 0x3 */ + coladdr += 4; + else if (ddr3_cfg->coladdr == 12) /* 12-bit COL is 0x4 */ + coladdr += 1; + mmdc0->mdctl = (ddr3_cfg->rowaddr - 11) << 24 | /* ROW */ + (coladdr - 9) << 20 | /* COL */ + (1 << 19) | /* Burst Length = 8 for DDR3 */ + (sysinfo->dsize << 16); /* DDR data bus size */ + + /* Step 6: Perform ZQ calibration */ + val = 0xa1390001; /* one-time HW ZQ calib */ + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + MMDC1(mpzqhwctrl, val); + + /* Step 7: Enable MMDC with desired chip select */ + mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */ + ((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ + + /* Step 8: Write Mode Registers to Init DDR3 devices */ + for (cs = 0; cs < sysinfo->ncs; cs++) { + /* MR2 */ + val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | + ((tcwl - 3) & 3) << 3; + mmdc0->mdscr = MR(val, 2, 3, cs); + /* MR3 */ + mmdc0->mdscr = MR(0, 3, 3, cs); + /* MR1 */ + val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 | + ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6; + mmdc0->mdscr = MR(val, 1, 3, cs); + /* MR0 */ + val = ((tcl - 1) << 4) | /* CAS */ + (1 << 8) | /* DLL Reset */ + ((twr - 3) << 9); /* Write Recovery */ + mmdc0->mdscr = MR(val, 0, 3, cs); + /* ZQ calibration */ + val = (1 << 10); + mmdc0->mdscr = MR(val, 0, 4, cs); + } + + /* Step 10: Power down control and self-refresh */ + mmdc0->mdpdc = (tcke & 0x7) << 16 | + 5 << 12 | /* PWDT_1: 256 cycles */ + 5 << 8 | /* PWDT_0: 256 cycles */ + 1 << 7 | /* SLOW_PD */ + 1 << 6 | /* BOTH_CS_PD */ + (tcksrx & 0x7) << 3 | + (tcksre & 0x7); + mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ + + /* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ + val = 0xa1390003; + mmdc0->mpzqhwctrl = val; + if (sysinfo->dsize > 1) + MMDC1(mpzqhwctrl, val); + + /* Step 12: Configure and activate periodic refresh */ + mmdc0->mdref = (1 << 14) | /* REF_SEL: Periodic refresh cycle: 32kHz */ + (7 << 11); /* REFR: Refresh Rate - 8 refreshes */ + + /* Step 13: Deassert config request - init complete */ + mmdc0->mdscr = 0x00000000; + + /* wait for auto-ZQ calibration to complete */ + mdelay(1); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/hab.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/hab.c new file mode 100644 index 0000000..d6ca139 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/hab.c
@@ -0,0 +1,336 @@ +/* + * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/arch/hab.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +/* -------- start of HAB API updates ------------*/ + +#define hab_rvt_report_event_p \ +( \ + ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) : \ + ((is_cpu_type(MXC_CPU_MX6DL) || \ + is_cpu_type(MXC_CPU_MX6SOLO)) && \ + (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) : \ + ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT) \ +) + +#define hab_rvt_report_status_p \ +( \ + ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\ + ((is_cpu_type(MXC_CPU_MX6DL) || \ + is_cpu_type(MXC_CPU_MX6SOLO)) && \ + (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\ + ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS) \ +) + +#define hab_rvt_authenticate_image_p \ +( \ + ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \ + ((is_cpu_type(MXC_CPU_MX6DL) || \ + is_cpu_type(MXC_CPU_MX6SOLO)) && \ + (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \ + ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE) \ +) + +#define hab_rvt_entry_p \ +( \ + ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) : \ + ((is_cpu_type(MXC_CPU_MX6DL) || \ + is_cpu_type(MXC_CPU_MX6SOLO)) && \ + (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) : \ + ((hab_rvt_entry_t *)HAB_RVT_ENTRY) \ +) + +#define hab_rvt_exit_p \ +( \ + ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_1_5)) ? \ + ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) : \ + ((is_cpu_type(MXC_CPU_MX6DL) || \ + is_cpu_type(MXC_CPU_MX6SOLO)) && \ + (soc_rev() >= CHIP_REV_1_2)) ? \ + ((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) : \ + ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ +) + +#define IVT_SIZE 0x20 +#define ALIGN_SIZE 0x1000 +#define CSF_PAD_SIZE 0x2000 +#define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 +#define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0 +#define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18 + +/* + * +------------+ 0x0 (DDR_UIMAGE_START) - + * | Header | | + * +------------+ 0x40 | + * | | | + * | | | + * | | | + * | | | + * | Image Data | | + * . | | + * . | > Stuff to be authenticated ----+ + * . | | | + * | | | | + * | | | | + * +------------+ | | + * | | | | + * | Fill Data | | | + * | | | | + * +------------+ Align to ALIGN_SIZE | | + * | IVT | | | + * +------------+ + IVT_SIZE - | + * | | | + * | CSF DATA | <---------------------------------------------------------+ + * | | + * +------------+ + * | | + * | Fill Data | + * | | + * +------------+ + CSF_PAD_SIZE + */ + +bool is_hab_enabled(void) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + uint32_t reg = readl(&fuse->cfg5); + + return (reg & 0x2) == 0x2; +} + +void display_event(uint8_t *event_data, size_t bytes) +{ + uint32_t i; + + if (!(event_data && bytes > 0)) + return; + + for (i = 0; i < bytes; i++) { + if (i == 0) + printf("\t0x%02x", event_data[i]); + else if ((i % 8) == 0) + printf("\n\t0x%02x", event_data[i]); + else + printf(" 0x%02x", event_data[i]); + } +} + +int get_hab_status(void) +{ + uint32_t index = 0; /* Loop index */ + uint8_t event_data[128]; /* Event data buffer */ + size_t bytes = sizeof(event_data); /* Event size in bytes */ + enum hab_config config = 0; + enum hab_state state = 0; + hab_rvt_report_event_t *hab_rvt_report_event; + hab_rvt_report_status_t *hab_rvt_report_status; + + hab_rvt_report_event = hab_rvt_report_event_p; + hab_rvt_report_status = hab_rvt_report_status_p; + + if (is_hab_enabled()) + puts("\nSecure boot enabled\n"); + else + puts("\nSecure boot disabled\n"); + + /* Check HAB status */ + if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) { + printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", + config, state); + + /* Display HAB Error events */ + while (hab_rvt_report_event(HAB_FAILURE, index, event_data, + &bytes) == HAB_SUCCESS) { + puts("\n"); + printf("--------- HAB Event %d -----------------\n", + index + 1); + puts("event data:\n"); + display_event(event_data, bytes); + puts("\n"); + bytes = sizeof(event_data); + index++; + } + } + /* Display message if no HAB events are found */ + else { + printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", + config, state); + puts("No HAB Events Found!\n\n"); + } + return 0; +} + +uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) +{ + uint32_t load_addr = 0; + size_t bytes; + ptrdiff_t ivt_offset = 0; + int result = 0; + ulong start; + hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; + hab_rvt_entry_t *hab_rvt_entry; + hab_rvt_exit_t *hab_rvt_exit; + + hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; + hab_rvt_entry = hab_rvt_entry_p; + hab_rvt_exit = hab_rvt_exit_p; + + if (is_hab_enabled()) { + printf("\nAuthenticate image from DDR location 0x%x...\n", + ddr_start); + + hab_caam_clock_enable(1); + + if (hab_rvt_entry() == HAB_SUCCESS) { + /* If not already aligned, Align to ALIGN_SIZE */ + ivt_offset = (image_size + ALIGN_SIZE - 1) & + ~(ALIGN_SIZE - 1); + + start = ddr_start; + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; +#ifdef DEBUG + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", + ivt_offset, ddr_start + ivt_offset); + puts("Dumping IVT\n"); + print_buffer(ddr_start + ivt_offset, + (void *)(ddr_start + ivt_offset), + 4, 0x8, 0); + + puts("Dumping CSF Header\n"); + print_buffer(ddr_start + ivt_offset+IVT_SIZE, + (void *)(ddr_start + ivt_offset+IVT_SIZE), + 4, 0x10, 0); + + get_hab_status(); + + puts("\nCalling authenticate_image in ROM\n"); + printf("\tivt_offset = 0x%x\n", ivt_offset); + printf("\tstart = 0x%08lx\n", start); + printf("\tbytes = 0x%x\n", bytes); +#endif + /* + * If the MMU is enabled, we have to notify the ROM + * code, or it won't flush the caches when needed. + * This is done, by setting the "pu_irom_mmu_enabled" + * word to 1. You can find its address by looking in + * the ROM map. This is critical for + * authenticate_image(). If MMU is enabled, without + * setting this bit, authentication will fail and may + * crash. + */ + /* Check MMU enabled */ + if (get_cr() & CR_M) { + if (is_cpu_type(MXC_CPU_MX6Q) || + is_cpu_type(MXC_CPU_MX6D)) { + /* + * This won't work on Rev 1.0.0 of + * i.MX6Q/D, since their ROM doesn't + * do cache flushes. don't think any + * exist, so we ignore them. + */ + if (!is_mx6dqp()) + writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); + } else if (is_cpu_type(MXC_CPU_MX6DL) || + is_cpu_type(MXC_CPU_MX6SOLO)) { + writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); + } else if (is_cpu_type(MXC_CPU_MX6SL)) { + writel(1, MX6SL_PU_IROM_MMU_EN_VAR); + } + } + + load_addr = (uint32_t)hab_rvt_authenticate_image( + HAB_CID_UBOOT, + ivt_offset, (void **)&start, + (size_t *)&bytes, NULL); + if (hab_rvt_exit() != HAB_SUCCESS) { + puts("hab exit function fail\n"); + load_addr = 0; + } + } else { + puts("hab entry function fail\n"); + } + + hab_caam_clock_enable(0); + + get_hab_status(); + } else { + puts("hab fuse not enabled\n"); + } + + if ((!is_hab_enabled()) || (load_addr != 0)) + result = 1; + + return result; +} + +int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if ((argc != 1)) { + cmd_usage(cmdtp); + return 1; + } + + get_hab_status(); + + return 0; +} + +static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong addr, ivt_offset; + int rcode = 0; + + if (argc < 3) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + ivt_offset = simple_strtoul(argv[2], NULL, 16); + + rcode = authenticate_image(addr, ivt_offset); + + return rcode; +} + +U_BOOT_CMD( + hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, + "display HAB status", + "" + ); + +U_BOOT_CMD( + hab_auth_img, 3, 1, do_authenticate_image, + "authenticate image via HAB", + "addr ivt_offset\n" + "addr - image hex address\n" + "ivt_offset - hex offset of IVT in the image" + );
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/mp.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..9f034d6 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/mp.c
@@ -0,0 +1,87 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau <contact@huau-gabriel.fr> + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h> + +#define MAX_CPUS 4 +static struct src *src = (struct src *)SRC_BASE_ADDR; + +static uint32_t cpu_reset_mask[MAX_CPUS] = { + 0, /* We don't really want to modify the cpu0 */ + SRC_SCR_CORE_1_RESET_MASK, + SRC_SCR_CORE_2_RESET_MASK, + SRC_SCR_CORE_3_RESET_MASK +}; + +static uint32_t cpu_ctrl_mask[MAX_CPUS] = { + 0, /* We don't really want to modify the cpu0 */ + SRC_SCR_CORE_1_ENABLE_MASK, + SRC_SCR_CORE_2_ENABLE_MASK, + SRC_SCR_CORE_3_ENABLE_MASK +}; + +int cpu_reset(int nr) +{ + /* Software reset of the CPU N */ + src->scr |= cpu_reset_mask[nr]; + return 0; +} + +int cpu_status(int nr) +{ + printf("core %d => %d\n", nr, !!(src->scr & cpu_ctrl_mask[nr])); + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + + switch (nr) { + case 1: + src->gpr3 = boot_addr; + break; + case 2: + src->gpr5 = boot_addr; + break; + case 3: + src->gpr7 = boot_addr; + break; + default: + return 1; + } + + /* CPU N is ready to start */ + src->scr |= cpu_ctrl_mask[nr]; + + return 0; +} + +int is_core_valid(unsigned int core) +{ + uint32_t nr_cores = get_nr_cpus(); + + if (core > nr_cores) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + /* Disable the CPU N */ + src->scr &= ~cpu_ctrl_mask[nr]; + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx6/soc.c b/u-boot-imx/arch/arm/cpu/armv7/mx6/soc.c new file mode 100644 index 0000000..79b99b2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx6/soc.c
@@ -0,0 +1,1079 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * (C) Copyright 2009-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/armv7.h> +#include <asm/bootm.h> +#include <asm/pl310.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/imx-common/boot_mode.h> +#include <asm/imx-common/dma.h> +#include <libfdt.h> +#include <stdbool.h> +#include <asm/arch/mxc_hdmi.h> +#include <asm/arch/crm_regs.h> +#include <dm.h> +#include <imx_thermal.h> +#include <mxsfb.h> +#ifdef CONFIG_FSL_FASTBOOT +#ifdef CONFIG_ANDROID_RECOVERY +#include <recovery.h> +#endif +#endif + +enum ldo_reg { + LDO_ARM, + LDO_SOC, + LDO_PU, +}; + +struct scu_regs { + u32 ctrl; + u32 config; + u32 status; + u32 invalidate; + u32 fpga_rev; +}; + +#if defined(CONFIG_IMX_THERMAL) +static const struct imx_thermal_plat imx6_thermal_plat = { + .regs = (void *)ANATOP_BASE_ADDR, + .fuse_bank = 1, + .fuse_word = 6, +}; + +U_BOOT_DEVICE(imx6_thermal) = { + .name = "imx_thermal", + .platdata = &imx6_thermal_plat, +}; +#endif + +u32 get_nr_cpus(void) +{ + struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; + return readl(&scu->config) & 3; +} + +u32 get_cpu_rev(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 reg = readl(&anatop->digprog_sololite); + u32 type = ((reg >> 16) & 0xff); + u32 major; + + if (type != MXC_CPU_MX6SL) { + reg = readl(&anatop->digprog); + struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; + u32 cfg = readl(&scu->config) & 3; + type = ((reg >> 16) & 0xff); + if (type == MXC_CPU_MX6DL) { + if (!cfg) + type = MXC_CPU_MX6SOLO; + } + + if (type == MXC_CPU_MX6Q) { + if (cfg == 1) + type = MXC_CPU_MX6D; + } + + } + major = ((reg >> 8) & 0xff); + reg &= 0xff; /* mx6 silicon revision */ + return (type << 12) | (reg + (0x10 * (major + 1))); +} + +#ifdef CONFIG_REVISION_TAG +u32 __weak get_board_rev(void) +{ + u32 cpurev = get_cpu_rev(); + u32 type = ((cpurev >> 12) & 0xff); + if (type == MXC_CPU_MX6SOLO) + cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF); + + if (type == MXC_CPU_MX6D) + cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF); + + return cpurev; +} +#endif + +void init_aips(void) +{ + struct aipstz_regs *aips1, *aips2; +#ifdef CONFIG_MX6SX + struct aipstz_regs *aips3; +#endif + + aips1 = (struct aipstz_regs *)AIPS1_BASE_ADDR; + aips2 = (struct aipstz_regs *)AIPS2_BASE_ADDR; +#ifdef CONFIG_MX6SX + aips3 = (struct aipstz_regs *)AIPS3_CONFIG_BASE_ADDR; +#endif + + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + writel(0x77777777, &aips1->mprot0); + writel(0x77777777, &aips1->mprot1); + writel(0x77777777, &aips2->mprot0); + writel(0x77777777, &aips2->mprot1); + + /* + * Set all OPACRx to be non-bufferable, not require + * supervisor privilege level for access,allow for + * write access and untrusted master access. + */ + writel(0x00000000, &aips1->opacr0); + writel(0x00000000, &aips1->opacr1); + writel(0x00000000, &aips1->opacr2); + writel(0x00000000, &aips1->opacr3); + writel(0x00000000, &aips1->opacr4); + writel(0x00000000, &aips2->opacr0); + writel(0x00000000, &aips2->opacr1); + writel(0x00000000, &aips2->opacr2); + writel(0x00000000, &aips2->opacr3); + writel(0x00000000, &aips2->opacr4); + +#ifdef CONFIG_MX6SX + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + writel(0x77777777, &aips3->mprot0); + writel(0x77777777, &aips3->mprot1); + + /* + * Set all OPACRx to be non-bufferable, not require + * supervisor privilege level for access,allow for + * write access and untrusted master access. + */ + writel(0x00000000, &aips3->opacr0); + writel(0x00000000, &aips3->opacr1); + writel(0x00000000, &aips3->opacr2); + writel(0x00000000, &aips3->opacr3); + writel(0x00000000, &aips3->opacr4); +#endif +} + +static void clear_ldo_ramp(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + int reg; + + /* ROM may modify LDO ramp up time according to fuse setting, so in + * order to be in the safe side we neeed to reset these settings to + * match the reset value: 0'b00 + */ + reg = readl(&anatop->ana_misc2); + reg &= ~(0x3f << 24); + writel(reg, &anatop->ana_misc2); +} + +/* + * Set the PMU_REG_CORE register + * + * Set LDO_SOC/PU/ARM regulators to the specified millivolt level. + * Possible values are from 0.725V to 1.450V in steps of + * 0.025V (25mV). + */ +static int set_ldo_voltage(enum ldo_reg ldo, u32 mv) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 val, step, old, reg = readl(&anatop->reg_core); + u8 shift; + + if (mv < 725) + val = 0x00; /* Power gated off */ + else if (mv > 1450) + val = 0x1F; /* Power FET switched full on. No regulation */ + else + val = (mv - 700) / 25; + + clear_ldo_ramp(); + + switch (ldo) { + case LDO_SOC: + shift = 18; + break; + case LDO_PU: + shift = 9; + break; + case LDO_ARM: + shift = 0; + break; + default: + return -EINVAL; + } + + old = (reg & (0x1F << shift)) >> shift; + step = abs(val - old); + if (step == 0) + return 0; + + reg = (reg & ~(0x1F << shift)) | (val << shift); + writel(reg, &anatop->reg_core); + + /* + * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per + * step + */ + udelay(3 * step); + + return 0; +} + +static void imx_set_wdog_powerdown(bool enable) +{ + struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; + struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; + +#if (defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL)) + struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; + writew(enable, &wdog3->wmcr); +#endif + + /* Write to the PDE (Power Down Enable) bit */ + writew(enable, &wdog1->wmcr); + writew(enable, &wdog2->wmcr); +} + +#if !defined(CONFIG_MX6UL) +static void set_ahb_rate(u32 val) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg, div; + + div = get_periph_clk() / val - 1; + reg = readl(&mxc_ccm->cbcdr); + + writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) | + (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr); +} +#endif + +static void clear_mmdc_ch_mask(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg; + reg = readl(&mxc_ccm->ccdr); + + /* Clear MMDC channel mask */ + reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK); + writel(reg, &mxc_ccm->ccdr); +} + +static void init_bandgap(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + /* + * Ensure the bandgap has stabilized. + */ + while (!(readl(&anatop->ana_misc0) & 0x80)) + ; + /* + * For best noise performance of the analog blocks using the + * outputs of the bandgap, the reftop_selfbiasoff bit should + * be set. + */ + writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); +} + + +#ifdef CONFIG_MX6SL +static void set_preclk_from_osc(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 reg; + + reg = readl(&mxc_ccm->cscmr1); + reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK; + writel(reg, &mxc_ccm->cscmr1); +} +#endif + +#define SRC_SCR_WARM_RESET_ENABLE 0 + +static void init_src(void) +{ + struct src *src_regs = (struct src *)SRC_BASE_ADDR; + u32 val; + + /* + * force warm reset sources to generate cold reset + * for a more reliable restart + */ + val = readl(&src_regs->scr); + val &= ~(1 << SRC_SCR_WARM_RESET_ENABLE); + writel(val, &src_regs->scr); +} + +#ifdef CONFIG_MX6SX +void vadc_power_up(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + u32 val; + + /* csi0 */ + val = readl(&iomux->gpr[5]); + val &= ~IMX6SX_GPR5_CSI1_MUX_CTRL_MASK, + val |= IMX6SX_GPR5_CSI1_MUX_CTRL_CVD; + writel(val, &iomux->gpr[5]); + + /* Power on vadc analog + * Power down vadc ext power */ + val = readl(GPC_BASE_ADDR + 0); + val &= ~0x60000; + writel(val, GPC_BASE_ADDR + 0); + + /* software reset afe */ + val = readl(&iomux->gpr[1]); + writel(val | 0x80000, &iomux->gpr[1]); + + udelay(10*1000); + + /* Release reset bit */ + writel(val & ~0x80000, &iomux->gpr[1]); + + /* Power on vadc ext power */ + val = readl(GPC_BASE_ADDR + 0); + val |= 0x40000; + writel(val, GPC_BASE_ADDR + 0); +} + +void vadc_power_down(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + u32 val; + + /* Power down vadc ext power + * Power off vadc analog */ + val = readl(GPC_BASE_ADDR + 0); + val &= ~0x40000; + val |= 0x20000; + writel(val, GPC_BASE_ADDR + 0); + + /* clean csi0 connect to vadc */ + val = readl(&iomux->gpr[5]); + val &= ~IMX6SX_GPR5_CSI1_MUX_CTRL_MASK, + writel(val, &iomux->gpr[5]); +} + +void pcie_power_up(void) +{ + set_ldo_voltage(LDO_PU, 1100); /* Set VDDPU to 1.1V */ +} + +void pcie_power_off(void) +{ + set_ldo_voltage(LDO_PU, 0); /* Set VDDPU to 1.1V */ +} +#endif + +#ifndef CONFIG_MX6UL +static void imx_set_vddpu_power_down(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + u32 val; + + /* need to power down xPU in GPC before turn off PU LDO */ + val = readl(GPC_BASE_ADDR + 0x260); + writel(val | 0x1, GPC_BASE_ADDR + 0x260); + + val = readl(GPC_BASE_ADDR + 0x0); + writel(val | 0x1, GPC_BASE_ADDR + 0x0); + while (readl(GPC_BASE_ADDR + 0x0) & 0x1) + ; + + /* disable VDDPU */ + val = 0x3e00; + writel(val, &anatop->reg_core_clr); +} +#endif + +#if !(defined(CONFIG_MX6SL) || defined(CONFIG_MX6UL)) +static void imx_set_pcie_phy_power_down(void) +{ + u32 val; + +#ifndef CONFIG_MX6SX + val = readl(IOMUXC_BASE_ADDR + 0x4); + val |= 0x1 << 18; + writel(val, IOMUXC_BASE_ADDR + 0x4); +#else + val = readl(IOMUXC_GPR_BASE_ADDR + 0x30); + val |= 0x1 << 30; + writel(val, IOMUXC_GPR_BASE_ADDR + 0x30); +#endif +} +#endif + +int arch_cpu_init(void) +{ + /* Clear the Align bit in SCTLR */ + set_cr(get_cr() & ~CR_A); + +#if !defined(CONFIG_MX6SX) && !defined(CONFIG_MX6SL) && !defined(CONFIG_MX6UL) + /* + * imx6sl doesn't have pcie at all. + * this bit is not used by imx6sx anymore + */ + u32 val; + + /* + * There are about 0.02% percentage, random pcie link down + * when warm-reset is used. + * clear the ref_ssp_en bit16 of gpr1 to workaround it. + * then warm-reset imx6q/dl/solo again. + */ + val = readl(IOMUXC_BASE_ADDR + 0x4); + if (val & (0x1 << 16)) { + val &= ~(0x1 << 16); + writel(val, IOMUXC_BASE_ADDR + 0x4); + reset_cpu(0); + } +#endif + + init_aips(); + + /* Need to clear MMDC_CHx_MASK to make warm reset work. */ + clear_mmdc_ch_mask(); + + /* + * Disable self-bias circuit in the analog bandap. + * The self-bias circuit is used by the bandgap during startup. + * This bit should be set after the bandgap has initialized. + */ + init_bandgap(); + +#if !defined(CONFIG_MX6UL) + /* + * When low freq boot is enabled, ROM will not set AHB + * freq, so we need to ensure AHB freq is 132MHz in such + * scenario. + */ + if (mxc_get_clock(MXC_ARM_CLK) == 396000000) + set_ahb_rate(132000000); +#endif + +#if defined(CONFIG_MX6UL) + /* + * According to the design team's requirement on i.MX6UL, + * the PMIC_STBY_REQ PAD should be configured as open + * drain 100K (0x0000b8a0). + */ + writel(0x0000b8a0, IOMUXC_BASE_ADDR + 0x29c); +#endif + + /* Set perclk to source from OSC 24MHz */ +#if defined(CONFIG_MX6SL) + set_preclk_from_osc(); +#endif + +#ifdef CONFIG_MX6SX + u32 reg; + + /* set uart clk to OSC */ + reg = readl(CCM_BASE_ADDR + 0x24); + reg |= MXC_CCM_CSCDR1_UART_CLK_SEL; + writel(reg, CCM_BASE_ADDR + 0x24); +#endif + + imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ + +#if !(defined(CONFIG_MX6SL) || defined(CONFIG_MX6UL)) + imx_set_pcie_phy_power_down(); +#endif + +#if !defined(CONFIG_MX6UL) + if (!is_mx6dqp()) + imx_set_vddpu_power_down(); +#endif + +#ifdef CONFIG_APBH_DMA + /* Start APBH DMA */ + mxs_dma_init(); +#endif + + init_src(); + + if (is_mx6dqp()) + writel(0x80000201, 0xbb0608); + + return 0; +} + +int board_postclk_init(void) +{ + set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */ + + return 0; +} + +#ifdef CONFIG_SERIAL_TAG +void get_board_serial(struct tag_serialnr *serialnr) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + + serialnr->low = fuse->uid_low; + serialnr->high = fuse->uid_high; +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) + enum dcache_option option = DCACHE_WRITETHROUGH; +#else + enum dcache_option option = DCACHE_WRITEBACK; +#endif + + /* Avoid random hang when download by usb */ + invalidate_dcache_all(); + + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); + + /* Enable caching on OCRAM and ROM */ + mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, + ROMCP_ARB_END_ADDR, + option); + mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, + IRAM_SIZE, + option); +} +#endif + +#if defined(CONFIG_FEC_MXC) +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[4]; + struct fuse_bank4_regs *fuse = + (struct fuse_bank4_regs *)bank->fuse_regs; + +#if (defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL)) + if (0 == dev_id) { + u32 value = readl(&fuse->mac_addr1); + mac[0] = (value >> 8); + mac[1] = value ; + + value = readl(&fuse->mac_addr0); + mac[2] = value >> 24 ; + mac[3] = value >> 16 ; + mac[4] = value >> 8 ; + mac[5] = value ; + } else { + u32 value = readl(&fuse->mac_addr2); + mac[0] = value >> 24 ; + mac[1] = value >> 16 ; + mac[2] = value >> 8 ; + mac[3] = value ; + + value = readl(&fuse->mac_addr1); + mac[4] = value >> 24 ; + mac[5] = value >> 16 ; + } +#else + u32 value = readl(&fuse->mac_addr_high); + mac[0] = (value >> 8); + mac[1] = value ; + + value = readl(&fuse->mac_addr_low); + mac[2] = value >> 24 ; + mac[3] = value >> 16 ; + mac[4] = value >> 8 ; + mac[5] = value ; + +#endif +} +#endif + +#ifdef CONFIG_MX6SX +int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) +{ + struct src *src_reg; + u32 stack, pc; + + if (!boot_private_data) + return 1; + + stack = *(u32 *)boot_private_data; + pc = *(u32 *)(boot_private_data + 4); + + /* Set the stack and pc to M4 bootROM */ + writel(stack, M4_BOOTROM_BASE_ADDR); + writel(pc, M4_BOOTROM_BASE_ADDR + 4); + + /* Enable M4 */ + src_reg = (struct src *)SRC_BASE_ADDR; + setbits_le32(&src_reg->scr, 0x00400000); + clrbits_le32(&src_reg->scr, 0x00000010); + + return 0; +} + +int arch_auxiliary_core_check_up(u32 core_id) +{ + struct src *src_reg = (struct src *)SRC_BASE_ADDR; + unsigned val; + + val = readl(&src_reg->scr); + + if (val & 0x00000010) + return 0; /* assert in reset */ + + return 1; +} +#endif + +void boot_mode_apply(unsigned cfg_val) +{ + unsigned reg; + struct src *psrc = (struct src *)SRC_BASE_ADDR; + writel(cfg_val, &psrc->gpr9); + reg = readl(&psrc->gpr10); + if (cfg_val) + reg |= 1 << 28; + else + reg &= ~(1 << 28); + writel(reg, &psrc->gpr10); +} +/* + * cfg_val will be used for + * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] + * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0] + * instead of SBMR1 to determine the boot device. + */ +const struct boot_mode soc_boot_modes[] = { + {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, + /* reserved value should start rom usb */ + {"usb", MAKE_CFGVAL(0x01, 0x00, 0x00, 0x00)}, + {"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)}, + {"ecspi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)}, + {"ecspi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)}, + {"ecspi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)}, + {"ecspi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)}, + /* 4 bit bus width */ + {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, + {"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, + {"esdhc3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, + {"esdhc4", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, + {NULL, 0}, +}; + +enum boot_device get_boot_device(void) +{ + enum boot_device boot_dev = UNKNOWN_BOOT; + uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4); + uint bt_mem_ctl = (soc_sbmr & 0x000000FF) >> 4 ; + uint bt_mem_type = (soc_sbmr & 0x00000008) >> 3; + uint bt_dev_port = (soc_sbmr & 0x00001800) >> 11; + + switch (bt_mem_ctl) { + case 0x0: + if (bt_mem_type) + boot_dev = ONE_NAND_BOOT; + else + boot_dev = WEIM_NOR_BOOT; + break; + case 0x2: + boot_dev = SATA_BOOT; + break; + case 0x3: + if (bt_mem_type) + boot_dev = I2C_BOOT; + else + boot_dev = SPI_NOR_BOOT; + break; + case 0x4: + case 0x5: + boot_dev = bt_dev_port + SD1_BOOT; + break; + case 0x6: + case 0x7: + boot_dev = bt_dev_port + MMC1_BOOT; + break; + case 0x8 ... 0xf: + boot_dev = NAND_BOOT; + break; + default: + boot_dev = UNKNOWN_BOOT; + break; + } + + return boot_dev; +} + +void s_init(void) +{ + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + u32 mask480; + u32 mask528; + u32 reg, periph1, periph2; + + if (is_cpu_type(MXC_CPU_MX6SX) || is_cpu_type(MXC_CPU_MX6UL)) + return; + + /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs + * to make sure PFD is working right, otherwise, PFDs may + * not output clock after reset, MX6DL and MX6SL have added 396M pfd + * workaround in ROM code, as bus clock need it + */ + + mask480 = ANATOP_PFD_CLKGATE_MASK(0) | + ANATOP_PFD_CLKGATE_MASK(1) | + ANATOP_PFD_CLKGATE_MASK(2) | + ANATOP_PFD_CLKGATE_MASK(3); + mask528 = ANATOP_PFD_CLKGATE_MASK(1) | + ANATOP_PFD_CLKGATE_MASK(3); + + reg = readl(&ccm->cbcmr); + periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) + >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET); + periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) + >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET); + + /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */ + if ((periph2 != 0x2) && (periph1 != 0x2)) + mask528 |= ANATOP_PFD_CLKGATE_MASK(0); + + if ((periph2 != 0x1) && (periph1 != 0x1) && + (periph2 != 0x3) && (periph1 != 0x3)) + mask528 |= ANATOP_PFD_CLKGATE_MASK(2); + + writel(mask480, &anatop->pfd_480_set); + writel(mask528, &anatop->pfd_528_set); + writel(mask480, &anatop->pfd_480_clr); + writel(mask528, &anatop->pfd_528_clr); +} + +void set_wdog_reset(struct wdog_regs *wdog) +{ + u32 reg = readw(&wdog->wcr); + /* + * use WDOG_B mode to reset external pmic because it's risky for the + * following watchdog reboot in case of cpu freq at lowest 400Mhz with + * ldo-bypass mode. Because boot frequency maybe higher 800Mhz i.e. So + * in ldo-bypass mode watchdog reset will only triger POR reset, not + * WDOG reset. But below code depends on hardware design, if HW didn't + * connect WDOG_B pin to external pmic such as i.mx6slevk, we can skip + * these code since it assumed boot from 400Mhz always. + */ + reg = readw(&wdog->wcr); + reg |= 1 << 3; + /* + * WDZST bit is write-once only bit. Align this bit in kernel, + * otherwise kernel code will have no chance to set this bit. + */ + reg |= 1 << 0; + writew(reg, &wdog->wcr); +} + +void reset_misc(void) +{ +#ifdef CONFIG_VIDEO_MXS + if (is_cpu_type(MXC_CPU_MX6UL)) + lcdif_power_down(); +#endif +} + +#ifdef CONFIG_LDO_BYPASS_CHECK +DECLARE_GLOBAL_DATA_PTR; +static int ldo_bypass; + +int check_ldo_bypass(void) +{ + const int *ldo_mode; + int node; + + /* get the right fdt_blob from the global working_fdt */ + gd->fdt_blob = working_fdt; + /* Get the node from FDT for anatop ldo-bypass */ + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, + "fsl,imx6q-gpc"); + if (node < 0) { + printf("No gpc device node %d, force to ldo-enable.\n", node); + return 0; + } + ldo_mode = fdt_getprop(gd->fdt_blob, node, "fsl,ldo-bypass", NULL); + /* + * return 1 if "fsl,ldo-bypass = <1>", else return 0 if + * "fsl,ldo-bypass = <0>" or no "fsl,ldo-bypass" property + */ + ldo_bypass = fdt32_to_cpu(*ldo_mode) == 1 ? 1 : 0; + + return ldo_bypass; +} + +int check_1_2G(void) +{ + u32 reg; + int result = 0; + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse_bank0 = + (struct fuse_bank0_regs *)bank->fuse_regs; + + reg = readl(&fuse_bank0->cfg3); + if (((reg >> 16) & 0x3) == 0x3) { + if (ldo_bypass) { + printf("Wrong dtb file used! i.MX6Q@1.2Ghz only " + "works with ldo-enable mode!\n"); + /* + * Currently, only imx6q-sabresd board might be here, + * since only i.MX6Q support 1.2G and only Sabresd board + * support ldo-bypass mode. So hardcode here. + * You can also modify your board(i.MX6Q) dtb name if it + * supports both ldo-bypass and ldo-enable mode. + */ + printf("Please use imx6q-sabresd-ldo.dtb!\n"); + hang(); + } + result = 1; + } + + return result; +} + +static int arm_orig_podf; +void set_arm_freq_400M(bool is_400M) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + if (is_400M) + writel(0x1, &mxc_ccm->cacrr); + else + writel(arm_orig_podf, &mxc_ccm->cacrr); +} + +void prep_anatop_bypass(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + arm_orig_podf = readl(&mxc_ccm->cacrr); + /* + * Downgrade ARM speed to 400Mhz as half of boot 800Mhz before ldo + * bypassed, also downgrade internal vddarm ldo to 0.975V. + * VDDARM_IN 0.975V + 125mV = 1.1V < Max(1.3V) + * otherwise at 800Mhz(i.mx6dl): + * VDDARM_IN 1.175V + 125mV = 1.3V = Max(1.3V) + * We need provide enough gap in this case. + * skip if boot from 400M. + */ + if (!arm_orig_podf) + set_arm_freq_400M(true); +#if !defined(CONFIG_MX6DL) && !defined(CONFIG_MX6SX) + set_ldo_voltage(LDO_ARM, 975); +#else + set_ldo_voltage(LDO_ARM, 1150); +#endif +} + +int set_anatop_bypass(int wdog_reset_pin) +{ + struct anatop_regs *anatop= (struct anatop_regs*)ANATOP_BASE_ADDR; + struct wdog_regs *wdog; + u32 reg = readl(&anatop->reg_core); + + /* bypass VDDARM/VDDSOC */ + reg = reg | (0x1F << 18) | 0x1F; + writel(reg, &anatop->reg_core); + + if (wdog_reset_pin == 2) + wdog = (struct wdog_regs *) WDOG2_BASE_ADDR; + else if (wdog_reset_pin == 1) + wdog = (struct wdog_regs *) WDOG1_BASE_ADDR; + else + return arm_orig_podf; + set_wdog_reset(wdog); + return arm_orig_podf; +} + +void finish_anatop_bypass(void) +{ + if (!arm_orig_podf) + set_arm_freq_400M(false); +} +#endif + +#ifdef CONFIG_IMX_HDMI +void imx_enable_hdmi_phy(void) +{ + struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; + u8 reg; + reg = readb(&hdmi->phy_conf0); + reg |= HDMI_PHY_CONF0_PDZ_MASK; + writeb(reg, &hdmi->phy_conf0); + udelay(3000); + reg |= HDMI_PHY_CONF0_ENTMDS_MASK; + writeb(reg, &hdmi->phy_conf0); + udelay(3000); + reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK; + writeb(reg, &hdmi->phy_conf0); + writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz); +} + +void imx_setup_hdmi(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; + int reg, count; + u8 val; + + /* Turn on HDMI PHY clock */ + reg = readl(&mxc_ccm->CCGR2); + reg |= MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK| + MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK; + writel(reg, &mxc_ccm->CCGR2); + writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz); + reg = readl(&mxc_ccm->chsccdr); + reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK| + MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK| + MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK); + reg |= (CHSCCDR_PODF_DIVIDE_BY_3 + << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) + |(CHSCCDR_IPU_PRE_CLK_540M_PFD + << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->chsccdr); + + /* Workaround to clear the overflow condition */ + if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) { + /* TMDS software reset */ + writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz); + val = readb(&hdmi->fc_invidconf); + for (count = 0 ; count < 5 ; count++) + writeb(val, &hdmi->fc_invidconf); + } +} +#endif + +#ifndef CONFIG_SYS_L2CACHE_OFF +#ifndef CONFIG_MX6UL +#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002 +void v7_outer_cache_enable(void) +{ + struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE; + unsigned int val, cache_id; + +#if defined CONFIG_MX6SL + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + val = readl(&iomux->gpr[11]); + if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) { + /* L2 cache configured as OCRAM, reset it */ + val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM; + writel(val, &iomux->gpr[11]); + } +#endif + + /* Must disable the L2 before changing the latency parameters */ + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); + + writel(0x132, &pl310->pl310_tag_latency_ctrl); + writel(0x132, &pl310->pl310_data_latency_ctrl); + + val = readl(&pl310->pl310_prefetch_ctrl); + + /* Turn on the L2 I/D prefetch, double linefill */ + /* Set prefetch offset with any value except 23 as per errata 765569 */ + val |= 0x7000000f; + + /* + * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0 + * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL/SX/DQP + * is r3p2. + * But according to ARM PL310 errata: 752271 + * ID: 752271: Double linefill feature can cause data corruption + * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2 + * Workaround: The only workaround to this erratum is to disable the + * double linefill feature. This is the default behavior. + */ + cache_id = readl(&pl310->pl310_cache_id); + if (((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310) + && ((cache_id & L2X0_CACHE_ID_RTL_MASK) < L2X0_CACHE_ID_RTL_R3P2)) + val &= ~(1 << 30); + writel(val, &pl310->pl310_prefetch_ctrl); + + val = readl(&pl310->pl310_power_ctrl); + val |= L2X0_DYNAMIC_CLK_GATING_EN; + val |= L2X0_STNDBY_MODE_EN; + writel(val, &pl310->pl310_power_ctrl); + + setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); +} + +void v7_outer_cache_disable(void) +{ + struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE; + + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); +} +#endif +#endif /* !CONFIG_SYS_L2CACHE_OFF */ + +#ifdef CONFIG_FSL_FASTBOOT + +#ifdef CONFIG_ANDROID_RECOVERY +#define ANDROID_RECOVERY_BOOT (1 << 7) +/* check if the recovery bit is set by kernel, it can be set by kernel + * issue a command '# reboot recovery' */ +int recovery_check_and_clean_flag(void) +{ + int flag_set = 0; + u32 reg; + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); + + flag_set = !!(reg & ANDROID_RECOVERY_BOOT); + printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set); + /* clean it in case looping infinite here.... */ + if (flag_set) { + reg &= ~ANDROID_RECOVERY_BOOT; + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); + } + + return flag_set; +} +#endif /*CONFIG_ANDROID_RECOVERY*/ + +#define ANDROID_FASTBOOT_BOOT (1 << 8) +/* check if the recovery bit is set by kernel, it can be set by kernel + * issue a command '# reboot fastboot' */ +int fastboot_check_and_clean_flag(void) +{ + int flag_set = 0; + u32 reg; + + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); + + flag_set = !!(reg & ANDROID_FASTBOOT_BOOT); + + /* clean it in case looping infinite here.... */ + if (flag_set) { + reg &= ~ANDROID_FASTBOOT_BOOT; + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); + } + + return flag_set; +} + +void fastboot_enable_flag(void) +{ + setbits_le32(SNVS_BASE_ADDR + SNVS_LPGPR, + ANDROID_FASTBOOT_BOOT); +} +#endif /*CONFIG_FSL_FASTBOOT*/
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx7/Makefile b/u-boot-imx/arch/arm/cpu/armv7/mx7/Makefile new file mode 100644 index 0000000..6c1764f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx7/Makefile
@@ -0,0 +1,9 @@ +# +# (C) Copyright 2014-2015 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# +# + +obj-y := soc.o clock.o clock_slice.o +obj-$(CONFIG_SECURE_BOOT) += hab.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx7/clock.c b/u-boot-imx/arch/arm/cpu/armv7/mx7/clock.c new file mode 100644 index 0000000..05b106c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx7/clock.c
@@ -0,0 +1,1130 @@ +/* + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * + * Author: + * Peng Fan <Peng.Fan@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) + ANATOP_BASE_ADDR; +struct mxc_ccm_reg *ccm_reg = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + +#ifdef CONFIG_FSL_ESDHC +DECLARE_GLOBAL_DATA_PTR; +#endif + +int get_clocks(void) +{ +#ifdef CONFIG_FSL_ESDHC +#if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); +#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); +#else + gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); +#endif +#endif + return 0; +} + +u32 get_ahb_clk(void) +{ + return get_root_clk(AHB_CLK_ROOT); +} + +static u32 get_ipg_clk(void) +{ + /* + * The AHB and IPG are fixed at 2:1 ratio, and synchronized to + * each other. + */ + return get_ahb_clk() / 2; +} + +u32 imx_get_uartclk(void) +{ + return get_root_clk(UART1_CLK_ROOT); +} + +u32 imx_get_fecclk(void) +{ + return get_root_clk(ENET_AXI_CLK_ROOT); +} + +#ifdef CONFIG_MXC_OCOTP +void enable_ocotp_clk(unsigned char enable) +{ + clock_enable(CCGR_OCOTP, enable); +} + +void enable_thermal_clk(void) +{ + enable_ocotp_clk(1); +} +#endif + +void enable_usboh3_clk(unsigned char enable) +{ + u32 target; + + if (enable) { + /* disable the clock gate first */ + clock_enable(CCGR_USB_HSIC, 0); + + /* 120Mhz */ + target = CLK_ROOT_ON | USB_HSIC_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(USB_HSIC_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_USB_CTRL, 1); + clock_enable(CCGR_USB_HSIC, 1); + clock_enable(CCGR_USB_PHY1, 1); + clock_enable(CCGR_USB_PHY2, 1); + } else { + clock_enable(CCGR_USB_CTRL, 0); + clock_enable(CCGR_USB_HSIC, 0); + clock_enable(CCGR_USB_PHY1, 0); + clock_enable(CCGR_USB_PHY2, 0); + } + +} + +static u32 decode_pll(enum pll_clocks pll, u32 infreq) +{ + u32 reg, div_sel; + u32 num, denom; + + /* + * Alought there are four choices for the bypass src, + * we choose OSC_24M which is the default set in ROM. + */ + switch (pll) { + case PLL_CORE: + reg = readl(&ccm_anatop->pll_arm); + + if (reg & CCM_ANALOG_PLL_ARM_POWERDOWN_MASK) + return 0; + + if (reg & CCM_ANALOG_PLL_ARM_BYPASS_MASK) + return MXC_HCLK; + + div_sel = (reg & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> + CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT; + + return (infreq * div_sel) / 2; + + case PLL_SYS: + reg = readl(&ccm_anatop->pll_480); + + if (reg & CCM_ANALOG_PLL_480_POWERDOWN_MASK) + return 0; + + if (reg & CCM_ANALOG_PLL_480_BYPASS_MASK) + return MXC_HCLK; + + if (((reg & CCM_ANALOG_PLL_480_DIV_SELECT_MASK) >> + CCM_ANALOG_PLL_480_DIV_SELECT_SHIFT) == 0) + return 480000000u; + else + return 528000000u; + + case PLL_ENET: + reg = readl(&ccm_anatop->pll_enet); + + if (reg & CCM_ANALOG_PLL_ENET_POWERDOWN_MASK) + return 0; + + if (reg & CCM_ANALOG_PLL_ENET_BYPASS_MASK) + return MXC_HCLK; + + return 1000000000u; + + case PLL_DDR: + reg = readl(&ccm_anatop->pll_ddr); + + if (reg & CCM_ANALOG_PLL_DDR_POWERDOWN_MASK) + return 0; + + num = ccm_anatop->pll_ddr_num; + denom = ccm_anatop->pll_ddr_denom; + + if (reg & CCM_ANALOG_PLL_DDR_BYPASS_MASK) + return MXC_HCLK; + + div_sel = (reg & CCM_ANALOG_PLL_DDR_DIV_SELECT_MASK) >> + CCM_ANALOG_PLL_DDR_DIV_SELECT_SHIFT; + + return infreq * (div_sel + num / denom); + + case PLL_USB: + return 480000000u; + + default: + printf("Unsupported pll clocks %d\n", pll); + break; + } + + return 0; +} + +static u32 mxc_get_pll_sys_derive(int derive) +{ + u32 freq, div, frac; + u32 reg; + + div = 1; + reg = readl(&ccm_anatop->pll_480); + freq = decode_pll(PLL_SYS, MXC_HCLK); + + switch (derive) { + case PLL_SYS_MAIN_480M_CLK: + if (reg & CCM_ANALOG_PLL_480_MAIN_DIV1_CLKGATE_MASK) + return 0; + else + return freq; + case PLL_SYS_MAIN_240M_CLK: + if (reg & CCM_ANALOG_PLL_480_MAIN_DIV2_CLKGATE_MASK) + return 0; + else + return freq / 2; + case PLL_SYS_MAIN_120M_CLK: + if (reg & CCM_ANALOG_PLL_480_MAIN_DIV4_CLKGATE_MASK) + return 0; + else + return freq / 4; + case PLL_SYS_PFD0_392M_CLK: + reg = readl(&ccm_anatop->pfd_480a); + if (reg & CCM_ANALOG_PFD_480A_PFD0_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT; + break; + case PLL_SYS_PFD0_196M_CLK: + if (reg & CCM_ANALOG_PLL_480_PFD0_DIV2_CLKGATE_MASK) + return 0; + reg = readl(&ccm_anatop->pfd_480a); + frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT; + div = 2; + break; + case PLL_SYS_PFD1_332M_CLK: + reg = readl(&ccm_anatop->pfd_480a); + if (reg & CCM_ANALOG_PFD_480A_PFD1_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT; + break; + case PLL_SYS_PFD1_166M_CLK: + if (reg & CCM_ANALOG_PLL_480_PFD1_DIV2_CLKGATE_MASK) + return 0; + reg = readl(&ccm_anatop->pfd_480a); + frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT; + div = 2; + break; + case PLL_SYS_PFD2_270M_CLK: + reg = readl(&ccm_anatop->pfd_480a); + if (reg & CCM_ANALOG_PFD_480A_PFD2_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT; + break; + case PLL_SYS_PFD2_135M_CLK: + if (reg & CCM_ANALOG_PLL_480_PFD2_DIV2_CLKGATE_MASK) + return 0; + reg = readl(&ccm_anatop->pfd_480a); + frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT; + div = 2; + break; + case PLL_SYS_PFD3_CLK: + reg = readl(&ccm_anatop->pfd_480a); + if (reg & CCM_ANALOG_PFD_480A_PFD3_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480A_PFD3_FRAC_MASK) >> + CCM_ANALOG_PFD_480A_PFD3_FRAC_SHIFT; + break; + case PLL_SYS_PFD4_CLK: + reg = readl(&ccm_anatop->pfd_480b); + if (reg & CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480B_PFD4_FRAC_MASK) >> + CCM_ANALOG_PFD_480B_PFD4_FRAC_SHIFT; + break; + case PLL_SYS_PFD5_CLK: + reg = readl(&ccm_anatop->pfd_480b); + if (reg & CCM_ANALOG_PFD_480B_PFD5_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480B_PFD5_FRAC_MASK) >> + CCM_ANALOG_PFD_480B_PFD5_FRAC_SHIFT; + break; + case PLL_SYS_PFD6_CLK: + reg = readl(&ccm_anatop->pfd_480b); + if (reg & CCM_ANALOG_PFD_480B_PFD6_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480B_PFD6_FRAC_MASK) >> + CCM_ANALOG_PFD_480B_PFD6_FRAC_SHIFT; + break; + case PLL_SYS_PFD7_CLK: + reg = readl(&ccm_anatop->pfd_480b); + if (reg & CCM_ANALOG_PFD_480B_PFD7_DIV1_CLKGATE_MASK) + return 0; + frac = (reg & CCM_ANALOG_PFD_480B_PFD7_FRAC_MASK) >> + CCM_ANALOG_PFD_480B_PFD7_FRAC_SHIFT; + break; + default: + printf("Error derived pll_sys clock %d\n", derive); + return 0; + } + + return ((freq / frac) * 18) / div; +} + +static u32 mxc_get_pll_enet_derive(int derive) +{ + u32 freq, reg; + + freq = decode_pll(PLL_ENET, MXC_HCLK); + reg = readl(&ccm_anatop->pll_enet); + + switch (derive) { + case PLL_ENET_MAIN_500M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK) + return freq / 2; + break; + case PLL_ENET_MAIN_250M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK) + return freq / 4; + break; + case PLL_ENET_MAIN_125M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK) + return freq / 8; + break; + case PLL_ENET_MAIN_100M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK) + return freq / 10; + break; + case PLL_ENET_MAIN_50M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK) + return freq / 20; + break; + case PLL_ENET_MAIN_40M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK) + return freq / 25; + break; + case PLL_ENET_MAIN_25M_CLK: + if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK) + return freq / 40; + break; + default: + printf("Error derived pll_enet clock %d\n", derive); + break; + } + + return 0; +} + +static u32 mxc_get_pll_ddr_derive(int derive) +{ + u32 freq, reg; + + freq = decode_pll(PLL_DDR, MXC_HCLK); + reg = readl(&ccm_anatop->pll_ddr); + + switch (derive) { + case PLL_DRAM_MAIN_1066M_CLK: + return freq; + case PLL_DRAM_MAIN_533M_CLK: + if (reg & CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK_MASK) + return freq / 2; + break; + default: + printf("Error derived pll_ddr clock %d\n", derive); + break; + } + + return 0; +} + +static u32 mxc_get_pll_derive(enum pll_clocks pll, int derive) +{ + switch (pll) { + case PLL_SYS: + return mxc_get_pll_sys_derive(derive); + case PLL_ENET: + return mxc_get_pll_enet_derive(derive); + case PLL_DDR: + return mxc_get_pll_ddr_derive(derive); + default: + printf("Error pll.\n"); + return 0; + } +} + +static u32 get_root_src_clk(enum clk_root_src root_src) +{ + switch (root_src) { + case OSC_24M_CLK: + return 24000000u; + case PLL_ARM_MAIN_800M_CLK: + return decode_pll(PLL_CORE, MXC_HCLK); + + case PLL_SYS_MAIN_480M_CLK: + case PLL_SYS_MAIN_240M_CLK: + case PLL_SYS_MAIN_120M_CLK: + case PLL_SYS_PFD0_392M_CLK: + case PLL_SYS_PFD0_196M_CLK: + case PLL_SYS_PFD1_332M_CLK: + case PLL_SYS_PFD1_166M_CLK: + case PLL_SYS_PFD2_270M_CLK: + case PLL_SYS_PFD2_135M_CLK: + case PLL_SYS_PFD3_CLK: + case PLL_SYS_PFD4_CLK: + case PLL_SYS_PFD5_CLK: + case PLL_SYS_PFD6_CLK: + case PLL_SYS_PFD7_CLK: + return mxc_get_pll_derive(PLL_SYS, root_src); + + case PLL_ENET_MAIN_500M_CLK: + case PLL_ENET_MAIN_250M_CLK: + case PLL_ENET_MAIN_125M_CLK: + case PLL_ENET_MAIN_100M_CLK: + case PLL_ENET_MAIN_50M_CLK: + case PLL_ENET_MAIN_40M_CLK: + case PLL_ENET_MAIN_25M_CLK: + return mxc_get_pll_derive(PLL_ENET, root_src); + + case PLL_DRAM_MAIN_1066M_CLK: + case PLL_DRAM_MAIN_533M_CLK: + return mxc_get_pll_derive(PLL_DDR, root_src); + + case PLL_AUDIO_MAIN_CLK: + return decode_pll(PLL_AUDIO, MXC_HCLK); + case PLL_VIDEO_MAIN_CLK: + return decode_pll(PLL_VIDEO, MXC_HCLK); + + case PLL_USB_MAIN_480M_CLK: + return decode_pll(PLL_USB, MXC_HCLK); + + case REF_1M_CLK: + return 1000000; + case OSC_32K_CLK: + return MXC_CLK32; + + case EXT_CLK_1: + case EXT_CLK_2: + case EXT_CLK_3: + case EXT_CLK_4: + printf("No EXT CLK supported??\n"); + break; + }; + + return 0; +} + +u32 get_root_clk(enum clk_root_index clock_id) +{ + enum clk_root_src root_src; + u32 post_podf, pre_podf, auto_podf, root_src_clk; + int auto_en; + + if (clock_root_enabled(clock_id) <= 0) + return 0; + + if (clock_get_prediv(clock_id, &pre_podf) < 0) + return 0; + + if (clock_get_postdiv(clock_id, &post_podf) < 0) + return 0; + + if (clock_get_autopostdiv(clock_id, &auto_podf, &auto_en) < 0) + return 0; + + if (auto_en == 0) + auto_podf = 0; + + if (clock_get_src(clock_id, &root_src) < 0) + return 0; + + root_src_clk = get_root_src_clk(root_src); + + /* + * bypass clk is ignored. + */ + + return root_src_clk / (post_podf + 1) / (pre_podf + 1) / + (auto_podf + 1); +} + +static u32 get_ddrc_clk(void) +{ + u32 reg, freq; + enum root_post_div post_div; + + reg = readl(&ccm_reg->root[DRAM_CLK_ROOT].target_root); + if (reg & CLK_ROOT_MUX_MASK) + /* DRAM_ALT_CLK_ROOT */ + freq = get_root_clk(DRAM_ALT_CLK_ROOT); + else + /* PLL_DRAM_MAIN_1066M_CLK */ + freq = mxc_get_pll_derive(PLL_DDR, PLL_DRAM_MAIN_1066M_CLK); + + post_div = reg & DRAM_CLK_ROOT_POST_DIV_MASK; + + return freq / (post_div + 1) / 2; +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_ARM_CLK: + return get_root_clk(ARM_A7_CLK_ROOT); + case MXC_AXI_CLK: + return get_root_clk(MAIN_AXI_CLK_ROOT); + case MXC_AHB_CLK: + return get_root_clk(AHB_CLK_ROOT); + case MXC_IPG_CLK: + return get_ipg_clk(); + case MXC_I2C_CLK: + return get_root_clk(I2C1_CLK_ROOT); + case MXC_UART_CLK: + return get_root_clk(UART1_CLK_ROOT); + case MXC_CSPI_CLK: + return get_root_clk(ECSPI1_CLK_ROOT); + case MXC_DDR_CLK: + return get_ddrc_clk(); + case MXC_ESDHC_CLK: + return get_root_clk(USDHC1_CLK_ROOT); + case MXC_ESDHC2_CLK: + return get_root_clk(USDHC2_CLK_ROOT); + case MXC_ESDHC3_CLK: + return get_root_clk(USDHC3_CLK_ROOT); + default: + printf("Unsupported mxc_clock %d\n", clk); + break; + } + + return 0; +} + +#ifdef CONFIG_SYS_I2C_MXC +/* i2c_num can be 0 - 3 */ +int enable_i2c_clk(bool enable, unsigned int i2c_num) +{ + u32 target; + + if (i2c_num >= 4) + return -EINVAL; + + if (enable) { + clock_enable(CCGR_I2C1 + i2c_num, 0); + + /* Set i2c root clock to PLL_SYS_MAIN_120M_CLK */ + + target = CLK_ROOT_ON | I2C1_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(I2C1_CLK_ROOT + i2c_num, target); + + clock_enable(CCGR_I2C1 + i2c_num, 1); + } else { + clock_enable(CCGR_I2C1 + i2c_num, 0); + } + + return 0; +} +#endif + +static void init_clk_esdhc(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_USDHC1, 0); + clock_enable(CCGR_USDHC2, 0); + clock_enable(CCGR_USDHC3, 0); + + /* 196: 392/2 */ + target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(USDHC1_CLK_ROOT, target); + + target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(USDHC2_CLK_ROOT, target); + + target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(USDHC3_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_USDHC1, 1); + clock_enable(CCGR_USDHC2, 1); + clock_enable(CCGR_USDHC3, 1); + +} + +static void init_clk_uart(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_UART1, 0); + clock_enable(CCGR_UART2, 0); + clock_enable(CCGR_UART3, 0); + clock_enable(CCGR_UART4, 0); + clock_enable(CCGR_UART5, 0); + clock_enable(CCGR_UART6, 0); + clock_enable(CCGR_UART7, 0); + + /* 24Mhz */ + target = CLK_ROOT_ON | UART1_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART1_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART2_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART2_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART3_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART3_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART4_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART4_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART5_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART5_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART6_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART6_CLK_ROOT, target); + + target = CLK_ROOT_ON | UART7_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(UART7_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_UART1, 1); + clock_enable(CCGR_UART2, 1); + clock_enable(CCGR_UART3, 1); + clock_enable(CCGR_UART4, 1); + clock_enable(CCGR_UART5, 1); + clock_enable(CCGR_UART6, 1); + clock_enable(CCGR_UART7, 1); + +} + +static void init_clk_weim(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_WEIM, 0); + + /* 120Mhz */ + target = CLK_ROOT_ON | EIM_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(EIM_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_WEIM, 1); +} + +static void init_clk_ecspi(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_ECSPI1, 0); + clock_enable(CCGR_ECSPI2, 0); + clock_enable(CCGR_ECSPI3, 0); + clock_enable(CCGR_ECSPI4, 0); + + /* 60Mhz: 240/4 */ + target = CLK_ROOT_ON | ECSPI1_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ECSPI1_CLK_ROOT, target); + + target = CLK_ROOT_ON | ECSPI2_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ECSPI2_CLK_ROOT, target); + + target = CLK_ROOT_ON | ECSPI3_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ECSPI3_CLK_ROOT, target); + + target = CLK_ROOT_ON | ECSPI4_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ECSPI4_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_ECSPI1, 1); + clock_enable(CCGR_ECSPI2, 1); + clock_enable(CCGR_ECSPI3, 1); + clock_enable(CCGR_ECSPI4, 1); +} + +static void init_clk_wdog(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_WDOG1, 0); + clock_enable(CCGR_WDOG2, 0); + clock_enable(CCGR_WDOG3, 0); + clock_enable(CCGR_WDOG4, 0); + + /* 24Mhz */ + target = CLK_ROOT_ON | WDOG_CLK_ROOT_FROM_OSC_24M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(WDOG_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_WDOG1, 1); + clock_enable(CCGR_WDOG2, 1); + clock_enable(CCGR_WDOG3, 1); + clock_enable(CCGR_WDOG4, 1); + +} + +#ifdef CONFIG_MXC_EPDC +static void init_clk_epdc(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_EPDC, 0); + + /* 24Mhz */ + target = CLK_ROOT_ON | EPDC_PIXEL_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV12); + clock_set_target_val(EPDC_PIXEL_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_EPDC, 1); +} +#endif + +static int enable_pll_enet(void) +{ + u32 reg; + s32 timeout = 100000; + + reg = readl(&ccm_anatop->pll_enet); + /* If pll_enet powered up, no need to set it again */ + if (reg & ANADIG_PLL_ENET_PWDN_MASK) { + reg &= ~ANADIG_PLL_ENET_PWDN_MASK; + writel(reg, &ccm_anatop->pll_enet); + + while (timeout--) { + if (readl(&ccm_anatop->pll_enet) & ANADIG_PLL_LOCK) + break; + } + + if (timeout <= 0) { + /* If timeout, we set pwdn for pll_enet. */ + reg |= ANADIG_PLL_ENET_PWDN_MASK; + return -ETIME; + } + } + + /* Clear bypass */ + writel(CCM_ANALOG_PLL_ENET_BYPASS_MASK, &ccm_anatop->pll_enet_clr); + + writel((CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK + | CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK), + &ccm_anatop->pll_enet_set); + + return 0; +} +static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom, + u32 post_div) +{ + u32 reg = 0; + ulong start; + + debug("pll5 div = %d, num = %d, denom = %d\n", + pll_div, pll_num, pll_denom); + + /* Power up PLL5 video and disable its output */ + writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK | + CCM_ANALOG_PLL_VIDEO_CLR_POWERDOWN_MASK | + CCM_ANALOG_PLL_VIDEO_CLR_BYPASS_MASK | + CCM_ANALOG_PLL_VIDEO_CLR_DIV_SELECT_MASK | + CCM_ANALOG_PLL_VIDEO_CLR_POST_DIV_SEL_MASK | + CCM_ANALOG_PLL_VIDEO_CLR_TEST_DIV_SELECT_MASK, + &ccm_anatop->pll_video_clr); + + /* Set div, num and denom */ + switch (post_div) { + case 1: + writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | + CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x1) | + CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), + &ccm_anatop->pll_video_set); + break; + case 2: + writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | + CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | + CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), + &ccm_anatop->pll_video_set); + break; + case 3: + writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | + CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | + CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x1), + &ccm_anatop->pll_video_set); + break; + case 4: + writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | + CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | + CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x3), + &ccm_anatop->pll_video_set); + break; + case 0: + default: + writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | + CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x2) | + CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), + &ccm_anatop->pll_video_set); + break; + } + + writel(CCM_ANALOG_PLL_VIDEO_NUM_A(pll_num), + &ccm_anatop->pll_video_num); + + writel(CCM_ANALOG_PLL_VIDEO_DENOM_B(pll_denom), + &ccm_anatop->pll_video_denom); + + /* Wait PLL5 lock */ + start = get_timer(0); /* Get current timestamp */ + + do { + reg = readl(&ccm_anatop->pll_video); + if (reg & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) { + /* Enable PLL out */ + writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK, + &ccm_anatop->pll_video_set); + return 0; + } + } while (get_timer(0) < (start + 10)); /* Wait 10ms */ + + printf("Lock PLL5 timeout\n"); + + return 1; + +} + +int set_clk_qspi(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_QSPI, 0); + + /* 49M: 392/2/4 */ + target = CLK_ROOT_ON | QSPI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(QSPI_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_QSPI, 1); + + return 0; +} + +int set_clk_nand(void) +{ + u32 target; + + /* disable the clock gate first */ + clock_enable(CCGR_RAWNAND, 0); + + enable_pll_enet(); + /* 100: 500/5 */ + target = CLK_ROOT_ON | NAND_CLK_ROOT_FROM_PLL_ENET_MAIN_500M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV5); + clock_set_target_val(NAND_CLK_ROOT, target); + + /* enable the clock gate */ + clock_enable(CCGR_RAWNAND, 1); + + return 0; +} + +void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq) +{ + u32 hck = MXC_HCLK/1000; + u32 min = hck * 27; + u32 max = hck * 54; + u32 temp, best = 0; + u32 i, j, pred = 1, postd = 1; + u32 pll_div, pll_num, pll_denom, post_div = 0; + u32 target; + + debug("mxs_set_lcdclk, freq = %d\n", freq); + + clock_enable(CCGR_LCDIF, 0); + + temp = (freq * 8 * 8); + if (temp < min) { + + for (i = 1; i <= 4; i++) { + if ((temp * (1 << i)) > min) { + post_div = i; + freq = (freq * (1 << i)); + break; + } + } + + if (5 == i) { + printf("Fail to set rate to %dkhz", freq); + return; + } + } + + for (i = 1; i <= 8; i++) { + for (j = 1; j <= 8; j++) { + temp = freq * i * j; + if (temp > max || temp < min) + continue; + + if (best == 0 || temp < best) { + best = temp; + pred = i; + postd = j; + } + } + } + + if (best == 0) { + printf("Fail to set rate to %dkhz", freq); + return; + } + + debug("best %d, pred = %d, postd = %d\n", best, pred, postd); + + pll_div = best / hck; + pll_denom = 1000000; + pll_num = (best - hck * pll_div) * pll_denom / hck; + + if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) + return; + + target = CLK_ROOT_ON | LCDIF_PIXEL_CLK_ROOT_FROM_PLL_VIDEO_MAIN_CLK | + CLK_ROOT_PRE_DIV((pred - 1)) | CLK_ROOT_POST_DIV((postd - 1)); + clock_set_target_val(LCDIF_PIXEL_CLK_ROOT, target); + + clock_enable(CCGR_LCDIF, 1); +} + +#ifdef CONFIG_FEC_MXC +int set_clk_enet(enum enet_freq type) +{ + u32 target; + int ret; + u32 enet1_ref, enet2_ref; + + /* disable the clock first */ + clock_enable(CCGR_ENET1, 0); + clock_enable(CCGR_ENET2, 0); + + switch (type) { + case ENET_125MHz: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK; + enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK; + break; + case ENET_50MHz: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK; + enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK; + break; + case ENET_25MHz: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; + enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; + break; + default: + return -EINVAL; + } + + ret = enable_pll_enet(); + if (ret != 0) + return ret; + + /* set enet axi clock 196M: 392/2 */ + target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); + clock_set_target_val(ENET_AXI_CLK_ROOT, target); + + target = CLK_ROOT_ON | enet1_ref | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(ENET1_REF_CLK_ROOT, target); + + target = CLK_ROOT_ON | ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ENET1_TIME_CLK_ROOT, target); + + target = CLK_ROOT_ON | enet2_ref | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(ENET2_REF_CLK_ROOT, target); + + target = CLK_ROOT_ON | ENET2_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ENET2_TIME_CLK_ROOT, target); + +#ifdef CONFIG_FEC_MXC_25M_REF_CLK + target = CLK_ROOT_ON | ENET_PHY_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(ENET_PHY_REF_CLK_ROOT, target); +#endif + /* enable clock */ + clock_enable(CCGR_ENET1, 1); + clock_enable(CCGR_ENET2, 1); + + return 0; +} +#endif + +/* Configure PLL/PFD freq */ +void clock_init(void) +{ + /* Rom has enabled PLL_ARM, PLL_DDR, PLL_SYS, PLL_ENET + * In u-boot, we have to: + * 1. Configure PFD3- PFD7 for freq we needed in u-boot + * 2. Set clock root for peripherals (ip channel) used in u-boot but without set rate + * interface. The clocks for these peripherals are enabled after this intialization. + * 3. Other peripherals with set clock rate interface does not be set in this function. + */ + + u32 reg; + + /* + * Configure PFD4 to 392M + * 480M * 18 / 0x16 = 392M + */ + reg = readl(&ccm_anatop->pfd_480b); + + reg &= ~(ANATOP_PFD480B_PFD4_FRAC_MASK | + CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK); + reg |= ANATOP_PFD480B_PFD4_FRAC_392M_VAL; + + writel(reg, &ccm_anatop->pfd_480b); + + init_clk_esdhc(); + init_clk_uart(); + init_clk_weim(); + init_clk_ecspi(); + init_clk_wdog(); +#ifdef CONFIG_MXC_EPDC + init_clk_epdc(); +#endif + + enable_usboh3_clk(1); + + clock_enable(CCGR_SNVS, 1); + +#ifdef CONFIG_NAND_MXS + clock_enable(CCGR_RAWNAND, 1); +#endif +} + +#ifdef CONFIG_SECURE_BOOT +void hab_caam_clock_enable(unsigned char enable) +{ + if (enable) + clock_enable(CCGR_CAAM, 1); + else + clock_enable(CCGR_CAAM, 0); +} +#endif + +#ifdef CONFIG_MXC_EPDC +void epdc_clock_enable(void) +{ + clock_enable(CCGR_EPDC, 1); +} +void epdc_clock_disable(void) +{ + clock_enable(CCGR_EPDC, 0); +} +#endif + +/* + * Dump some core clockes. + */ +int do_mx7_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + u32 freq; + freq = decode_pll(PLL_CORE, MXC_HCLK); + printf("PLL_CORE %8d MHz\n", freq / 1000000); + freq = decode_pll(PLL_SYS, MXC_HCLK); + printf("PLL_SYS %8d MHz\n", freq / 1000000); + freq = decode_pll(PLL_ENET, MXC_HCLK); + printf("PLL_NET %8d MHz\n", freq / 1000000); + + printf("\n"); + + printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); + printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); +#ifdef CONFIG_MXC_SPI + printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); +#endif + printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); + printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000); + printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); + printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); + printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); + printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); + + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx7_showclocks, + "display clocks", + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx7/clock_slice.c b/u-boot-imx/arch/arm/cpu/armv7/mx7/clock_slice.c new file mode 100644 index 0000000..ad5d504 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx7/clock_slice.c
@@ -0,0 +1,757 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * Author: + * Peng Fan <Peng.Fan@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + +static struct clk_root_map root_array[] = { + {ARM_A7_CLK_ROOT, CCM_CORE_CHANNEL, + {OSC_24M_CLK, PLL_ARM_MAIN_800M_CLK, PLL_ENET_MAIN_500M_CLK, + PLL_DRAM_MAIN_1066M_CLK, PLL_SYS_MAIN_480M_CLK, + PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {ARM_M4_CLK_ROOT, CCM_BUS_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_250M_CLK, + PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {ARM_M0_CLK_ROOT, CCM_BUS_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_125M_CLK, + PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {MAIN_AXI_CLK_ROOT, CCM_BUS_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD5_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD7_CLK} + }, + {DISP_AXI_CLK_ROOT, CCM_BUS_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK, + PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} + }, + {ENET_AXI_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK} + }, + {NAND_USDHC_BUS_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_PFD6_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_AUDIO_MAIN_CLK} + }, + {AHB_CLK_ROOT, CCM_AHB_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_PFD0_392M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, + PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} + }, + {DRAM_PHYM_CLK_ROOT, CCM_DRAM_PHYM_CHANNEL, + {PLL_DRAM_MAIN_1066M_CLK, DRAM_PHYM_ALT_CLK_ROOT} + }, + {DRAM_CLK_ROOT, CCM_DRAM_CHANNEL, + {PLL_DRAM_MAIN_1066M_CLK, DRAM_ALT_CLK_ROOT} + }, + {DRAM_PHYM_ALT_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD7_CLK, + PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} + }, + {DRAM_ALT_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_ENET_MAIN_250M_CLK, + PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_SYS_PFD2_270M_CLK} + }, + {USB_HSIC_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_USB_MAIN_480M_CLK, + PLL_SYS_PFD3_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD5_CLK, + PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} + }, + {PCIE_CTRL_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, + PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_SYS_PFD6_CLK} + }, + {PCIE_PHY_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_ENET_MAIN_500M_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, + EXT_CLK_4, PLL_SYS_PFD0_392M_CLK} + }, + {EPDC_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD6_CLK, + PLL_SYS_PFD7_CLK, PLL_VIDEO_MAIN_CLK} + }, + {LCDIF_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_DRAM_MAIN_533M_CLK, + EXT_CLK_3, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {MIPI_DSI_EXTSER_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD3_CLK, + PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} + }, + {MIPI_CSI_WARP_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD3_CLK, + PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} + }, + {MIPI_DPHY_REF_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_PFD5_CLK, REF_1M_CLK, EXT_CLK_2, + PLL_VIDEO_MAIN_CLK, EXT_CLK_3} + }, + {SAI1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} + }, + {SAI2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} + }, + {SAI3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} + }, + {SPDIF_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} + }, + {ENET1_REF_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, EXT_CLK_4} + }, + {ENET1_TIME_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, + EXT_CLK_4, PLL_VIDEO_MAIN_CLK} + }, + {ENET2_REF_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, EXT_CLK_4} + }, + {ENET2_TIME_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, + EXT_CLK_4, PLL_VIDEO_MAIN_CLK} + }, + {ENET_PHY_REF_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_25M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_ENET_MAIN_125M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD3_CLK} + }, + {EIM_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_SYS_PFD3_CLK, + PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK} + }, + {NAND_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_PFD0_392M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {QSPI_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD3_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} + }, + {USDHC1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} + }, + {USDHC2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} + }, + {USDHC3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} + }, + {CAN1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, + EXT_CLK_1, EXT_CLK_4} + }, + {CAN2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, + EXT_CLK_1, EXT_CLK_3} + }, + {I2C1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, + PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} + }, + {I2C2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, + PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} + }, + {I2C3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, + PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} + }, + {I2C4_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, + PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} + }, + {UART1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_4, PLL_USB_MAIN_480M_CLK} + }, + {UART2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_3, PLL_USB_MAIN_480M_CLK} + }, + {UART3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_4, PLL_USB_MAIN_480M_CLK} + }, + {UART4_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_3, PLL_USB_MAIN_480M_CLK} + }, + {UART5_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_4, PLL_USB_MAIN_480M_CLK} + }, + {UART6_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_3, PLL_USB_MAIN_480M_CLK} + }, + {UART7_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, + EXT_CLK_4, PLL_USB_MAIN_480M_CLK} + }, + {ECSPI1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} + }, + {ECSPI2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} + }, + {ECSPI3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} + }, + {ECSPI4_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, + PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, + PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} + }, + {PWM1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {PWM2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {PWM3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {PWM4_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {FLEXTIMER1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {FLEXTIMER2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, + REF_1M_CLK, PLL_VIDEO_MAIN_CLK} + }, + {SIM1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} + }, + {SIM2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_VIDEO_MAIN_CLK, + PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} + }, + {GPT1_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, + PLL_AUDIO_MAIN_CLK, EXT_CLK_1} + }, + {GPT2_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, + PLL_AUDIO_MAIN_CLK, EXT_CLK_2} + }, + {GPT3_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, + PLL_AUDIO_MAIN_CLK, EXT_CLK_3} + }, + {GPT4_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, + PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, + PLL_AUDIO_MAIN_CLK, EXT_CLK_4} + }, + {TRACE_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, + EXT_CLK_1, EXT_CLK_3} + }, + {WDOG_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, + REF_1M_CLK, PLL_SYS_PFD1_166M_CLK} + }, + {CSI_MCLK_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {AUDIO_MCLK_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, + PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} + }, + {WRCLK_CLK_ROOT, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_DRAM_MAIN_533M_CLK, + PLL_USB_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_270M_CLK, + PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD7_CLK} + }, + {IPP_DO_CLKO1, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, + PLL_SYS_PFD0_196M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, + PLL_DRAM_MAIN_533M_CLK, REF_1M_CLK} + }, + {IPP_DO_CLKO2, CCM_IP_CHANNEL, + {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD0_392M_CLK, + PLL_SYS_PFD1_166M_CLK, PLL_SYS_PFD4_CLK, PLL_AUDIO_MAIN_CLK, + PLL_VIDEO_MAIN_CLK, OSC_32K_CLK} + }, +}; + +/* select which entry of root_array */ +static int select(enum clk_root_index clock_id) +{ + int i, size; + struct clk_root_map *p = root_array; + + size = ARRAY_SIZE(root_array); + + for (i = 0; i < size; i++, p++) { + if (clock_id == p->entry) + return i; + } + + return -EINVAL; +} + +static int src_supported(int entry, enum clk_root_src clock_src) +{ + int i, size; + struct clk_root_map *p = &root_array[entry]; + + if ((p->type == CCM_DRAM_PHYM_CHANNEL) || (p->type == CCM_DRAM_CHANNEL)) + size = 2; + else + size = 8; + + for (i = 0; i < size; i++) { + if (p->src_mux[i] == clock_src) + return i; + } + + return -EINVAL; +} + +/* Set src for clock root slice. */ +int clock_set_src(enum clk_root_index clock_id, enum clk_root_src clock_src) +{ + int root_entry, src_entry; + u32 reg; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + src_entry = src_supported(root_entry, clock_src); + if (src_entry < 0) + return -EINVAL; + + reg = __raw_readl(&imx_ccm->root[clock_id].target_root); + reg &= ~CLK_ROOT_MUX_MASK; + reg |= src_entry << CLK_ROOT_MUX_SHIFT; + __raw_writel(reg, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +/* Get src of a clock root slice. */ +int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src) +{ + u32 val; + int root_entry; + struct clk_root_map *p; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + val &= CLK_ROOT_MUX_MASK; + val >>= CLK_ROOT_MUX_SHIFT; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + *p_clock_src = p->src_mux[val]; + + return 0; +} + +int clock_set_prediv(enum clk_root_index clock_id, enum root_pre_div pre_div) +{ + int root_entry; + struct clk_root_map *p; + u32 reg; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + if ((p->type == CCM_CORE_CHANNEL) || + (p->type == CCM_DRAM_PHYM_CHANNEL) || + (p->type == CCM_DRAM_CHANNEL)) { + if (pre_div != CLK_ROOT_PRE_DIV1) { + printf("Error pre div!\n"); + return -EINVAL; + } + } + + reg = __raw_readl(&imx_ccm->root[clock_id].target_root); + reg &= ~CLK_ROOT_PRE_DIV_MASK; + reg |= pre_div << CLK_ROOT_PRE_DIV_SHIFT; + __raw_writel(reg, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div) +{ + u32 val; + int root_entry; + struct clk_root_map *p; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + if ((p->type == CCM_CORE_CHANNEL) || + (p->type == CCM_DRAM_PHYM_CHANNEL) || + (p->type == CCM_DRAM_CHANNEL)) { + *pre_div = 0; + return 0; + } + + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + val &= CLK_ROOT_PRE_DIV_MASK; + val >>= CLK_ROOT_PRE_DIV_SHIFT; + + *pre_div = val; + + return 0; +} + +int clock_set_postdiv(enum clk_root_index clock_id, enum root_post_div div) +{ + u32 reg; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + if (clock_id == DRAM_PHYM_CLK_ROOT) { + if (div != CLK_ROOT_POST_DIV1) { + printf("Error post div!\n"); + return -EINVAL; + } + } + + /* Only 3 bit post div. */ + if ((clock_id == DRAM_CLK_ROOT) && (div > CLK_ROOT_POST_DIV7)) { + printf("Error post div!\n"); + return -EINVAL; + } + + reg = __raw_readl(&imx_ccm->root[clock_id].target_root); + reg &= ~CLK_ROOT_POST_DIV_MASK; + reg |= div << CLK_ROOT_POST_DIV_SHIFT; + __raw_writel(reg, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +int clock_get_postdiv(enum clk_root_index clock_id, enum root_post_div *div) +{ + u32 val; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + if (clock_id == DRAM_PHYM_CLK_ROOT) { + *div = 0; + return 0; + } + + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + if (clock_id == DRAM_CLK_ROOT) + val &= DRAM_CLK_ROOT_POST_DIV_MASK; + else + val &= CLK_ROOT_POST_DIV_MASK; + val >>= CLK_ROOT_POST_DIV_SHIFT; + + *div = val; + + return 0; +} + +int clock_set_autopostdiv(enum clk_root_index clock_id, enum root_auto_div div, + int auto_en) +{ + u32 val; + int root_entry; + struct clk_root_map *p; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { + printf("Auto postdiv not supported.!\n"); + return -EINVAL; + } + + /* + * Each time only one filed can be changed, no use target_root_set. + */ + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + val &= ~CLK_ROOT_AUTO_DIV_MASK; + val |= (div << CLK_ROOT_AUTO_DIV_SHIFT); + + if (auto_en) + val |= CLK_ROOT_AUTO_EN; + else + val &= ~CLK_ROOT_AUTO_EN; + + __raw_writel(val, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +int clock_get_autopostdiv(enum clk_root_index clock_id, enum root_auto_div *div, + int *auto_en) +{ + u32 val; + int root_entry; + struct clk_root_map *p; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + /* + * Only bus/ahb channel supports auto div. + * If unsupported, just set auto_en and div with 0. + */ + if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { + *auto_en = 0; + *div = 0; + return 0; + } + + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + if ((val & CLK_ROOT_AUTO_EN_MASK) == 0) + *auto_en = 0; + else + *auto_en = 1; + + val &= CLK_ROOT_AUTO_DIV_MASK; + val >>= CLK_ROOT_AUTO_DIV_SHIFT; + + *div = val; + + return 0; +} + +int clock_get_target_val(enum clk_root_index clock_id, u32 *val) +{ + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + *val = __raw_readl(&imx_ccm->root[clock_id].target_root); + + return 0; +} + +int clock_set_target_val(enum clk_root_index clock_id, u32 val) +{ + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + __raw_writel(val, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +/* Auto_div and auto_en is ignored, they are rarely used. */ +int clock_root_cfg(enum clk_root_index clock_id, enum root_pre_div pre_div, + enum root_post_div post_div, enum clk_root_src clock_src) +{ + u32 val; + int root_entry, src_entry; + struct clk_root_map *p; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + if ((p->type == CCM_CORE_CHANNEL) || + (p->type == CCM_DRAM_PHYM_CHANNEL) || + (p->type == CCM_DRAM_CHANNEL)) { + if (pre_div != CLK_ROOT_PRE_DIV1) { + printf("Error pre div!\n"); + return -EINVAL; + } + } + + /* Only 3 bit post div. */ + if (p->type == CCM_DRAM_CHANNEL) { + if (post_div > CLK_ROOT_POST_DIV7) { + printf("Error post div!\n"); + return -EINVAL; + } + } + + if (p->type == CCM_DRAM_PHYM_CHANNEL) { + if (post_div != CLK_ROOT_POST_DIV1) { + printf("Error post div!\n"); + return -EINVAL; + } + } + + src_entry = src_supported(root_entry, clock_src); + if (src_entry < 0) + return -EINVAL; + + val = CLK_ROOT_ON | pre_div << CLK_ROOT_PRE_DIV_SHIFT | + post_div << CLK_ROOT_POST_DIV_SHIFT | + src_entry << CLK_ROOT_MUX_SHIFT; + + __raw_writel(val, &imx_ccm->root[clock_id].target_root); + + return 0; +} + +int clock_root_enabled(enum clk_root_index clock_id) +{ + u32 val; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + /* + * No enable bit for DRAM controller and PHY. Just return enabled. + */ + if ((clock_id == DRAM_PHYM_CLK_ROOT) || (clock_id == DRAM_CLK_ROOT)) + return 1; + + val = __raw_readl(&imx_ccm->root[clock_id].target_root); + + return (val & CLK_ROOT_ENABLE_MASK) ? 1 : 0; +} + +/* CCGR gate operation */ +int clock_enable(enum clk_ccgr_index index, bool enable) +{ + if (index >= CCGR_MAX) + return -EINVAL; + + if (enable) + __raw_writel(CCM_CLK_ON_MSK, + &imx_ccm->ccgr_array[index].ccgr_set); + else + __raw_writel(CCM_CLK_ON_MSK, + &imx_ccm->ccgr_array[index].ccgr_clr); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx7/hab.c b/u-boot-imx/arch/arm/cpu/armv7/mx7/hab.c new file mode 100644 index 0000000..43b06bd --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx7/hab.c
@@ -0,0 +1,277 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/hab.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> + +/* -------- start of HAB API updates ------------*/ +#define hab_rvt_report_event_p \ +( \ + ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT) \ +) + +#define hab_rvt_report_status_p \ +( \ + ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS) \ +) + +#define hab_rvt_authenticate_image_p \ +( \ + ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE) \ +) + +#define hab_rvt_entry_p \ +( \ + ((hab_rvt_entry_t *)HAB_RVT_ENTRY) \ +) + +#define hab_rvt_exit_p \ +( \ + ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ +) + +#define IVT_SIZE 0x20 +#define ALIGN_SIZE 0x1000 +#define CSF_PAD_SIZE 0x2000 + +/* + * +------------+ 0x0 (DDR_UIMAGE_START) - + * | Header | | + * +------------+ 0x40 | + * | | | + * | | | + * | | | + * | | | + * | Image Data | | + * . | | + * . | > Stuff to be authenticated ----+ + * . | | | + * | | | | + * | | | | + * +------------+ | | + * | | | | + * | Fill Data | | | + * | | | | + * +------------+ Align to ALIGN_SIZE | | + * | IVT | | | + * +------------+ + IVT_SIZE - | + * | | | + * | CSF DATA | <---------------------------------------------------------+ + * | | + * +------------+ + * | | + * | Fill Data | + * | | + * +------------+ + CSF_PAD_SIZE + */ + +bool is_hab_enabled(void) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[1]; + struct fuse_bank1_regs *fuse = + (struct fuse_bank1_regs *)bank->fuse_regs; + uint32_t reg = readl(&fuse->cfg0); + + return (reg & 0x2000000) == 0x2000000; +} + +void display_event(uint8_t *event_data, size_t bytes) +{ + uint32_t i; + + if (!(event_data && bytes > 0)) + return; + + for (i = 0; i < bytes; i++) { + if (i == 0) + printf("\t0x%02x", event_data[i]); + else if ((i % 8) == 0) + printf("\n\t0x%02x", event_data[i]); + else + printf(" 0x%02x", event_data[i]); + } +} + +int get_hab_status(void) +{ + uint32_t index = 0; /* Loop index */ + uint8_t event_data[128]; /* Event data buffer */ + size_t bytes = sizeof(event_data); /* Event size in bytes */ + enum hab_config config = 0; + enum hab_state state = 0; + hab_rvt_report_event_t *hab_rvt_report_event; + hab_rvt_report_status_t *hab_rvt_report_status; + + if (is_hab_enabled()) + puts("\nSecure boot enabled\n"); + else + puts("\nSecure boot disabled\n"); + + hab_rvt_report_event = hab_rvt_report_event_p; + hab_rvt_report_status = hab_rvt_report_status_p; + + /* Check HAB status */ + if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) { + printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", + config, state); + + /* Display HAB Error events */ + while (hab_rvt_report_event(HAB_FAILURE, index, event_data, + &bytes) == HAB_SUCCESS) { + puts("\n"); + printf("--------- HAB Event %d -----------------\n", + index + 1); + puts("event data:\n"); + display_event(event_data, bytes); + puts("\n"); + bytes = sizeof(event_data); + index++; + } + } + /* Display message if no HAB events are found */ + else { + printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", + config, state); + puts("No HAB Events Found!\n\n"); + } + return 0; +} + +#ifdef DEBUG_AUTHENTICATE_IMAGE +void dump_mem(uint32_t addr, int size) +{ + int i; + + for (i = 0; i < size; i += 4) { + if (i != 0) { + if (i % 16 == 0) + printf("\n"); + else + printf(" "); + } + + printf("0x%08x", *(uint32_t *)addr); + addr += 4; + } + + printf("\n"); + + return; +} +#endif + +uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) +{ + uint32_t load_addr = 0; + size_t bytes; + ptrdiff_t ivt_offset = 0; + int result = 0; + ulong start; + hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; + hab_rvt_entry_t *hab_rvt_entry; + hab_rvt_exit_t *hab_rvt_exit; + + hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; + hab_rvt_entry = hab_rvt_entry_p; + hab_rvt_exit = hab_rvt_exit_p; + + if (is_hab_enabled()) { + printf("\nAuthenticate uImage from DDR location 0x%x...\n", + ddr_start); + + hab_caam_clock_enable(1); + + if (hab_rvt_entry() == HAB_SUCCESS) { + /* If not already aligned, Align to ALIGN_SIZE */ + ivt_offset = (image_size + ALIGN_SIZE - 1) & + ~(ALIGN_SIZE - 1); + + start = ddr_start; + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; + +#ifdef DEBUG_AUTHENTICATE_IMAGE + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", + ivt_offset, ddr_start + ivt_offset); + printf("Dumping IVT\n"); + dump_mem(ddr_start + ivt_offset, 0x20); + + printf("Dumping CSF Header\n"); + dump_mem(ddr_start + ivt_offset + 0x20, 0x40); + + get_hab_status(); + + printf("\nCalling authenticate_image in ROM\n"); + printf("\tivt_offset = 0x%x\n\tstart = 0x%08x" + "\n\tbytes = 0x%x\n", ivt_offset, start, bytes); +#endif + load_addr = (uint32_t)hab_rvt_authenticate_image( + HAB_CID_UBOOT, + ivt_offset, (void **)&start, + (size_t *)&bytes, NULL); + if (hab_rvt_exit() != HAB_SUCCESS) { + printf("hab exit function fail\n"); + load_addr = 0; + } + } else + printf("hab entry function fail\n"); + + hab_caam_clock_enable(0); + + get_hab_status(); + } + + if ((!is_hab_enabled()) || (load_addr != 0)) + result = 1; + + return result; +} + +int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if ((argc != 1)) { + cmd_usage(cmdtp); + return 1; + } + + get_hab_status(); + + return 0; +} + +static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong addr, ivt_offset; + int rcode = 0; + + if (argc < 3) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + ivt_offset = simple_strtoul(argv[2], NULL, 16); + + rcode = authenticate_image(addr, ivt_offset); + + return rcode; +} + +U_BOOT_CMD( + hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, + "display HAB status", + "" + ); + +U_BOOT_CMD( + hab_auth_img, 3, 1, do_authenticate_image, + "authenticate image via HAB", + "addr ivt_offset\n" + "addr - image hex address\n" + "ivt_offset - hex offset of IVT in the image" + );
diff --git a/u-boot-imx/arch/arm/cpu/armv7/mx7/soc.c b/u-boot-imx/arch/arm/cpu/armv7/mx7/soc.c new file mode 100644 index 0000000..e30493e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/mx7/soc.c
@@ -0,0 +1,451 @@ +/* + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/armv7.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/imx-common/boot_mode.h> +#include <asm/imx-common/dma.h> +#include <stdbool.h> +#include <asm/arch/crm_regs.h> +#include <dm.h> +#include <imx_thermal.h> +#include <mxsfb.h> +#ifdef CONFIG_FSL_FASTBOOT +#ifdef CONFIG_ANDROID_RECOVERY +#include <recovery.h> +#endif +#endif + +struct src *src_reg = (struct src *)SRC_BASE_ADDR; + +#if defined(CONFIG_IMX_THERMAL) +static const struct imx_thermal_plat imx7_thermal_plat = { + .regs = (void *)ANATOP_BASE_ADDR, + .fuse_bank = 3, + .fuse_word = 3, +}; + +U_BOOT_DEVICE(imx7_thermal) = { + .name = "imx_thermal", + .platdata = &imx7_thermal_plat, +}; +#endif + +u32 get_cpu_rev(void) +{ + struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) + ANATOP_BASE_ADDR; + u32 reg = readl(&ccm_anatop->digprog); + u32 type = (reg >> 16) & 0xff; + + reg &= 0xff; + return (type << 12) | reg; +} + +#ifdef CONFIG_REVISION_TAG +u32 __weak get_board_rev(void) +{ + u32 cpurev = get_cpu_rev(); + u32 type = ((cpurev >> 12) & 0xff); + + if (type == MXC_CPU_MX7D) + cpurev = (MXC_CPU_MX7D) << 12 | (cpurev & 0xFFF); + + return cpurev; +} +#endif + +static void init_aips(void) +{ + struct aipstz_regs *aips1, *aips2, *aips3; + + aips1 = (struct aipstz_regs *)AIPS1_ON_BASE_ADDR; + aips2 = (struct aipstz_regs *)AIPS2_ON_BASE_ADDR; + aips3 = (struct aipstz_regs *)AIPS3_ON_BASE_ADDR; + + /* + * Set all MPROTx to be non-bufferable, trusted for R/W, + * not forced to user-mode. + */ + writel(0x77777777, &aips1->mprot0); + writel(0x77777777, &aips1->mprot1); + writel(0x77777777, &aips2->mprot0); + writel(0x77777777, &aips2->mprot1); + writel(0x77777777, &aips3->mprot0); + writel(0x77777777, &aips3->mprot1); + + /* + * Set all OPACRx to be non-bufferable, not require + * supervisor privilege level for access,allow for + * write access and untrusted master access. + */ + writel(0x00000000, &aips1->opacr0); + writel(0x00000000, &aips1->opacr1); + writel(0x00000000, &aips1->opacr2); + writel(0x00000000, &aips1->opacr3); + writel(0x00000000, &aips1->opacr4); + writel(0x00000000, &aips2->opacr0); + writel(0x00000000, &aips2->opacr1); + writel(0x00000000, &aips2->opacr2); + writel(0x00000000, &aips2->opacr3); + writel(0x00000000, &aips2->opacr4); + writel(0x00000000, &aips3->opacr0); + writel(0x00000000, &aips3->opacr1); + writel(0x00000000, &aips3->opacr2); + writel(0x00000000, &aips3->opacr3); + writel(0x00000000, &aips3->opacr4); +} + +static void imx_set_pcie_phy_power_down(void) +{ + /* TODO */ +} + +static void imx_set_wdog_powerdown(bool enable) +{ + struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; + struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; + struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; + struct wdog_regs *wdog4 = (struct wdog_regs *)WDOG4_BASE_ADDR; + + writew(enable, &wdog1->wmcr); + writew(enable, &wdog2->wmcr); + writew(enable, &wdog3->wmcr); + writew(enable, &wdog4->wmcr); +} + +static void set_epdc_qos(void) +{ +#define REGS_QOS_BASE QOSC_IPS_BASE_ADDR +#define REGS_QOS_EPDC (QOSC_IPS_BASE_ADDR + 0x3400) +#define REGS_QOS_PXP0 (QOSC_IPS_BASE_ADDR + 0x2C00) +#define REGS_QOS_PXP1 (QOSC_IPS_BASE_ADDR + 0x3C00) + + writel(0, REGS_QOS_BASE); /* Disable clkgate & soft_reset */ + writel(0, REGS_QOS_BASE + 0x60); /* Enable all masters */ + writel(0, REGS_QOS_EPDC); /* Disable clkgate & soft_reset */ + writel(0, REGS_QOS_PXP0); /* Disable clkgate & soft_reset */ + writel(0, REGS_QOS_PXP1); /* Disable clkgate & soft_reset */ + + writel(0x0f020722, REGS_QOS_EPDC + 0xd0); /* WR, init = 7 with red flag */ + writel(0x0f020722, REGS_QOS_EPDC + 0xe0); /* RD, init = 7 with red flag */ + + writel(1, REGS_QOS_PXP0); /* OT_CTRL_EN =1 */ + writel(1, REGS_QOS_PXP1); /* OT_CTRL_EN =1 */ + + writel(0x0f020222, REGS_QOS_PXP0 + 0x50); /* WR, init = 2 with red flag */ + writel(0x0f020222, REGS_QOS_PXP1 + 0x50); /* WR, init = 2 with red flag */ + writel(0x0f020222, REGS_QOS_PXP0 + 0x60); /* rD, init = 2 with red flag */ + writel(0x0f020222, REGS_QOS_PXP1 + 0x60); /* rD, init = 2 with red flag */ + writel(0x0f020422, REGS_QOS_PXP0 + 0x70); /* tOTAL, init = 4 with red flag */ + writel(0x0f020422, REGS_QOS_PXP1 + 0x70); /* TOTAL, init = 4 with red flag */ + + writel(0xe080, IOMUXC_GPR_BASE_ADDR + 0x0034); /* EPDC AW/AR CACHE ENABLE */ +} + +int arch_cpu_init(void) +{ + init_aips(); + + /* Disable PDE bit of WMCR register */ + imx_set_wdog_powerdown(false); + + imx_set_pcie_phy_power_down(); + +#ifdef CONFIG_APBH_DMA + /* Start APBH DMA */ + mxs_dma_init(); +#endif + + set_epdc_qos(); + + return 0; +} + +#ifdef CONFIG_BOARD_POSTCLK_INIT +int board_postclk_init(void) +{ + /* + * We do not need to set LDO_SOC as i.mx6, since LDO_ARM and LDO_SOC + * does not exist. Check "Figure 7-9. i.MX7Dual Power Diagram" + */ + return 0; +} +#endif + +#ifdef CONFIG_SERIAL_TAG +void get_board_serial(struct tag_serialnr *serialnr) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[0]; + struct fuse_bank0_regs *fuse = + (struct fuse_bank0_regs *)bank->fuse_regs; + + serialnr->low = fuse->tester0; + serialnr->high = fuse->tester1; +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) + enum dcache_option option = DCACHE_WRITETHROUGH; +#else + enum dcache_option option = DCACHE_WRITEBACK; +#endif + + /* Avoid random hang when download by usb */ + invalidate_dcache_all(); + + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); + + /* Enable caching on OCRAM and ROM */ + mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, + ROMCP_ARB_END_ADDR, + option); + mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, + IRAM_SIZE, + option); +} +#endif + +#if defined(CONFIG_FEC_MXC) +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[9]; + struct fuse_bank9_regs *fuse = + (struct fuse_bank9_regs *)bank->fuse_regs; + + if (0 == dev_id) { + u32 value = readl(&fuse->mac_addr1); + mac[0] = (value >> 8); + mac[1] = value; + + value = readl(&fuse->mac_addr0); + mac[2] = value >> 24; + mac[3] = value >> 16; + mac[4] = value >> 8; + mac[5] = value; + } else { + u32 value = readl(&fuse->mac_addr2); + mac[0] = value >> 24; + mac[1] = value >> 16; + mac[2] = value >> 8; + mac[3] = value; + + value = readl(&fuse->mac_addr1); + mac[4] = value >> 24; + mac[5] = value >> 16; + } +} +#endif + +int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) +{ + u32 stack, pc; + + if (!boot_private_data) + return 1; + + stack = *(u32 *)boot_private_data; + pc = *(u32 *)(boot_private_data + 4); + + /* Set the stack and pc to M4 bootROM */ + writel(stack, M4_BOOTROM_BASE_ADDR); + writel(pc, M4_BOOTROM_BASE_ADDR + 4); + + /* Enable M4 */ + setbits_le32(&src_reg->m4rcr, 0x00000008); + clrbits_le32(&src_reg->m4rcr, 0x00000001); + + return 0; +} + +int arch_auxiliary_core_check_up(u32 core_id) +{ + uint32_t val; + + val = readl(&src_reg->m4rcr); + if (val & 0x00000001) + return 0; /* assert in reset */ + + return 1; +} + +void boot_mode_apply(uint32_t cfg_val) +{ + uint32_t reg; + writel(cfg_val, &src_reg->gpr9); + reg = readl(&src_reg->gpr10); + if (cfg_val) + reg |= 1 << 28; + else + reg &= ~(1 << 28); + writel(reg, &src_reg->gpr10); +} + +void set_wdog_reset(struct wdog_regs *wdog) +{ + u32 reg = readw(&wdog->wcr); + /* + * Output WDOG_B signal to reset external pmic or POR_B decided by + * the board desgin. Without external reset, the peripherals/DDR/ + * PMIC are not reset, that may cause system working abnormal. + */ + reg = readw(&wdog->wcr); + reg |= 1 << 3; + /* + * WDZST bit is write-once only bit. Align this bit in kernel, + * otherwise kernel code will have no chance to set this bit. + */ + reg |= 1 << 0; + writew(reg, &wdog->wcr); +} + +/* + * cfg_val will be used for + * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] + * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0] + * to SBMR1, which will determine the boot device. + */ +const struct boot_mode soc_boot_modes[] = { + {"ecspi1:0", MAKE_CFGVAL(0x00, 0x60, 0x00, 0x00)}, + {"ecspi1:1", MAKE_CFGVAL(0x40, 0x62, 0x00, 0x00)}, + {"ecspi1:2", MAKE_CFGVAL(0x80, 0x64, 0x00, 0x00)}, + {"ecspi1:3", MAKE_CFGVAL(0xc0, 0x66, 0x00, 0x00)}, + + {"weim", MAKE_CFGVAL(0x00, 0x50, 0x00, 0x00)}, + {"qspi1", MAKE_CFGVAL(0x10, 0x40, 0x00, 0x00)}, + /* 4 bit bus width */ + {"usdhc1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, + {"usdhc2", MAKE_CFGVAL(0x10, 0x14, 0x00, 0x00)}, + {"usdhc3", MAKE_CFGVAL(0x10, 0x18, 0x00, 0x00)}, + {"mmc1", MAKE_CFGVAL(0x10, 0x20, 0x00, 0x00)}, + {"mmc2", MAKE_CFGVAL(0x10, 0x24, 0x00, 0x00)}, + {"mmc3", MAKE_CFGVAL(0x10, 0x28, 0x00, 0x00)}, + {NULL, 0}, +}; + +enum boot_device get_boot_device(void) +{ + struct bootrom_sw_info **p = + (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; + + enum boot_device boot_dev = SD1_BOOT; + u8 boot_type = (*p)->boot_dev_type; + u8 boot_instance = (*p)->boot_dev_instance; + + switch (boot_type) { + case BOOT_TYPE_SD: + boot_dev = boot_instance + SD1_BOOT; + break; + case BOOT_TYPE_MMC: + boot_dev = boot_instance + MMC1_BOOT; + break; + case BOOT_TYPE_NAND: + boot_dev = NAND_BOOT; + break; + case BOOT_TYPE_QSPI: + boot_dev = QSPI_BOOT; + break; + case BOOT_TYPE_WEIM: + boot_dev = WEIM_NOR_BOOT; + break; + case BOOT_TYPE_SPINOR: + boot_dev = SPI_NOR_BOOT; + break; + default: + break; + } + + return boot_dev; +} + +void s_init(void) +{ +#if !defined CONFIG_SPL_BUILD + /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ + asm volatile( + "mrc p15, 0, r0, c1, c0, 1\n" + "orr r0, r0, #1 << 6\n" + "mcr p15, 0, r0, c1, c0, 1\n"); +#endif + /* clock configuration. */ + clock_init(); + + return; +} + +void reset_misc(void) +{ +#ifdef CONFIG_VIDEO_MXS + lcdif_power_down(); +#endif +} + +#ifdef CONFIG_FSL_FASTBOOT + +#ifdef CONFIG_ANDROID_RECOVERY +#define ANDROID_RECOVERY_BOOT (1 << 7) +/* + * check if the recovery bit is set by kernel, it can be set by kernel + * issue a command '# reboot recovery' + */ +int recovery_check_and_clean_flag(void) +{ + int flag_set = 0; + u32 reg; + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); + + flag_set = !!(reg & ANDROID_RECOVERY_BOOT); + printf("check_and_clean: reg %x, flag_set %d\n", reg, flag_set); + /* clean it in case looping infinite here.... */ + if (flag_set) { + reg &= ~ANDROID_RECOVERY_BOOT; + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); + } + + return flag_set; +} +#endif /*CONFIG_ANDROID_RECOVERY*/ + +#define ANDROID_FASTBOOT_BOOT (1 << 8) +/* + * check if the recovery bit is set by kernel, it can be set by kernel + * issue a command '# reboot fastboot' + */ +int fastboot_check_and_clean_flag(void) +{ + int flag_set = 0; + u32 reg; + + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR); + + flag_set = !!(reg & ANDROID_FASTBOOT_BOOT); + + /* clean it in case looping infinite here.... */ + if (flag_set) { + reg &= ~ANDROID_FASTBOOT_BOOT; + writel(reg, SNVS_BASE_ADDR + SNVS_LPGPR); + } + + return flag_set; +} + +void fastboot_enable_flag(void) +{ + setbits_le32(SNVS_BASE_ADDR + SNVS_LPGPR, + ANDROID_FASTBOOT_BOOT); +} +#endif /*CONFIG_FSL_FASTBOOT*/
diff --git a/u-boot-imx/arch/arm/cpu/armv7/nonsec_virt.S b/u-boot-imx/arch/arm/cpu/armv7/nonsec_virt.S new file mode 100644 index 0000000..30d81db --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/nonsec_virt.S
@@ -0,0 +1,205 @@ +/* + * code for switching cores into non-secure state and into HYP mode + * + * Copyright (c) 2013 Andre Przywara <andre.przywara@linaro.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> +#include <asm/gic.h> +#include <asm/armv7.h> +#include <asm/proc-armv/ptrace.h> + +.arch_extension sec +.arch_extension virt + + .pushsection ._secure.text, "ax" + + .align 5 +/* the vector table for secure state and HYP mode */ +_monitor_vectors: + .word 0 /* reset */ + .word 0 /* undef */ + adr pc, _secure_monitor + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + +.macro is_cpu_virt_capable tmp + mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1 + and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits + cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT) +.endm + +/* + * secure monitor handler + * U-boot calls this "software interrupt" in start.S + * This is executed on a "smc" instruction, we use a "smc #0" to switch + * to non-secure state. + * r0, r1, r2: passed to the callee + * ip: target PC + */ +_secure_monitor: +#ifdef CONFIG_ARMV7_PSCI + ldr r5, =_psci_vectors @ Switch to the next monitor + mcr p15, 0, r5, c12, c0, 1 + isb + + @ Obtain a secure stack, and configure the PSCI backend + bl psci_arch_init +#endif + + mrc p15, 0, r5, c1, c1, 0 @ read SCR + bic r5, r5, #0x4a @ clear IRQ, EA, nET bits + orr r5, r5, #0x31 @ enable NS, AW, FW bits + @ FIQ preserved for secure mode + mov r6, #SVC_MODE @ default mode is SVC + is_cpu_virt_capable r4 +#ifdef CONFIG_ARMV7_VIRT + orreq r5, r5, #0x100 @ allow HVC instruction + moveq r6, #HYP_MODE @ Enter the kernel as HYP +#endif + + mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set) + isb + + bne 1f + + @ Reset CNTVOFF to 0 before leaving monitor mode + mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1 + ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits + movne r4, #0 + mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero +1: + mov lr, ip + mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F + tst lr, #1 @ Check for Thumb PC + orrne ip, ip, #T_BIT @ Set T if Thumb + orr ip, ip, r6 @ Slot target mode in + msr spsr_cxfs, ip @ Set full SPSR + movs pc, lr @ ERET to non-secure + +ENTRY(_do_nonsec_entry) + mov ip, r0 + mov r0, r1 + mov r1, r2 + mov r2, r3 + smc #0 +ENDPROC(_do_nonsec_entry) + +.macro get_cbar_addr addr +#ifdef CONFIG_ARM_GIC_BASE_ADDRESS + ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS +#else + mrc p15, 4, \addr, c15, c0, 0 @ read CBAR + bfc \addr, #0, #15 @ clear reserved bits +#endif +.endm + +.macro get_gicd_addr addr + get_cbar_addr \addr + add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset +.endm + +.macro get_gicc_addr addr, tmp + get_cbar_addr \addr + is_cpu_virt_capable \tmp + movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 + moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 + add \addr, \addr, \tmp +.endm + +#ifndef CONFIG_ARMV7_PSCI +/* + * Secondary CPUs start here and call the code for the core specific parts + * of the non-secure and HYP mode transition. The GIC distributor specific + * code has already been executed by a C function before. + * Then they go back to wfi and wait to be woken up by the kernel again. + */ +ENTRY(_smp_pen) + cpsid i + cpsid f + + bl _nonsec_init + + adr r0, _smp_pen @ do not use this address again + b smp_waitloop @ wait for IPIs, board specific +ENDPROC(_smp_pen) +#endif + +/* + * Switch a core to non-secure state. + * + * 1. initialize the GIC per-core interface + * 2. allow coprocessor access in non-secure modes + * + * Called from smp_pen by secondary cores and directly by the BSP. + * Do not assume that the stack is available and only use registers + * r0-r3 and r12. + * + * PERIPHBASE is used to get the GIC address. This could be 40 bits long, + * though, but we check this in C before calling this function. + */ +ENTRY(_nonsec_init) + get_gicd_addr r3 + + mvn r1, #0 @ all bits to 1 + str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts + + get_gicc_addr r3, r1 + + mov r1, #3 @ Enable both groups + str r1, [r3, #GICC_CTLR] @ and clear all other bits + mov r1, #0xff + str r1, [r3, #GICC_PMR] @ set priority mask register + + mrc p15, 0, r0, c1, c1, 2 + movw r1, #0x3fff + movt r1, #0x0004 + orr r0, r0, r1 + mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec + +/* The CNTFRQ register of the generic timer needs to be + * programmed in secure state. Some primary bootloaders / firmware + * omit this, so if the frequency is provided in the configuration, + * we do this here instead. + * But first check if we have the generic timer. + */ +#ifdef CONFIG_TIMER_CLK_FREQ + mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 + and r0, r0, #CPUID_ARM_GENTIMER_MASK @ mask arch timer bits + cmp r0, #(1 << CPUID_ARM_GENTIMER_SHIFT) + ldreq r1, =CONFIG_TIMER_CLK_FREQ + mcreq p15, 0, r1, c14, c0, 0 @ write CNTFRQ +#endif + + adr r1, _monitor_vectors + mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors + isb + + mov r0, r3 @ return GICC address + bx lr +ENDPROC(_nonsec_init) + +#ifdef CONFIG_SMP_PEN_ADDR +/* void __weak smp_waitloop(unsigned previous_address); */ +ENTRY(smp_waitloop) + wfi + ldr r1, =CONFIG_SMP_PEN_ADDR @ load start address + ldr r1, [r1] +#ifdef CONFIG_PEN_ADDR_BIG_ENDIAN + rev r1, r1 +#endif + cmp r0, r1 @ make sure we dont execute this code + beq smp_waitloop @ again (due to a spurious wakeup) + mov r0, r1 + b _do_nonsec_entry +ENDPROC(smp_waitloop) +.weak smp_waitloop +#endif + + .popsection
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/Makefile b/u-boot-imx/arch/arm/cpu/armv7/omap-common/Makefile new file mode 100644 index 0000000..f3725b2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/Makefile
@@ -0,0 +1,34 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := reset.o +obj-y += timer.o +obj-y += utils.o + +ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) +obj-y += hwinit-common.o +obj-y += clocks-common.o +obj-y += emif-common.o +obj-y += vc.o +obj-y += abb.o +endif + +ifneq ($(CONFIG_OMAP54XX),) +obj-y += pipe3-phy.o +obj-$(CONFIG_SCSI_AHCI_PLAT) += sata.o +endif + +ifeq ($(CONFIG_SYS_DCACHE_OFF),) +obj-y += omap-cache.o +endif + +ifeq ($(CONFIG_OMAP34XX),) +obj-y += boot-common.o +endif +obj-y += lowlevel_init.o + +obj-y += mem-common.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/abb.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/abb.c new file mode 100644 index 0000000..a0add66 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/abb.c
@@ -0,0 +1,121 @@ +/* + * Adaptive Body Bias programming sequence for OMAP family + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/omap_common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> + +__weak s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb) +{ + return -1; +} + +static void abb_setup_timings(u32 setup) +{ + u32 sys_rate, sr2_cnt, clk_cycles; + + /* + * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a + * transition and must be programmed with the correct time at boot. + * The value programmed into the register is the number of SYS_CLK + * clock cycles that match a given wall time profiled for the ldo. + * This value depends on: + * settling time of ldo in micro-seconds (varies per OMAP family), + * of clock cycles per SYS_CLK period (varies per OMAP family), + * the SYS_CLK frequency in MHz (varies per board) + * The formula is: + * + * ldo settling time (in micro-seconds) + * SR2_WTCNT_VALUE = ------------------------------------------ + * (# system clock cycles) * (sys_clk period) + * + * Put another way: + * + * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate)) + * + * To avoid dividing by zero multiply both "# clock cycles" and + * "settling time" by 10 such that the final result is the one we want. + */ + + /* calculate SR2_WTCNT_VALUE */ + sys_rate = DIV_ROUND_CLOSEST(V_OSCK, 1000000); + clk_cycles = DIV_ROUND_CLOSEST(OMAP_ABB_CLOCK_CYCLES * 10, sys_rate); + sr2_cnt = DIV_ROUND_CLOSEST(OMAP_ABB_SETTLING_TIME * 10, clk_cycles); + + setbits_le32(setup, + sr2_cnt << (ffs(OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK) - 1)); +} + +void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control, + u32 txdone, u32 txdone_mask, u32 opp) +{ + u32 abb_type_mask, opp_sel_mask; + + /* sanity check */ + if (!setup || !control || !txdone) + return; + + /* setup ABB only in case of Fast or Slow OPP */ + switch (opp) { + case OMAP_ABB_FAST_OPP: + abb_type_mask = OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK; + opp_sel_mask = OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK; + break; + case OMAP_ABB_SLOW_OPP: + abb_type_mask = OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK; + opp_sel_mask = OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK; + break; + default: + return; + } + + /* + * For some OMAP silicons additional setup for LDOVBB register is + * required. This is determined by data retrieved from corresponding + * OPP EFUSE register. Data, which is retrieved from EFUSE - is + * ABB enable/disable flag and VSET value, which must be copied + * to LDOVBB register. If function call fails - return quietly, + * it means no ABB is required for such silicon. + * + * For silicons, which don't require LDOVBB setup "fuse" and + * "ldovbb" offsets are not defined. ABB will be initialized in + * the common way for them. + */ + if (fuse && ldovbb) { + if (abb_setup_ldovbb(fuse, ldovbb)) + return; + } + + /* clear ABB registers */ + writel(0, setup); + writel(0, control); + + /* configure timings, based on oscillator value */ + abb_setup_timings(setup); + + /* clear pending interrupts before setup */ + setbits_le32(txdone, txdone_mask); + + /* select ABB type */ + setbits_le32(setup, abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK); + + /* initiate ABB ldo change */ + setbits_le32(control, opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK); + + /* wait until transition complete */ + if (!wait_on_value(txdone_mask, txdone_mask, (void *)txdone, LDELAY)) + puts("Error: ABB txdone is not set\n"); + + /* clear ABB tranxdone */ + setbits_le32(txdone, txdone_mask); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/boot-common.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/boot-common.c new file mode 100644 index 0000000..17500f2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -0,0 +1,164 @@ +/* + * boot-common.c + * + * Common bootmode functions for omap based boards + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <ahci.h> +#include <spl.h> +#include <asm/omap_common.h> +#include <asm/arch/omap.h> +#include <asm/arch/mmc_host_def.h> +#include <asm/arch/sys_proto.h> +#include <watchdog.h> +#include <scsi.h> + +DECLARE_GLOBAL_DATA_PTR; + +void save_omap_boot_params(void) +{ + u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS); + u8 boot_device; + u32 dev_desc, dev_data; + + if ((rom_params < NON_SECURE_SRAM_START) || + (rom_params > NON_SECURE_SRAM_END)) + return; + + /* + * rom_params can be type casted to omap_boot_parameters and + * used. But it not correct to assume that romcode structure + * encoding would be same as u-boot. So use the defined offsets. + */ + boot_device = *((u8 *)(rom_params + BOOT_DEVICE_OFFSET)); + +#if defined(BOOT_DEVICE_NAND_I2C) + /* + * Re-map NAND&I2C boot-device to the "normal" NAND boot-device. + * Otherwise the SPL boot IF can't handle this device correctly. + * Somehow booting with Hynix 4GBit NAND H27U4G8 on Siemens + * Draco leads to this boot-device passed to SPL from the BootROM. + */ + if (boot_device == BOOT_DEVICE_NAND_I2C) + boot_device = BOOT_DEVICE_NAND; +#endif + gd->arch.omap_boot_params.omap_bootdevice = boot_device; + + gd->arch.omap_boot_params.ch_flags = + *((u8 *)(rom_params + CH_FLAGS_OFFSET)); + + if ((boot_device >= MMC_BOOT_DEVICES_START) && + (boot_device <= MMC_BOOT_DEVICES_END)) { +#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX) && \ + !defined(CONFIG_AM43XX) + if ((omap_hw_init_context() == + OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) { + gd->arch.omap_boot_params.omap_bootmode = + *((u8 *)(rom_params + BOOT_MODE_OFFSET)); + } else +#endif + { + dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET)); + dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET)); + gd->arch.omap_boot_params.omap_bootmode = + *((u32 *)(dev_data + BOOT_MODE_OFFSET)); + } + } + +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + /* + * We get different values for QSPI_1 and QSPI_4 being used, but + * don't actually care about this difference. Rather than + * mangle the later code, if we're coming in as QSPI_4 just + * change to the QSPI_1 value. + */ + if (gd->arch.omap_boot_params.omap_bootdevice == 11) + gd->arch.omap_boot_params.omap_bootdevice = BOOT_DEVICE_SPI; +#endif +} + +#ifdef CONFIG_SPL_BUILD +u32 spl_boot_device(void) +{ + return (u32) (gd->arch.omap_boot_params.omap_bootdevice); +} + +u32 spl_boot_mode(void) +{ + u32 val = gd->arch.omap_boot_params.omap_bootmode; + + if (val == MMCSD_MODE_RAW) + return MMCSD_MODE_RAW; + else if (val == MMCSD_MODE_FS) + return MMCSD_MODE_FS; + else +#ifdef CONFIG_SUPPORT_EMMC_BOOT + return MMCSD_MODE_EMMCBOOT; +#else + return MMCSD_MODE_UNDEFINED; +#endif +} + +void spl_board_init(void) +{ + /* + * Save the boot parameters passed from romcode. + * We cannot delay the saving further than this, + * to prevent overwrites. + */ + save_omap_boot_params(); + + /* Prepare console output */ + preloader_console_init(); + +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif +#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT) + arch_misc_init(); +#endif +#if defined(CONFIG_HW_WATCHDOG) + hw_watchdog_init(); +#endif +#ifdef CONFIG_AM33XX + am33xx_spl_board_init(); +#endif +} + +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0, -1, -1); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0, -1, -1); + break; + } + return 0; +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + typedef void __noreturn (*image_entry_noargs_t)(u32 *); + image_entry_noargs_t image_entry = + (image_entry_noargs_t) spl_image->entry_point; + + debug("image entry point: 0x%X\n", spl_image->entry_point); + /* Pass the saved boot_params from rom code */ + image_entry((u32 *)&gd->arch.omap_boot_params); +} +#endif + +#ifdef CONFIG_SCSI_AHCI_PLAT +void arch_preboot_os(void) +{ + ahci_reset(DWC_AHSATA_BASE); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/clocks-common.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/clocks-common.c new file mode 100644 index 0000000..03674e6 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -0,0 +1,804 @@ +/* + * + * Clock initialization for OMAP4 + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * Based on previous work by: + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * Rajendra Nayak <rnayak@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <i2c.h> +#include <asm/omap_common.h> +#include <asm/gpio.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/utils.h> +#include <asm/omap_gpio.h> +#include <asm/emif.h> + +#ifndef CONFIG_SPL_BUILD +/* + * printing to console doesn't work unless + * this code is executed from SPL + */ +#define printf(fmt, args...) +#define puts(s) +#endif + +const u32 sys_clk_array[8] = { + 12000000, /* 12 MHz */ + 20000000, /* 20 MHz */ + 16800000, /* 16.8 MHz */ + 19200000, /* 19.2 MHz */ + 26000000, /* 26 MHz */ + 27000000, /* 27 MHz */ + 38400000, /* 38.4 MHz */ +}; + +static inline u32 __get_sys_clk_index(void) +{ + s8 ind; + /* + * For ES1 the ROM code calibration of sys clock is not reliable + * due to hw issue. So, use hard-coded value. If this value is not + * correct for any board over-ride this function in board file + * From ES2.0 onwards you will get this information from + * CM_SYS_CLKSEL + */ + if (omap_revision() == OMAP4430_ES1_0) + ind = OMAP_SYS_CLK_IND_38_4_MHZ; + else { + /* SYS_CLKSEL - 1 to match the dpll param array indices */ + ind = (readl((*prcm)->cm_sys_clksel) & + CM_SYS_CLKSEL_SYS_CLKSEL_MASK) - 1; + } + return ind; +} + +u32 get_sys_clk_index(void) + __attribute__ ((weak, alias("__get_sys_clk_index"))); + +u32 get_sys_clk_freq(void) +{ + u8 index = get_sys_clk_index(); + return sys_clk_array[index]; +} + +void setup_post_dividers(u32 const base, const struct dpll_params *params) +{ + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + + /* Setup post-dividers */ + if (params->m2 >= 0) + writel(params->m2, &dpll_regs->cm_div_m2_dpll); + if (params->m3 >= 0) + writel(params->m3, &dpll_regs->cm_div_m3_dpll); + if (params->m4_h11 >= 0) + writel(params->m4_h11, &dpll_regs->cm_div_m4_h11_dpll); + if (params->m5_h12 >= 0) + writel(params->m5_h12, &dpll_regs->cm_div_m5_h12_dpll); + if (params->m6_h13 >= 0) + writel(params->m6_h13, &dpll_regs->cm_div_m6_h13_dpll); + if (params->m7_h14 >= 0) + writel(params->m7_h14, &dpll_regs->cm_div_m7_h14_dpll); + if (params->h21 >= 0) + writel(params->h21, &dpll_regs->cm_div_h21_dpll); + if (params->h22 >= 0) + writel(params->h22, &dpll_regs->cm_div_h22_dpll); + if (params->h23 >= 0) + writel(params->h23, &dpll_regs->cm_div_h23_dpll); + if (params->h24 >= 0) + writel(params->h24, &dpll_regs->cm_div_h24_dpll); +} + +static inline void do_bypass_dpll(u32 const base) +{ + struct dpll_regs *dpll_regs = (struct dpll_regs *)base; + + clrsetbits_le32(&dpll_regs->cm_clkmode_dpll, + CM_CLKMODE_DPLL_DPLL_EN_MASK, + DPLL_EN_FAST_RELOCK_BYPASS << + CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_bypass(u32 const base) +{ + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + + if (!wait_on_value(ST_DPLL_CLK_MASK, 0, &dpll_regs->cm_idlest_dpll, + LDELAY)) { + printf("Bypassing DPLL failed %x\n", base); + } +} + +static inline void do_lock_dpll(u32 const base) +{ + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + + clrsetbits_le32(&dpll_regs->cm_clkmode_dpll, + CM_CLKMODE_DPLL_DPLL_EN_MASK, + DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT); +} + +static inline void wait_for_lock(u32 const base) +{ + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + + if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK, + &dpll_regs->cm_idlest_dpll, LDELAY)) { + printf("DPLL locking failed for %x\n", base); + hang(); + } +} + +inline u32 check_for_lock(u32 const base) +{ + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + u32 lock = readl(&dpll_regs->cm_idlest_dpll) & ST_DPLL_CLK_MASK; + + return lock; +} + +const struct dpll_params *get_mpu_dpll_params(struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->mpu[sysclk_ind]; +} + +const struct dpll_params *get_core_dpll_params(struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->core[sysclk_ind]; +} + +const struct dpll_params *get_per_dpll_params(struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->per[sysclk_ind]; +} + +const struct dpll_params *get_iva_dpll_params(struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->iva[sysclk_ind]; +} + +const struct dpll_params *get_usb_dpll_params(struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->usb[sysclk_ind]; +} + +const struct dpll_params *get_abe_dpll_params(struct dplls const *dpll_data) +{ +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + u32 sysclk_ind = get_sys_clk_index(); + return &dpll_data->abe[sysclk_ind]; +#else + return dpll_data->abe; +#endif +} + +static const struct dpll_params *get_ddr_dpll_params + (struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + + if (!dpll_data->ddr) + return NULL; + return &dpll_data->ddr[sysclk_ind]; +} + +#ifdef CONFIG_DRIVER_TI_CPSW +static const struct dpll_params *get_gmac_dpll_params + (struct dplls const *dpll_data) +{ + u32 sysclk_ind = get_sys_clk_index(); + + if (!dpll_data->gmac) + return NULL; + return &dpll_data->gmac[sysclk_ind]; +} +#endif + +static void do_setup_dpll(u32 const base, const struct dpll_params *params, + u8 lock, char *dpll) +{ + u32 temp, M, N; + struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; + + if (!params) + return; + + temp = readl(&dpll_regs->cm_clksel_dpll); + + if (check_for_lock(base)) { + /* + * The Dpll has already been locked by rom code using CH. + * Check if M,N are matching with Ideal nominal opp values. + * If matches, skip the rest otherwise relock. + */ + M = (temp & CM_CLKSEL_DPLL_M_MASK) >> CM_CLKSEL_DPLL_M_SHIFT; + N = (temp & CM_CLKSEL_DPLL_N_MASK) >> CM_CLKSEL_DPLL_N_SHIFT; + if ((M != (params->m)) || (N != (params->n))) { + debug("\n %s Dpll locked, but not for ideal M = %d," + "N = %d values, current values are M = %d," + "N= %d" , dpll, params->m, params->n, + M, N); + } else { + /* Dpll locked with ideal values for nominal opps. */ + debug("\n %s Dpll already locked with ideal" + "nominal opp values", dpll); + goto setup_post_dividers; + } + } + + bypass_dpll(base); + + /* Set M & N */ + temp &= ~CM_CLKSEL_DPLL_M_MASK; + temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK; + + temp &= ~CM_CLKSEL_DPLL_N_MASK; + temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK; + + writel(temp, &dpll_regs->cm_clksel_dpll); + + /* Lock */ + if (lock) + do_lock_dpll(base); + +setup_post_dividers: + setup_post_dividers(base, params); + + /* Wait till the DPLL locks */ + if (lock) + wait_for_lock(base); +} + +u32 omap_ddr_clk(void) +{ + u32 ddr_clk, sys_clk_khz, omap_rev, divider; + const struct dpll_params *core_dpll_params; + + omap_rev = omap_revision(); + sys_clk_khz = get_sys_clk_freq() / 1000; + + core_dpll_params = get_core_dpll_params(*dplls_data); + + debug("sys_clk %d\n ", sys_clk_khz * 1000); + + /* Find Core DPLL locked frequency first */ + ddr_clk = sys_clk_khz * 2 * core_dpll_params->m / + (core_dpll_params->n + 1); + + if (omap_rev < OMAP5430_ES1_0) { + /* + * DDR frequency is PHY_ROOT_CLK/2 + * PHY_ROOT_CLK = Fdpll/2/M2 + */ + divider = 4; + } else { + /* + * DDR frequency is PHY_ROOT_CLK + * PHY_ROOT_CLK = Fdpll/2/M2 + */ + divider = 2; + } + + ddr_clk = ddr_clk / divider / core_dpll_params->m2; + ddr_clk *= 1000; /* convert to Hz */ + debug("ddr_clk %d\n ", ddr_clk); + + return ddr_clk; +} + +/* + * Lock MPU dpll + * + * Resulting MPU frequencies: + * 4430 ES1.0 : 600 MHz + * 4430 ES2.x : 792 MHz (OPP Turbo) + * 4460 : 920 MHz (OPP Turbo) - DCC disabled + */ +void configure_mpu_dpll(void) +{ + const struct dpll_params *params; + struct dpll_regs *mpu_dpll_regs; + u32 omap_rev; + omap_rev = omap_revision(); + + /* + * DCC and clock divider settings for 4460. + * DCC is required, if more than a certain frequency is required. + * For, 4460 > 1GHZ. + * 5430 > 1.4GHZ. + */ + if ((omap_rev >= OMAP4460_ES1_0) && (omap_rev < OMAP5430_ES1_0)) { + mpu_dpll_regs = + (struct dpll_regs *)((*prcm)->cm_clkmode_dpll_mpu); + bypass_dpll((*prcm)->cm_clkmode_dpll_mpu); + clrbits_le32((*prcm)->cm_mpu_mpu_clkctrl, + MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK); + setbits_le32((*prcm)->cm_mpu_mpu_clkctrl, + MPU_CLKCTRL_CLKSEL_ABE_DIV_MODE_MASK); + clrbits_le32(&mpu_dpll_regs->cm_clksel_dpll, + CM_CLKSEL_DCC_EN_MASK); + } + + params = get_mpu_dpll_params(*dplls_data); + + do_setup_dpll((*prcm)->cm_clkmode_dpll_mpu, params, DPLL_LOCK, "mpu"); + debug("MPU DPLL locked\n"); +} + +#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) +static void setup_usb_dpll(void) +{ + const struct dpll_params *params; + u32 sys_clk_khz, sd_div, num, den; + + sys_clk_khz = get_sys_clk_freq() / 1000; + /* + * USB: + * USB dpll is J-type. Need to set DPLL_SD_DIV for jitter correction + * DPLL_SD_DIV = CEILING ([DPLL_MULT/(DPLL_DIV+1)]* CLKINP / 250) + * - where CLKINP is sys_clk in MHz + * Use CLKINP in KHz and adjust the denominator accordingly so + * that we have enough accuracy and at the same time no overflow + */ + params = get_usb_dpll_params(*dplls_data); + num = params->m * sys_clk_khz; + den = (params->n + 1) * 250 * 1000; + num += den - 1; + sd_div = num / den; + clrsetbits_le32((*prcm)->cm_clksel_dpll_usb, + CM_CLKSEL_DPLL_DPLL_SD_DIV_MASK, + sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT); + + /* Now setup the dpll with the regular function */ + do_setup_dpll((*prcm)->cm_clkmode_dpll_usb, params, DPLL_LOCK, "usb"); +} +#endif + +static void setup_dplls(void) +{ + u32 temp; + const struct dpll_params *params; + + debug("setup_dplls\n"); + + /* CORE dpll */ + params = get_core_dpll_params(*dplls_data); /* default - safest */ + /* + * Do not lock the core DPLL now. Just set it up. + * Core DPLL will be locked after setting up EMIF + * using the FREQ_UPDATE method(freq_update_core()) + */ + if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params, + DPLL_NO_LOCK, "core"); + else + do_setup_dpll((*prcm)->cm_clkmode_dpll_core, params, + DPLL_LOCK, "core"); + /* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */ + temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) | + (CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) | + (CLKSEL_L4_L3_DIV_2 << CLKSEL_L4_SHIFT); + writel(temp, (*prcm)->cm_clksel_core); + debug("Core DPLL configured\n"); + + /* lock PER dpll */ + params = get_per_dpll_params(*dplls_data); + do_setup_dpll((*prcm)->cm_clkmode_dpll_per, + params, DPLL_LOCK, "per"); + debug("PER DPLL locked\n"); + + /* MPU dpll */ + configure_mpu_dpll(); + +#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) + setup_usb_dpll(); +#endif + params = get_ddr_dpll_params(*dplls_data); + do_setup_dpll((*prcm)->cm_clkmode_dpll_ddrphy, + params, DPLL_LOCK, "ddr"); + +#ifdef CONFIG_DRIVER_TI_CPSW + params = get_gmac_dpll_params(*dplls_data); + do_setup_dpll((*prcm)->cm_clkmode_dpll_gmac, params, + DPLL_LOCK, "gmac"); +#endif +} + +u32 get_offset_code(u32 volt_offset, struct pmic_data *pmic) +{ + u32 offset_code; + + volt_offset -= pmic->base_offset; + + offset_code = (volt_offset + pmic->step - 1) / pmic->step; + + /* + * Offset codes 1-6 all give the base voltage in Palmas + * Offset code 0 switches OFF the SMPS + */ + return offset_code + pmic->start_code; +} + +void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic) +{ + u32 offset_code; + u32 offset = volt_mv; +#ifndef CONFIG_DRA7XX + int ret = 0; +#endif + + if (!volt_mv) + return; + + pmic->pmic_bus_init(); +#ifndef CONFIG_DRA7XX + /* See if we can first get the GPIO if needed */ + if (pmic->gpio_en) + ret = gpio_request(pmic->gpio, "PMIC_GPIO"); + + if (ret < 0) { + printf("%s: gpio %d request failed %d\n", __func__, + pmic->gpio, ret); + return; + } + + /* Pull the GPIO low to select SET0 register, while we program SET1 */ + if (pmic->gpio_en) + gpio_direction_output(pmic->gpio, 0); +#endif + /* convert to uV for better accuracy in the calculations */ + offset *= 1000; + + offset_code = get_offset_code(offset, pmic); + + debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv, + offset_code); + + if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code)) + printf("Scaling voltage failed for 0x%x\n", vcore_reg); +#ifndef CONFIG_DRA7XX + if (pmic->gpio_en) + gpio_direction_output(pmic->gpio, 1); +#endif +} + +static u32 optimize_vcore_voltage(struct volts const *v) +{ + u32 val; + if (!v->value) + return 0; + if (!v->efuse.reg) + return v->value; + + switch (v->efuse.reg_bits) { + case 16: + val = readw(v->efuse.reg); + break; + case 32: + val = readl(v->efuse.reg); + break; + default: + printf("Error: efuse 0x%08x bits=%d unknown\n", + v->efuse.reg, v->efuse.reg_bits); + return v->value; + } + + if (!val) { + printf("Error: efuse 0x%08x bits=%d val=0, using %d\n", + v->efuse.reg, v->efuse.reg_bits, v->value); + return v->value; + } + + debug("%s:efuse 0x%08x bits=%d Vnom=%d, using efuse value %d\n", + __func__, v->efuse.reg, v->efuse.reg_bits, v->value, val); + return val; +} + +/* + * Setup the voltages for the main SoC core power domains. + * We start with the maximum voltages allowed here, as set in the corresponding + * vcores_data struct, and then scale (usually down) to the fused values that + * are retrieved from the SoC. The scaling happens only if the efuse.reg fields + * are initialised. + * Rail grouping is supported for the DRA7xx SoCs only, therefore the code is + * compiled conditionally. Note that the new code writes the scaled (or zeroed) + * values back to the vcores_data struct for eventual reuse. Zero values mean + * that the corresponding rails are not controlled separately, and are not sent + * to the PMIC. + */ +void scale_vcores(struct vcores_data const *vcores) +{ +#if defined(CONFIG_DRA7XX) + int i; + struct volts *pv = (struct volts *)vcores; + struct volts *px; + + for (i=0; i<(sizeof(struct vcores_data)/sizeof(struct volts)); i++) { + debug("%d -> ", pv->value); + if (pv->value) { + /* Handle non-empty members only */ + pv->value = optimize_vcore_voltage(pv); + px = (struct volts *)vcores; + while (px < pv) { + /* + * Scan already handled non-empty members to see + * if we have a group and find the max voltage, + * which is set to the first occurance of the + * particular SMPS; the other group voltages are + * zeroed. + */ + if (px->value) { + if ((pv->pmic->i2c_slave_addr == + px->pmic->i2c_slave_addr) && + (pv->addr == px->addr)) { + /* Same PMIC, same SMPS */ + if (pv->value > px->value) + px->value = pv->value; + + pv->value = 0; + } + } + px++; + } + } + debug("%d\n", pv->value); + pv++; + } + + debug("cor: %d\n", vcores->core.value); + do_scale_vcore(vcores->core.addr, vcores->core.value, vcores->core.pmic); + debug("mpu: %d\n", vcores->mpu.value); + do_scale_vcore(vcores->mpu.addr, vcores->mpu.value, vcores->mpu.pmic); + /* Configure MPU ABB LDO after scale */ + abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2, + (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl, + (*prcm)->prm_abbldo_mpu_setup, + (*prcm)->prm_abbldo_mpu_ctrl, + (*prcm)->prm_irqstatus_mpu_2, + OMAP_ABB_MPU_TXDONE_MASK, + OMAP_ABB_FAST_OPP); + + /* The .mm member is not used for the DRA7xx */ + + debug("gpu: %d\n", vcores->gpu.value); + do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic); + debug("eve: %d\n", vcores->eve.value); + do_scale_vcore(vcores->eve.addr, vcores->eve.value, vcores->eve.pmic); + debug("iva: %d\n", vcores->iva.value); + do_scale_vcore(vcores->iva.addr, vcores->iva.value, vcores->iva.pmic); + /* Might need udelay(1000) here if debug is enabled to see all prints */ +#else + u32 val; + + val = optimize_vcore_voltage(&vcores->core); + do_scale_vcore(vcores->core.addr, val, vcores->core.pmic); + + val = optimize_vcore_voltage(&vcores->mpu); + do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic); + + /* Configure MPU ABB LDO after scale */ + abb_setup((*ctrl)->control_std_fuse_opp_vdd_mpu_2, + (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl, + (*prcm)->prm_abbldo_mpu_setup, + (*prcm)->prm_abbldo_mpu_ctrl, + (*prcm)->prm_irqstatus_mpu_2, + OMAP_ABB_MPU_TXDONE_MASK, + OMAP_ABB_FAST_OPP); + + val = optimize_vcore_voltage(&vcores->mm); + do_scale_vcore(vcores->mm.addr, val, vcores->mm.pmic); + + val = optimize_vcore_voltage(&vcores->gpu); + do_scale_vcore(vcores->gpu.addr, val, vcores->gpu.pmic); + + val = optimize_vcore_voltage(&vcores->eve); + do_scale_vcore(vcores->eve.addr, val, vcores->eve.pmic); + + val = optimize_vcore_voltage(&vcores->iva); + do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic); +#endif +} + +static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode) +{ + clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK, + enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT); + debug("Enable clock domain - %x\n", clkctrl_reg); +} + +static inline void wait_for_clk_enable(u32 clkctrl_addr) +{ + u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; + u32 bound = LDELAY; + + while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || + (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { + + clkctrl = readl(clkctrl_addr); + idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> + MODULE_CLKCTRL_IDLEST_SHIFT; + if (--bound == 0) { + printf("Clock enable failed for 0x%x idlest 0x%x\n", + clkctrl_addr, clkctrl); + return; + } + } +} + +static inline void enable_clock_module(u32 const clkctrl_addr, u32 enable_mode, + u32 wait_for_enable) +{ + clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK, + enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT); + debug("Enable clock module - %x\n", clkctrl_addr); + if (wait_for_enable) + wait_for_clk_enable(clkctrl_addr); +} + +void freq_update_core(void) +{ + u32 freq_config1 = 0; + const struct dpll_params *core_dpll_params; + u32 omap_rev = omap_revision(); + + core_dpll_params = get_core_dpll_params(*dplls_data); + /* Put EMIF clock domain in sw wakeup mode */ + enable_clock_domain((*prcm)->cm_memif_clkstctrl, + CD_CLKCTRL_CLKTRCTRL_SW_WKUP); + wait_for_clk_enable((*prcm)->cm_memif_emif_1_clkctrl); + wait_for_clk_enable((*prcm)->cm_memif_emif_2_clkctrl); + + freq_config1 = SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK | + SHADOW_FREQ_CONFIG1_DLL_RESET_MASK; + + freq_config1 |= (DPLL_EN_LOCK << SHADOW_FREQ_CONFIG1_DPLL_EN_SHIFT) & + SHADOW_FREQ_CONFIG1_DPLL_EN_MASK; + + freq_config1 |= (core_dpll_params->m2 << + SHADOW_FREQ_CONFIG1_M2_DIV_SHIFT) & + SHADOW_FREQ_CONFIG1_M2_DIV_MASK; + + writel(freq_config1, (*prcm)->cm_shadow_freq_config1); + if (!wait_on_value(SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK, 0, + (u32 *) (*prcm)->cm_shadow_freq_config1, LDELAY)) { + puts("FREQ UPDATE procedure failed!!"); + hang(); + } + + /* + * Putting EMIF in HW_AUTO is seen to be causing issues with + * EMIF clocks and the master DLL. Keep EMIF in SW_WKUP + * in OMAP5430 ES1.0 silicon + */ + if (omap_rev != OMAP5430_ES1_0) { + /* Put EMIF clock domain back in hw auto mode */ + enable_clock_domain((*prcm)->cm_memif_clkstctrl, + CD_CLKCTRL_CLKTRCTRL_HW_AUTO); + wait_for_clk_enable((*prcm)->cm_memif_emif_1_clkctrl); + wait_for_clk_enable((*prcm)->cm_memif_emif_2_clkctrl); + } +} + +void bypass_dpll(u32 const base) +{ + do_bypass_dpll(base); + wait_for_bypass(base); +} + +void lock_dpll(u32 const base) +{ + do_lock_dpll(base); + wait_for_lock(base); +} + +void setup_clocks_for_console(void) +{ + /* Do not add any spl_debug prints in this function */ + clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_SW_WKUP << + CD_CLKCTRL_CLKTRCTRL_SHIFT); + + /* Enable all UARTs - console will be on one of them */ + clrsetbits_le32((*prcm)->cm_l4per_uart1_clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + + clrsetbits_le32((*prcm)->cm_l4per_uart2_clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + + clrsetbits_le32((*prcm)->cm_l4per_uart3_clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + + clrsetbits_le32((*prcm)->cm_l4per_uart4_clkctrl, + MODULE_CLKCTRL_MODULEMODE_MASK, + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << + MODULE_CLKCTRL_MODULEMODE_SHIFT); + + clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, + CD_CLKCTRL_CLKTRCTRL_HW_AUTO << + CD_CLKCTRL_CLKTRCTRL_SHIFT); +} + +void do_enable_clocks(u32 const *clk_domains, + u32 const *clk_modules_hw_auto, + u32 const *clk_modules_explicit_en, + u8 wait_for_enable) +{ + u32 i, max = 100; + + /* Put the clock domains in SW_WKUP mode */ + for (i = 0; (i < max) && clk_domains[i]; i++) { + enable_clock_domain(clk_domains[i], + CD_CLKCTRL_CLKTRCTRL_SW_WKUP); + } + + /* Clock modules that need to be put in HW_AUTO */ + for (i = 0; (i < max) && clk_modules_hw_auto[i]; i++) { + enable_clock_module(clk_modules_hw_auto[i], + MODULE_CLKCTRL_MODULEMODE_HW_AUTO, + wait_for_enable); + }; + + /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ + for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) { + enable_clock_module(clk_modules_explicit_en[i], + MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, + wait_for_enable); + }; + + /* Put the clock domains in HW_AUTO mode now */ + for (i = 0; (i < max) && clk_domains[i]; i++) { + enable_clock_domain(clk_domains[i], + CD_CLKCTRL_CLKTRCTRL_HW_AUTO); + } +} + +void prcm_init(void) +{ + switch (omap_hw_init_context()) { + case OMAP_INIT_CONTEXT_SPL: + case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: + case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: + enable_basic_clocks(); + timer_init(); + scale_vcores(*omap_vcores); + setup_dplls(); + setup_warmreset_time(); + break; + default: + break; + } + + if (OMAP_INIT_CONTEXT_SPL != omap_hw_init_context()) + enable_basic_uboot_clocks(); +} + +void gpi2c_init(void) +{ + static int gpi2c = 1; + + if (gpi2c) { + i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, + CONFIG_SYS_OMAP24_I2C_SLAVE); + gpi2c = 0; + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/emif-common.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/emif-common.c new file mode 100644 index 0000000..c01a98f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -0,0 +1,1361 @@ +/* + * EMIF programming + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/emif.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/omap_common.h> +#include <asm/utils.h> +#include <linux/compiler.h> + +static int emif1_enabled = -1, emif2_enabled = -1; + +void set_lpmode_selfrefresh(u32 base) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + u32 reg; + + reg = readl(&emif->emif_pwr_mgmt_ctrl); + reg &= ~EMIF_REG_LP_MODE_MASK; + reg |= LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT; + reg &= ~EMIF_REG_SR_TIM_MASK; + writel(reg, &emif->emif_pwr_mgmt_ctrl); + + /* dummy read for the new SR_TIM to be loaded */ + readl(&emif->emif_pwr_mgmt_ctrl); +} + +void force_emif_self_refresh() +{ + set_lpmode_selfrefresh(EMIF1_BASE); + set_lpmode_selfrefresh(EMIF2_BASE); +} + +inline u32 emif_num(u32 base) +{ + if (base == EMIF1_BASE) + return 1; + else if (base == EMIF2_BASE) + return 2; + else + return 0; +} + +static inline u32 get_mr(u32 base, u32 cs, u32 mr_addr) +{ + u32 mr; + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + mr_addr |= cs << EMIF_REG_CS_SHIFT; + writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg); + if (omap_revision() == OMAP4430_ES2_0) + mr = readl(&emif->emif_lpddr2_mode_reg_data_es2); + else + mr = readl(&emif->emif_lpddr2_mode_reg_data); + debug("get_mr: EMIF%d cs %d mr %08x val 0x%x\n", emif_num(base), + cs, mr_addr, mr); + if (((mr & 0x0000ff00) >> 8) == (mr & 0xff) && + ((mr & 0x00ff0000) >> 16) == (mr & 0xff) && + ((mr & 0xff000000) >> 24) == (mr & 0xff)) + return mr & 0xff; + else + return mr; +} + +static inline void set_mr(u32 base, u32 cs, u32 mr_addr, u32 mr_val) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + mr_addr |= cs << EMIF_REG_CS_SHIFT; + writel(mr_addr, &emif->emif_lpddr2_mode_reg_cfg); + writel(mr_val, &emif->emif_lpddr2_mode_reg_data); +} + +void emif_reset_phy(u32 base) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + u32 iodft; + + iodft = readl(&emif->emif_iodft_tlgc); + iodft |= EMIF_REG_RESET_PHY_MASK; + writel(iodft, &emif->emif_iodft_tlgc); +} + +static void do_lpddr2_init(u32 base, u32 cs) +{ + u32 mr_addr; + const struct lpddr2_mr_regs *mr_regs; + + get_lpddr2_mr_regs(&mr_regs); + /* Wait till device auto initialization is complete */ + while (get_mr(base, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK) + ; + set_mr(base, cs, LPDDR2_MR10, mr_regs->mr10); + /* + * tZQINIT = 1 us + * Enough loops assuming a maximum of 2GHz + */ + + sdelay(2000); + + set_mr(base, cs, LPDDR2_MR1, mr_regs->mr1); + set_mr(base, cs, LPDDR2_MR16, mr_regs->mr16); + + /* + * Enable refresh along with writing MR2 + * Encoding of RL in MR2 is (RL - 2) + */ + mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK; + set_mr(base, cs, mr_addr, mr_regs->mr2); + + if (mr_regs->mr3 > 0) + set_mr(base, cs, LPDDR2_MR3, mr_regs->mr3); +} + +static void lpddr2_init(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + /* Not NVM */ + clrbits_le32(&emif->emif_lpddr2_nvm_config, EMIF_REG_CS1NVMEN_MASK); + + /* + * Keep REG_INITREF_DIS = 1 to prevent re-initialization of SDRAM + * when EMIF_SDRAM_CONFIG register is written + */ + setbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK); + + /* + * Set the SDRAM_CONFIG and PHY_CTRL for the + * un-locked frequency & default RL + */ + writel(regs->sdram_config_init, &emif->emif_sdram_config); + writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1); + + do_ext_phy_settings(base, regs); + + do_lpddr2_init(base, CS0); + if (regs->sdram_config & EMIF_REG_EBANK_MASK) + do_lpddr2_init(base, CS1); + + writel(regs->sdram_config, &emif->emif_sdram_config); + writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1); + + /* Enable refresh now */ + clrbits_le32(&emif->emif_sdram_ref_ctrl, EMIF_REG_INITREF_DIS_MASK); + + } + +__weak void do_ext_phy_settings(u32 base, const struct emif_regs *regs) +{ +} + +void emif_update_timings(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl_shdw); + writel(regs->sdram_tim1, &emif->emif_sdram_tim_1_shdw); + writel(regs->sdram_tim2, &emif->emif_sdram_tim_2_shdw); + writel(regs->sdram_tim3, &emif->emif_sdram_tim_3_shdw); + if (omap_revision() == OMAP4430_ES1_0) { + /* ES1 bug EMIF should be in force idle during freq_update */ + writel(0, &emif->emif_pwr_mgmt_ctrl); + } else { + writel(EMIF_PWR_MGMT_CTRL, &emif->emif_pwr_mgmt_ctrl); + writel(EMIF_PWR_MGMT_CTRL_SHDW, &emif->emif_pwr_mgmt_ctrl_shdw); + } + writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl_shdw); + writel(regs->zq_config, &emif->emif_zq_config); + writel(regs->temp_alert_config, &emif->emif_temp_alert_config); + writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1_shdw); + + if ((omap_revision() >= OMAP5430_ES1_0) || is_dra7xx()) { + writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_5_LL_0, + &emif->emif_l3_config); + } else if (omap_revision() >= OMAP4460_ES1_0) { + writel(EMIF_L3_CONFIG_VAL_SYS_10_MPU_3_LL_0, + &emif->emif_l3_config); + } else { + writel(EMIF_L3_CONFIG_VAL_SYS_10_LL_0, + &emif->emif_l3_config); + } +} + +static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + /* keep sdram in self-refresh */ + writel(((LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT) + & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl); + __udelay(130); + + /* + * Set invert_clkout (if activated)--DDR_PHYCTRL_1 + * Invert clock adds an additional half cycle delay on the + * command interface. The additional half cycle, is usually + * meant to enable leveling in the situation that DQS is later + * than CK on the board.It also helps provide some additional + * margin for leveling. + */ + writel(regs->emif_ddr_phy_ctlr_1, + &emif->emif_ddr_phy_ctrl_1); + + writel(regs->emif_ddr_phy_ctlr_1, + &emif->emif_ddr_phy_ctrl_1_shdw); + __udelay(130); + + writel(((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT) + & EMIF_REG_LP_MODE_MASK), &emif->emif_pwr_mgmt_ctrl); + + /* Launch Full leveling */ + writel(DDR3_FULL_LVL, &emif->emif_rd_wr_lvl_ctl); + + /* Wait till full leveling is complete */ + readl(&emif->emif_rd_wr_lvl_ctl); + __udelay(130); + + /* Read data eye leveling no of samples */ + config_data_eye_leveling_samples(base); + + /* + * Launch 8 incremental WR_LVL- to compensate for + * PHY limitation. + */ + writel(0x2 << EMIF_REG_WRLVLINC_INT_SHIFT, + &emif->emif_rd_wr_lvl_ctl); + + __udelay(130); + + /* Launch Incremental leveling */ + writel(DDR3_INC_LVL, &emif->emif_rd_wr_lvl_ctl); + __udelay(130); +} + +static void ddr3_leveling(u32 base, const struct emif_regs *regs) +{ + if (is_omap54xx()) + omap5_ddr3_leveling(base, regs); +} + +static void ddr3_init(u32 base, const struct emif_regs *regs) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl); + writel(regs->sdram_config_init, &emif->emif_sdram_config); + /* + * Set SDRAM_CONFIG and PHY control registers to locked frequency + * and RL =7. As the default values of the Mode Registers are not + * defined, contents of mode Registers must be fully initialized. + * H/W takes care of this initialization + */ + writel(regs->emif_ddr_phy_ctlr_1_init, &emif->emif_ddr_phy_ctrl_1); + + /* Update timing registers */ + writel(regs->sdram_tim1, &emif->emif_sdram_tim_1); + writel(regs->sdram_tim2, &emif->emif_sdram_tim_2); + writel(regs->sdram_tim3, &emif->emif_sdram_tim_3); + + writel(regs->read_idle_ctrl, &emif->emif_read_idlectrl); + + /* + * The same sequence should work on OMAP5432 as well. But strange that + * it is not working + */ + if (is_dra7xx()) { + do_ext_phy_settings(base, regs); + writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl); + writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config); + writel(regs->sdram_config_init, &emif->emif_sdram_config); + } else { + writel(regs->sdram_config2, &emif->emif_lpddr2_nvm_config); + writel(regs->sdram_config_init, &emif->emif_sdram_config); + do_ext_phy_settings(base, regs); + } + + /* enable leveling */ + writel(regs->emif_rd_wr_lvl_rmp_ctl, &emif->emif_rd_wr_lvl_rmp_ctl); + + ddr3_leveling(base, regs); +} + +#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) + +/* + * Organization and refresh requirements for LPDDR2 devices of different + * types and densities. Derived from JESD209-2 section 2.4 + */ +const struct lpddr2_addressing addressing_table[] = { + /* Banks tREFIx10 rowx32,rowx16 colx32,colx16 density */ + {BANKS4, T_REFI_15_6, {ROW_12, ROW_12}, {COL_7, COL_8} },/*64M */ + {BANKS4, T_REFI_15_6, {ROW_12, ROW_12}, {COL_8, COL_9} },/*128M */ + {BANKS4, T_REFI_7_8, {ROW_13, ROW_13}, {COL_8, COL_9} },/*256M */ + {BANKS4, T_REFI_7_8, {ROW_13, ROW_13}, {COL_9, COL_10} },/*512M */ + {BANKS8, T_REFI_7_8, {ROW_13, ROW_13}, {COL_9, COL_10} },/*1GS4 */ + {BANKS8, T_REFI_3_9, {ROW_14, ROW_14}, {COL_9, COL_10} },/*2GS4 */ + {BANKS8, T_REFI_3_9, {ROW_14, ROW_14}, {COL_10, COL_11} },/*4G */ + {BANKS8, T_REFI_3_9, {ROW_15, ROW_15}, {COL_10, COL_11} },/*8G */ + {BANKS4, T_REFI_7_8, {ROW_14, ROW_14}, {COL_9, COL_10} },/*1GS2 */ + {BANKS4, T_REFI_3_9, {ROW_15, ROW_15}, {COL_9, COL_10} },/*2GS2 */ +}; + +static const u32 lpddr2_density_2_size_in_mbytes[] = { + 8, /* 64Mb */ + 16, /* 128Mb */ + 32, /* 256Mb */ + 64, /* 512Mb */ + 128, /* 1Gb */ + 256, /* 2Gb */ + 512, /* 4Gb */ + 1024, /* 8Gb */ + 2048, /* 16Gb */ + 4096 /* 32Gb */ +}; + +/* + * Calculate the period of DDR clock from frequency value and set the + * denominator and numerator in global variables for easy access later + */ +static void set_ddr_clk_period(u32 freq) +{ + /* + * period = 1/freq + * period_in_ns = 10^9/freq + */ + *T_num = 1000000000; + *T_den = freq; + cancel_out(T_num, T_den, 200); + +} + +/* + * Convert time in nano seconds to number of cycles of DDR clock + */ +static inline u32 ns_2_cycles(u32 ns) +{ + return ((ns * (*T_den)) + (*T_num) - 1) / (*T_num); +} + +/* + * ns_2_cycles with the difference that the time passed is 2 times the actual + * value(to avoid fractions). The cycles returned is for the original value of + * the timing parameter + */ +static inline u32 ns_x2_2_cycles(u32 ns) +{ + return ((ns * (*T_den)) + (*T_num) * 2 - 1) / ((*T_num) * 2); +} + +/* + * Find addressing table index based on the device's type(S2 or S4) and + * density + */ +s8 addressing_table_index(u8 type, u8 density, u8 width) +{ + u8 index; + if ((density > LPDDR2_DENSITY_8Gb) || (width == LPDDR2_IO_WIDTH_8)) + return -1; + + /* + * Look at the way ADDR_TABLE_INDEX* values have been defined + * in emif.h compared to LPDDR2_DENSITY_* values + * The table is layed out in the increasing order of density + * (ignoring type). The exceptions 1GS2 and 2GS2 have been placed + * at the end + */ + if ((type == LPDDR2_TYPE_S2) && (density == LPDDR2_DENSITY_1Gb)) + index = ADDR_TABLE_INDEX1GS2; + else if ((type == LPDDR2_TYPE_S2) && (density == LPDDR2_DENSITY_2Gb)) + index = ADDR_TABLE_INDEX2GS2; + else + index = density; + + debug("emif: addressing table index %d\n", index); + + return index; +} + +/* + * Find the the right timing table from the array of timing + * tables of the device using DDR clock frequency + */ +static const struct lpddr2_ac_timings *get_timings_table(const struct + lpddr2_ac_timings const *const *device_timings, + u32 freq) +{ + u32 i, temp, freq_nearest; + const struct lpddr2_ac_timings *timings = 0; + + emif_assert(freq <= MAX_LPDDR2_FREQ); + emif_assert(device_timings); + + /* + * Start with the maximum allowed frequency - that is always safe + */ + freq_nearest = MAX_LPDDR2_FREQ; + /* + * Find the timings table that has the max frequency value: + * i. Above or equal to the DDR frequency - safe + * ii. The lowest that satisfies condition (i) - optimal + */ + for (i = 0; (i < MAX_NUM_SPEEDBINS) && device_timings[i]; i++) { + temp = device_timings[i]->max_freq; + if ((temp >= freq) && (temp <= freq_nearest)) { + freq_nearest = temp; + timings = device_timings[i]; + } + } + debug("emif: timings table: %d\n", freq_nearest); + return timings; +} + +/* + * Finds the value of emif_sdram_config_reg + * All parameters are programmed based on the device on CS0. + * If there is a device on CS1, it will be same as that on CS0 or + * it will be NVM. We don't support NVM yet. + * If cs1_device pointer is NULL it is assumed that there is no device + * on CS1 + */ +static u32 get_sdram_config_reg(const struct lpddr2_device_details *cs0_device, + const struct lpddr2_device_details *cs1_device, + const struct lpddr2_addressing *addressing, + u8 RL) +{ + u32 config_reg = 0; + + config_reg |= (cs0_device->type + 4) << EMIF_REG_SDRAM_TYPE_SHIFT; + config_reg |= EMIF_INTERLEAVING_POLICY_MAX_INTERLEAVING << + EMIF_REG_IBANK_POS_SHIFT; + + config_reg |= cs0_device->io_width << EMIF_REG_NARROW_MODE_SHIFT; + + config_reg |= RL << EMIF_REG_CL_SHIFT; + + config_reg |= addressing->row_sz[cs0_device->io_width] << + EMIF_REG_ROWSIZE_SHIFT; + + config_reg |= addressing->num_banks << EMIF_REG_IBANK_SHIFT; + + config_reg |= (cs1_device ? EBANK_CS1_EN : EBANK_CS1_DIS) << + EMIF_REG_EBANK_SHIFT; + + config_reg |= addressing->col_sz[cs0_device->io_width] << + EMIF_REG_PAGESIZE_SHIFT; + + return config_reg; +} + +static u32 get_sdram_ref_ctrl(u32 freq, + const struct lpddr2_addressing *addressing) +{ + u32 ref_ctrl = 0, val = 0, freq_khz; + freq_khz = freq / 1000; + /* + * refresh rate to be set is 'tREFI * freq in MHz + * division by 10000 to account for khz and x10 in t_REFI_us_x10 + */ + val = addressing->t_REFI_us_x10 * freq_khz / 10000; + ref_ctrl |= val << EMIF_REG_REFRESH_RATE_SHIFT; + + return ref_ctrl; +} + +static u32 get_sdram_tim_1_reg(const struct lpddr2_ac_timings *timings, + const struct lpddr2_min_tck *min_tck, + const struct lpddr2_addressing *addressing) +{ + u32 tim1 = 0, val = 0; + val = max(min_tck->tWTR, ns_x2_2_cycles(timings->tWTRx2)) - 1; + tim1 |= val << EMIF_REG_T_WTR_SHIFT; + + if (addressing->num_banks == BANKS8) + val = (timings->tFAW * (*T_den) + 4 * (*T_num) - 1) / + (4 * (*T_num)) - 1; + else + val = max(min_tck->tRRD, ns_2_cycles(timings->tRRD)) - 1; + + tim1 |= val << EMIF_REG_T_RRD_SHIFT; + + val = ns_2_cycles(timings->tRASmin + timings->tRPab) - 1; + tim1 |= val << EMIF_REG_T_RC_SHIFT; + + val = max(min_tck->tRAS_MIN, ns_2_cycles(timings->tRASmin)) - 1; + tim1 |= val << EMIF_REG_T_RAS_SHIFT; + + val = max(min_tck->tWR, ns_2_cycles(timings->tWR)) - 1; + tim1 |= val << EMIF_REG_T_WR_SHIFT; + + val = max(min_tck->tRCD, ns_2_cycles(timings->tRCD)) - 1; + tim1 |= val << EMIF_REG_T_RCD_SHIFT; + + val = max(min_tck->tRP_AB, ns_2_cycles(timings->tRPab)) - 1; + tim1 |= val << EMIF_REG_T_RP_SHIFT; + + return tim1; +} + +static u32 get_sdram_tim_2_reg(const struct lpddr2_ac_timings *timings, + const struct lpddr2_min_tck *min_tck) +{ + u32 tim2 = 0, val = 0; + val = max(min_tck->tCKE, timings->tCKE) - 1; + tim2 |= val << EMIF_REG_T_CKE_SHIFT; + + val = max(min_tck->tRTP, ns_x2_2_cycles(timings->tRTPx2)) - 1; + tim2 |= val << EMIF_REG_T_RTP_SHIFT; + + /* + * tXSRD = tRFCab + 10 ns. XSRD and XSNR should have the + * same value + */ + val = ns_2_cycles(timings->tXSR) - 1; + tim2 |= val << EMIF_REG_T_XSRD_SHIFT; + tim2 |= val << EMIF_REG_T_XSNR_SHIFT; + + val = max(min_tck->tXP, ns_x2_2_cycles(timings->tXPx2)) - 1; + tim2 |= val << EMIF_REG_T_XP_SHIFT; + + return tim2; +} + +static u32 get_sdram_tim_3_reg(const struct lpddr2_ac_timings *timings, + const struct lpddr2_min_tck *min_tck, + const struct lpddr2_addressing *addressing) +{ + u32 tim3 = 0, val = 0; + val = min(timings->tRASmax * 10 / addressing->t_REFI_us_x10 - 1, 0xF); + tim3 |= val << EMIF_REG_T_RAS_MAX_SHIFT; + + val = ns_2_cycles(timings->tRFCab) - 1; + tim3 |= val << EMIF_REG_T_RFC_SHIFT; + + val = ns_x2_2_cycles(timings->tDQSCKMAXx2) - 1; + tim3 |= val << EMIF_REG_T_TDQSCKMAX_SHIFT; + + val = ns_2_cycles(timings->tZQCS) - 1; + tim3 |= val << EMIF_REG_ZQ_ZQCS_SHIFT; + + val = max(min_tck->tCKESR, ns_2_cycles(timings->tCKESR)) - 1; + tim3 |= val << EMIF_REG_T_CKESR_SHIFT; + + return tim3; +} + +static u32 get_zq_config_reg(const struct lpddr2_device_details *cs1_device, + const struct lpddr2_addressing *addressing, + u8 volt_ramp) +{ + u32 zq = 0, val = 0; + if (volt_ramp) + val = + EMIF_ZQCS_INTERVAL_DVFS_IN_US * 10 / + addressing->t_REFI_us_x10; + else + val = + EMIF_ZQCS_INTERVAL_NORMAL_IN_US * 10 / + addressing->t_REFI_us_x10; + zq |= val << EMIF_REG_ZQ_REFINTERVAL_SHIFT; + + zq |= (REG_ZQ_ZQCL_MULT - 1) << EMIF_REG_ZQ_ZQCL_MULT_SHIFT; + + zq |= (REG_ZQ_ZQINIT_MULT - 1) << EMIF_REG_ZQ_ZQINIT_MULT_SHIFT; + + zq |= REG_ZQ_SFEXITEN_ENABLE << EMIF_REG_ZQ_SFEXITEN_SHIFT; + + /* + * Assuming that two chipselects have a single calibration resistor + * If there are indeed two calibration resistors, then this flag should + * be enabled to take advantage of dual calibration feature. + * This data should ideally come from board files. But considering + * that none of the boards today have calibration resistors per CS, + * it would be an unnecessary overhead. + */ + zq |= REG_ZQ_DUALCALEN_DISABLE << EMIF_REG_ZQ_DUALCALEN_SHIFT; + + zq |= REG_ZQ_CS0EN_ENABLE << EMIF_REG_ZQ_CS0EN_SHIFT; + + zq |= (cs1_device ? 1 : 0) << EMIF_REG_ZQ_CS1EN_SHIFT; + + return zq; +} + +static u32 get_temp_alert_config(const struct lpddr2_device_details *cs1_device, + const struct lpddr2_addressing *addressing, + u8 is_derated) +{ + u32 alert = 0, interval; + interval = + TEMP_ALERT_POLL_INTERVAL_MS * 10000 / addressing->t_REFI_us_x10; + if (is_derated) + interval *= 4; + alert |= interval << EMIF_REG_TA_REFINTERVAL_SHIFT; + + alert |= TEMP_ALERT_CONFIG_DEVCT_1 << EMIF_REG_TA_DEVCNT_SHIFT; + + alert |= TEMP_ALERT_CONFIG_DEVWDT_32 << EMIF_REG_TA_DEVWDT_SHIFT; + + alert |= 1 << EMIF_REG_TA_SFEXITEN_SHIFT; + + alert |= 1 << EMIF_REG_TA_CS0EN_SHIFT; + + alert |= (cs1_device ? 1 : 0) << EMIF_REG_TA_CS1EN_SHIFT; + + return alert; +} + +static u32 get_read_idle_ctrl_reg(u8 volt_ramp) +{ + u32 idle = 0, val = 0; + if (volt_ramp) + val = ns_2_cycles(READ_IDLE_INTERVAL_DVFS) / 64 - 1; + else + /*Maximum value in normal conditions - suggested by hw team */ + val = 0x1FF; + idle |= val << EMIF_REG_READ_IDLE_INTERVAL_SHIFT; + + idle |= EMIF_REG_READ_IDLE_LEN_VAL << EMIF_REG_READ_IDLE_LEN_SHIFT; + + return idle; +} + +static u32 get_ddr_phy_ctrl_1(u32 freq, u8 RL) +{ + u32 phy = 0, val = 0; + + phy |= (RL + 2) << EMIF_REG_READ_LATENCY_SHIFT; + + if (freq <= 100000000) + val = EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS; + else if (freq <= 200000000) + val = EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ; + else + val = EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ; + phy |= val << EMIF_REG_DLL_SLAVE_DLY_CTRL_SHIFT; + + /* Other fields are constant magic values. Hardcode them together */ + phy |= EMIF_DDR_PHY_CTRL_1_BASE_VAL << + EMIF_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHIFT; + + return phy; +} + +static u32 get_emif_mem_size(u32 base) +{ + u32 size_mbytes = 0, temp; + struct emif_device_details dev_details; + struct lpddr2_device_details cs0_dev_details, cs1_dev_details; + u32 emif_nr = emif_num(base); + + emif_reset_phy(base); + dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0, + &cs0_dev_details); + dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1, + &cs1_dev_details); + emif_reset_phy(base); + + if (dev_details.cs0_device_details) { + temp = dev_details.cs0_device_details->density; + size_mbytes += lpddr2_density_2_size_in_mbytes[temp]; + } + + if (dev_details.cs1_device_details) { + temp = dev_details.cs1_device_details->density; + size_mbytes += lpddr2_density_2_size_in_mbytes[temp]; + } + /* convert to bytes */ + return size_mbytes << 20; +} + +/* Gets the encoding corresponding to a given DMM section size */ +u32 get_dmm_section_size_map(u32 section_size) +{ + /* + * Section size mapping: + * 0x0: 16-MiB section + * 0x1: 32-MiB section + * 0x2: 64-MiB section + * 0x3: 128-MiB section + * 0x4: 256-MiB section + * 0x5: 512-MiB section + * 0x6: 1-GiB section + * 0x7: 2-GiB section + */ + section_size >>= 24; /* divide by 16 MB */ + return log_2_n_round_down(section_size); +} + +static void emif_calculate_regs( + const struct emif_device_details *emif_dev_details, + u32 freq, struct emif_regs *regs) +{ + u32 temp, sys_freq; + const struct lpddr2_addressing *addressing; + const struct lpddr2_ac_timings *timings; + const struct lpddr2_min_tck *min_tck; + const struct lpddr2_device_details *cs0_dev_details = + emif_dev_details->cs0_device_details; + const struct lpddr2_device_details *cs1_dev_details = + emif_dev_details->cs1_device_details; + const struct lpddr2_device_timings *cs0_dev_timings = + emif_dev_details->cs0_device_timings; + + emif_assert(emif_dev_details); + emif_assert(regs); + /* + * You can not have a device on CS1 without one on CS0 + * So configuring EMIF without a device on CS0 doesn't + * make sense + */ + emif_assert(cs0_dev_details); + emif_assert(cs0_dev_details->type != LPDDR2_TYPE_NVM); + /* + * If there is a device on CS1 it should be same type as CS0 + * (or NVM. But NVM is not supported in this driver yet) + */ + emif_assert((cs1_dev_details == NULL) || + (cs1_dev_details->type == LPDDR2_TYPE_NVM) || + (cs0_dev_details->type == cs1_dev_details->type)); + emif_assert(freq <= MAX_LPDDR2_FREQ); + + set_ddr_clk_period(freq); + + /* + * The device on CS0 is used for all timing calculations + * There is only one set of registers for timings per EMIF. So, if the + * second CS(CS1) has a device, it should have the same timings as the + * device on CS0 + */ + timings = get_timings_table(cs0_dev_timings->ac_timings, freq); + emif_assert(timings); + min_tck = cs0_dev_timings->min_tck; + + temp = addressing_table_index(cs0_dev_details->type, + cs0_dev_details->density, + cs0_dev_details->io_width); + + emif_assert((temp >= 0)); + addressing = &(addressing_table[temp]); + emif_assert(addressing); + + sys_freq = get_sys_clk_freq(); + + regs->sdram_config_init = get_sdram_config_reg(cs0_dev_details, + cs1_dev_details, + addressing, RL_BOOT); + + regs->sdram_config = get_sdram_config_reg(cs0_dev_details, + cs1_dev_details, + addressing, RL_FINAL); + + regs->ref_ctrl = get_sdram_ref_ctrl(freq, addressing); + + regs->sdram_tim1 = get_sdram_tim_1_reg(timings, min_tck, addressing); + + regs->sdram_tim2 = get_sdram_tim_2_reg(timings, min_tck); + + regs->sdram_tim3 = get_sdram_tim_3_reg(timings, min_tck, addressing); + + regs->read_idle_ctrl = get_read_idle_ctrl_reg(LPDDR2_VOLTAGE_STABLE); + + regs->temp_alert_config = + get_temp_alert_config(cs1_dev_details, addressing, 0); + + regs->zq_config = get_zq_config_reg(cs1_dev_details, addressing, + LPDDR2_VOLTAGE_STABLE); + + regs->emif_ddr_phy_ctlr_1_init = + get_ddr_phy_ctrl_1(sys_freq / 2, RL_BOOT); + + regs->emif_ddr_phy_ctlr_1 = + get_ddr_phy_ctrl_1(freq, RL_FINAL); + + regs->freq = freq; + + print_timing_reg(regs->sdram_config_init); + print_timing_reg(regs->sdram_config); + print_timing_reg(regs->ref_ctrl); + print_timing_reg(regs->sdram_tim1); + print_timing_reg(regs->sdram_tim2); + print_timing_reg(regs->sdram_tim3); + print_timing_reg(regs->read_idle_ctrl); + print_timing_reg(regs->temp_alert_config); + print_timing_reg(regs->zq_config); + print_timing_reg(regs->emif_ddr_phy_ctlr_1); + print_timing_reg(regs->emif_ddr_phy_ctlr_1_init); +} +#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ + +#ifdef CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION +const char *get_lpddr2_type(u8 type_id) +{ + switch (type_id) { + case LPDDR2_TYPE_S4: + return "LPDDR2-S4"; + case LPDDR2_TYPE_S2: + return "LPDDR2-S2"; + default: + return NULL; + } +} + +const char *get_lpddr2_io_width(u8 width_id) +{ + switch (width_id) { + case LPDDR2_IO_WIDTH_8: + return "x8"; + case LPDDR2_IO_WIDTH_16: + return "x16"; + case LPDDR2_IO_WIDTH_32: + return "x32"; + default: + return NULL; + } +} + +const char *get_lpddr2_manufacturer(u32 manufacturer) +{ + switch (manufacturer) { + case LPDDR2_MANUFACTURER_SAMSUNG: + return "Samsung"; + case LPDDR2_MANUFACTURER_QIMONDA: + return "Qimonda"; + case LPDDR2_MANUFACTURER_ELPIDA: + return "Elpida"; + case LPDDR2_MANUFACTURER_ETRON: + return "Etron"; + case LPDDR2_MANUFACTURER_NANYA: + return "Nanya"; + case LPDDR2_MANUFACTURER_HYNIX: + return "Hynix"; + case LPDDR2_MANUFACTURER_MOSEL: + return "Mosel"; + case LPDDR2_MANUFACTURER_WINBOND: + return "Winbond"; + case LPDDR2_MANUFACTURER_ESMT: + return "ESMT"; + case LPDDR2_MANUFACTURER_SPANSION: + return "Spansion"; + case LPDDR2_MANUFACTURER_SST: + return "SST"; + case LPDDR2_MANUFACTURER_ZMOS: + return "ZMOS"; + case LPDDR2_MANUFACTURER_INTEL: + return "Intel"; + case LPDDR2_MANUFACTURER_NUMONYX: + return "Numonyx"; + case LPDDR2_MANUFACTURER_MICRON: + return "Micron"; + default: + return NULL; + } +} + +static void display_sdram_details(u32 emif_nr, u32 cs, + struct lpddr2_device_details *device) +{ + const char *mfg_str; + const char *type_str; + char density_str[10]; + u32 density; + + debug("EMIF%d CS%d\t", emif_nr, cs); + + if (!device) { + debug("None\n"); + return; + } + + mfg_str = get_lpddr2_manufacturer(device->manufacturer); + type_str = get_lpddr2_type(device->type); + + density = lpddr2_density_2_size_in_mbytes[device->density]; + if ((density / 1024 * 1024) == density) { + density /= 1024; + sprintf(density_str, "%d GB", density); + } else + sprintf(density_str, "%d MB", density); + if (mfg_str && type_str) + debug("%s\t\t%s\t%s\n", mfg_str, type_str, density_str); +} + +static u8 is_lpddr2_sdram_present(u32 base, u32 cs, + struct lpddr2_device_details *lpddr2_device) +{ + u32 mr = 0, temp; + + mr = get_mr(base, cs, LPDDR2_MR0); + if (mr > 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + temp = (mr & LPDDR2_MR0_DI_MASK) >> LPDDR2_MR0_DI_SHIFT; + if (temp) { + /* Not SDRAM */ + return 0; + } + temp = (mr & LPDDR2_MR0_DNVI_MASK) >> LPDDR2_MR0_DNVI_SHIFT; + + if (temp) { + /* DNV supported - But DNV is only supported for NVM */ + return 0; + } + + mr = get_mr(base, cs, LPDDR2_MR4); + if (mr > 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + mr = get_mr(base, cs, LPDDR2_MR5); + if (mr > 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + if (!get_lpddr2_manufacturer(mr)) { + /* Manufacturer not identified */ + return 0; + } + lpddr2_device->manufacturer = mr; + + mr = get_mr(base, cs, LPDDR2_MR6); + if (mr >= 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + mr = get_mr(base, cs, LPDDR2_MR7); + if (mr >= 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + mr = get_mr(base, cs, LPDDR2_MR8); + if (mr >= 0xFF) { + /* Mode register value bigger than 8 bit */ + return 0; + } + + temp = (mr & MR8_TYPE_MASK) >> MR8_TYPE_SHIFT; + if (!get_lpddr2_type(temp)) { + /* Not SDRAM */ + return 0; + } + lpddr2_device->type = temp; + + temp = (mr & MR8_DENSITY_MASK) >> MR8_DENSITY_SHIFT; + if (temp > LPDDR2_DENSITY_32Gb) { + /* Density not supported */ + return 0; + } + lpddr2_device->density = temp; + + temp = (mr & MR8_IO_WIDTH_MASK) >> MR8_IO_WIDTH_SHIFT; + if (!get_lpddr2_io_width(temp)) { + /* IO width unsupported value */ + return 0; + } + lpddr2_device->io_width = temp; + + /* + * If all the above tests pass we should + * have a device on this chip-select + */ + return 1; +} + +struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs, + struct lpddr2_device_details *lpddr2_dev_details) +{ + u32 phy; + u32 base = (emif_nr == 1) ? EMIF1_BASE : EMIF2_BASE; + + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + if (!lpddr2_dev_details) + return NULL; + + /* Do the minimum init for mode register accesses */ + if (!(running_from_sdram() || warm_reset())) { + phy = get_ddr_phy_ctrl_1(get_sys_clk_freq() / 2, RL_BOOT); + writel(phy, &emif->emif_ddr_phy_ctrl_1); + } + + if (!(is_lpddr2_sdram_present(base, cs, lpddr2_dev_details))) + return NULL; + + display_sdram_details(emif_num(base), cs, lpddr2_dev_details); + + return lpddr2_dev_details; +} +#endif /* CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION */ + +static void do_sdram_init(u32 base) +{ + const struct emif_regs *regs; + u32 in_sdram, emif_nr; + + debug(">>do_sdram_init() %x\n", base); + + in_sdram = running_from_sdram(); + emif_nr = (base == EMIF1_BASE) ? 1 : 2; + +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS + emif_get_reg_dump(emif_nr, ®s); + if (!regs) { + debug("EMIF: reg dump not provided\n"); + return; + } +#else + /* + * The user has not provided the register values. We need to + * calculate it based on the timings and the DDR frequency + */ + struct emif_device_details dev_details; + struct emif_regs calculated_regs; + + /* + * Get device details: + * - Discovered if CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION is set + * - Obtained from user otherwise + */ + struct lpddr2_device_details cs0_dev_details, cs1_dev_details; + emif_reset_phy(base); + dev_details.cs0_device_details = emif_get_device_details(emif_nr, CS0, + &cs0_dev_details); + dev_details.cs1_device_details = emif_get_device_details(emif_nr, CS1, + &cs1_dev_details); + emif_reset_phy(base); + + /* Return if no devices on this EMIF */ + if (!dev_details.cs0_device_details && + !dev_details.cs1_device_details) { + return; + } + + /* + * Get device timings: + * - Default timings specified by JESD209-2 if + * CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS is set + * - Obtained from user otherwise + */ + emif_get_device_timings(emif_nr, &dev_details.cs0_device_timings, + &dev_details.cs1_device_timings); + + /* Calculate the register values */ + emif_calculate_regs(&dev_details, omap_ddr_clk(), &calculated_regs); + regs = &calculated_regs; +#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ + + /* + * Initializing the LPDDR2 device can not happen from SDRAM. + * Changing the timing registers in EMIF can happen(going from one + * OPP to another) + */ + if (!(in_sdram || warm_reset())) { + if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + lpddr2_init(base, regs); + else + ddr3_init(base, regs); + } + if (warm_reset() && (emif_sdram_type() == EMIF_SDRAM_TYPE_DDR3)) { + set_lpmode_selfrefresh(base); + emif_reset_phy(base); + ddr3_leveling(base, regs); + } + + /* Write to the shadow registers */ + emif_update_timings(base, regs); + + debug("<<do_sdram_init() %x\n", base); +} + +void emif_post_init_config(u32 base) +{ + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + u32 omap_rev = omap_revision(); + + /* reset phy on ES2.0 */ + if (omap_rev == OMAP4430_ES2_0) + emif_reset_phy(base); + + /* Put EMIF back in smart idle on ES1.0 */ + if (omap_rev == OMAP4430_ES1_0) + writel(0x80000000, &emif->emif_pwr_mgmt_ctrl); +} + +void dmm_init(u32 base) +{ + const struct dmm_lisa_map_regs *lisa_map_regs; + u32 i, section, valid; + +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS + emif_get_dmm_regs(&lisa_map_regs); +#else + u32 emif1_size, emif2_size, mapped_size, section_map = 0; + u32 section_cnt, sys_addr; + struct dmm_lisa_map_regs lis_map_regs_calculated = {0}; + + mapped_size = 0; + section_cnt = 3; + sys_addr = CONFIG_SYS_SDRAM_BASE; + emif1_size = get_emif_mem_size(EMIF1_BASE); + emif2_size = get_emif_mem_size(EMIF2_BASE); + debug("emif1_size 0x%x emif2_size 0x%x\n", emif1_size, emif2_size); + + if (!emif1_size && !emif2_size) + return; + + /* symmetric interleaved section */ + if (emif1_size && emif2_size) { + mapped_size = min(emif1_size, emif2_size); + section_map = DMM_LISA_MAP_INTERLEAVED_BASE_VAL; + section_map |= 0 << EMIF_SDRC_ADDR_SHIFT; + /* only MSB */ + section_map |= (sys_addr >> 24) << + EMIF_SYS_ADDR_SHIFT; + section_map |= get_dmm_section_size_map(mapped_size * 2) + << EMIF_SYS_SIZE_SHIFT; + lis_map_regs_calculated.dmm_lisa_map_3 = section_map; + emif1_size -= mapped_size; + emif2_size -= mapped_size; + sys_addr += (mapped_size * 2); + section_cnt--; + } + + /* + * Single EMIF section(we can have a maximum of 1 single EMIF + * section- either EMIF1 or EMIF2 or none, but not both) + */ + if (emif1_size) { + section_map = DMM_LISA_MAP_EMIF1_ONLY_BASE_VAL; + section_map |= get_dmm_section_size_map(emif1_size) + << EMIF_SYS_SIZE_SHIFT; + /* only MSB */ + section_map |= (mapped_size >> 24) << + EMIF_SDRC_ADDR_SHIFT; + /* only MSB */ + section_map |= (sys_addr >> 24) << EMIF_SYS_ADDR_SHIFT; + section_cnt--; + } + if (emif2_size) { + section_map = DMM_LISA_MAP_EMIF2_ONLY_BASE_VAL; + section_map |= get_dmm_section_size_map(emif2_size) << + EMIF_SYS_SIZE_SHIFT; + /* only MSB */ + section_map |= mapped_size >> 24 << EMIF_SDRC_ADDR_SHIFT; + /* only MSB */ + section_map |= sys_addr >> 24 << EMIF_SYS_ADDR_SHIFT; + section_cnt--; + } + + if (section_cnt == 2) { + /* Only 1 section - either symmetric or single EMIF */ + lis_map_regs_calculated.dmm_lisa_map_3 = section_map; + lis_map_regs_calculated.dmm_lisa_map_2 = 0; + lis_map_regs_calculated.dmm_lisa_map_1 = 0; + } else { + /* 2 sections - 1 symmetric, 1 single EMIF */ + lis_map_regs_calculated.dmm_lisa_map_2 = section_map; + lis_map_regs_calculated.dmm_lisa_map_1 = 0; + } + + /* TRAP for invalid TILER mappings in section 0 */ + lis_map_regs_calculated.dmm_lisa_map_0 = DMM_LISA_MAP_0_INVAL_ADDR_TRAP; + + if (omap_revision() >= OMAP4460_ES1_0) + lis_map_regs_calculated.is_ma_present = 1; + + lisa_map_regs = &lis_map_regs_calculated; +#endif + struct dmm_lisa_map_regs *hw_lisa_map_regs = + (struct dmm_lisa_map_regs *)base; + + writel(0, &hw_lisa_map_regs->dmm_lisa_map_3); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_2); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_1); + writel(0, &hw_lisa_map_regs->dmm_lisa_map_0); + + writel(lisa_map_regs->dmm_lisa_map_3, + &hw_lisa_map_regs->dmm_lisa_map_3); + writel(lisa_map_regs->dmm_lisa_map_2, + &hw_lisa_map_regs->dmm_lisa_map_2); + writel(lisa_map_regs->dmm_lisa_map_1, + &hw_lisa_map_regs->dmm_lisa_map_1); + writel(lisa_map_regs->dmm_lisa_map_0, + &hw_lisa_map_regs->dmm_lisa_map_0); + + if (lisa_map_regs->is_ma_present) { + hw_lisa_map_regs = + (struct dmm_lisa_map_regs *)MA_BASE; + + writel(lisa_map_regs->dmm_lisa_map_3, + &hw_lisa_map_regs->dmm_lisa_map_3); + writel(lisa_map_regs->dmm_lisa_map_2, + &hw_lisa_map_regs->dmm_lisa_map_2); + writel(lisa_map_regs->dmm_lisa_map_1, + &hw_lisa_map_regs->dmm_lisa_map_1); + writel(lisa_map_regs->dmm_lisa_map_0, + &hw_lisa_map_regs->dmm_lisa_map_0); + } + + /* + * EMIF should be configured only when + * memory is mapped on it. Using emif1_enabled + * and emif2_enabled variables for this. + */ + emif1_enabled = 0; + emif2_enabled = 0; + for (i = 0; i < 4; i++) { + section = __raw_readl(DMM_BASE + i*4); + valid = (section & EMIF_SDRC_MAP_MASK) >> + (EMIF_SDRC_MAP_SHIFT); + if (valid == 3) { + emif1_enabled = 1; + emif2_enabled = 1; + break; + } + + if (valid == 1) + emif1_enabled = 1; + + if (valid == 2) + emif2_enabled = 1; + } +} + +static void do_bug0039_workaround(u32 base) +{ + u32 val, i, clkctrl; + struct emif_reg_struct *emif_base = (struct emif_reg_struct *)base; + const struct read_write_regs *bug_00339_regs; + u32 iterations; + u32 *phy_status_base = &emif_base->emif_ddr_phy_status[0]; + u32 *phy_ctrl_base = &emif_base->emif_ddr_ext_phy_ctrl_1; + + if (is_dra7xx()) + phy_status_base++; + + bug_00339_regs = get_bug_regs(&iterations); + + /* Put EMIF in to idle */ + clkctrl = __raw_readl((*prcm)->cm_memif_clkstctrl); + __raw_writel(0x0, (*prcm)->cm_memif_clkstctrl); + + /* Copy the phy status registers in to phy ctrl shadow registers */ + for (i = 0; i < iterations; i++) { + val = __raw_readl(phy_status_base + + bug_00339_regs[i].read_reg - 1); + + __raw_writel(val, phy_ctrl_base + + ((bug_00339_regs[i].write_reg - 1) << 1)); + + __raw_writel(val, phy_ctrl_base + + (bug_00339_regs[i].write_reg << 1) - 1); + } + + /* Disable leveling */ + writel(0x0, &emif_base->emif_rd_wr_lvl_rmp_ctl); + + __raw_writel(clkctrl, (*prcm)->cm_memif_clkstctrl); +} + +/* + * SDRAM initialization: + * SDRAM initialization has two parts: + * 1. Configuring the SDRAM device + * 2. Update the AC timings related parameters in the EMIF module + * (1) should be done only once and should not be done while we are + * running from SDRAM. + * (2) can and should be done more than once if OPP changes. + * Particularly, this may be needed when we boot without SPL and + * and using Configuration Header(CH). ROM code supports only at 50% OPP + * at boot (low power boot). So u-boot has to switch to OPP100 and update + * the frequency. So, + * Doing (1) and (2) makes sense - first time initialization + * Doing (2) and not (1) makes sense - OPP change (when using CH) + * Doing (1) and not (2) doen't make sense + * See do_sdram_init() for the details + */ +void sdram_init(void) +{ + u32 in_sdram, size_prog, size_detect; + u32 sdram_type = emif_sdram_type(); + + debug(">>sdram_init()\n"); + + if (omap_hw_init_context() == OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL) + return; + + in_sdram = running_from_sdram(); + debug("in_sdram = %d\n", in_sdram); + + if (!in_sdram) { + if ((sdram_type == EMIF_SDRAM_TYPE_LPDDR2) && !warm_reset()) + bypass_dpll((*prcm)->cm_clkmode_dpll_core); + else if (sdram_type == EMIF_SDRAM_TYPE_DDR3) + writel(CM_DLL_CTRL_NO_OVERRIDE, (*prcm)->cm_dll_ctrl); + } + + if (!in_sdram) + dmm_init(DMM_BASE); + + if (emif1_enabled) + do_sdram_init(EMIF1_BASE); + + if (emif2_enabled) + do_sdram_init(EMIF2_BASE); + + if (!(in_sdram || warm_reset())) { + if (emif1_enabled) + emif_post_init_config(EMIF1_BASE); + if (emif2_enabled) + emif_post_init_config(EMIF2_BASE); + } + + /* for the shadow registers to take effect */ + if (sdram_type == EMIF_SDRAM_TYPE_LPDDR2) + freq_update_core(); + + /* Do some testing after the init */ + if (!in_sdram) { + size_prog = omap_sdram_size(); + size_prog = log_2_n_round_down(size_prog); + size_prog = (1 << size_prog); + + size_detect = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, + size_prog); + /* Compare with the size programmed */ + if (size_detect != size_prog) { + printf("SDRAM: identified size not same as expected" + " size identified: %x expected: %x\n", + size_detect, + size_prog); + } else + debug("get_ram_size() successful"); + } + + if (sdram_type == EMIF_SDRAM_TYPE_DDR3 && + (!in_sdram && !warm_reset()) && (!is_dra7xx())) { + if (emif1_enabled) + do_bug0039_workaround(EMIF1_BASE); + if (emif2_enabled) + do_bug0039_workaround(EMIF2_BASE); + } + + debug("<<sdram_init()\n"); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/hwinit-common.c new file mode 100644 index 0000000..6c8f3bc --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -0,0 +1,257 @@ +/* + * + * Common functions for OMAP4/5 based boards + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * Steve Sakoman <steve@sakoman.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <spl.h> +#include <asm/arch/sys_proto.h> +#include <linux/sizes.h> +#include <asm/emif.h> +#include <asm/omap_common.h> +#include <linux/compiler.h> +#include <asm/system.h> + +DECLARE_GLOBAL_DATA_PTR; + +void do_set_mux(u32 base, struct pad_conf_entry const *array, int size) +{ + int i; + struct pad_conf_entry *pad = (struct pad_conf_entry *) array; + + for (i = 0; i < size; i++, pad++) + writew(pad->val, base + pad->offset); +} + +static void set_mux_conf_regs(void) +{ + switch (omap_hw_init_context()) { + case OMAP_INIT_CONTEXT_SPL: + set_muxconf_regs_essential(); + break; + case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL: + break; + case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: + case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: + set_muxconf_regs_essential(); + break; + } +} + +u32 cortex_rev(void) +{ + + unsigned int rev; + + /* Read Main ID Register (MIDR) */ + asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev)); + + return rev; +} + +static void omap_rev_string(void) +{ + u32 omap_rev = omap_revision(); + u32 soc_variant = (omap_rev & 0xF0000000) >> 28; + u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16; + u32 major_rev = (omap_rev & 0x00000F00) >> 8; + u32 minor_rev = (omap_rev & 0x000000F0) >> 4; + + if (soc_variant) + printf("OMAP"); + else + printf("DRA"); + printf("%x ES%x.%x\n", omap_variant, major_rev, + minor_rev); +} + +#ifdef CONFIG_SPL_BUILD +void spl_display_print(void) +{ + omap_rev_string(); +} +#endif + +void __weak srcomp_enable(void) +{ +} + +#ifdef CONFIG_ARCH_CPU_INIT +/* + * SOC specific cpu init + */ +int arch_cpu_init(void) +{ + save_omap_boot_params(); + return 0; +} +#endif /* CONFIG_ARCH_CPU_INIT */ + +/* + * Routine: s_init + * Description: Does early system init of watchdog, muxing, andclocks + * Watchdog disable is done always. For the rest what gets done + * depends on the boot mode in which this function is executed + * 1. s_init of SPL running from SRAM + * 2. s_init of U-Boot running from FLASH + * 3. s_init of U-Boot loaded to SDRAM by SPL + * 4. s_init of U-Boot loaded to SDRAM by ROM code using the + * Configuration Header feature + * Please have a look at the respective functions to see what gets + * done in each of these cases + * This function is called with SRAM stack. + */ +void s_init(void) +{ + init_omap_revision(); + hw_data_init(); + +#ifdef CONFIG_SPL_BUILD + if (warm_reset() && + (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0))) + force_emif_self_refresh(); +#endif + watchdog_init(); + set_mux_conf_regs(); +#ifdef CONFIG_SPL_BUILD + srcomp_enable(); + setup_clocks_for_console(); + + do_io_settings(); +#endif + prcm_init(); +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ +#ifdef CONFIG_BOARD_EARLY_INIT_F + board_early_init_f(); +#endif + /* For regular u-boot sdram_init() is called from dram_init() */ + sdram_init(); +} +#endif + +/* + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + */ +void wait_for_command_complete(struct watchdog *wd_base) +{ + int pending = 1; + do { + pending = readl(&wd_base->wwps); + } while (pending); +} + +/* + * Routine: watchdog_init + * Description: Shut down watch dogs + */ +void watchdog_init(void) +{ + struct watchdog *wd2_base = (struct watchdog *)WDT2_BASE; + + writel(WD_UNLOCK1, &wd2_base->wspr); + wait_for_command_complete(wd2_base); + writel(WD_UNLOCK2, &wd2_base->wspr); +} + + +/* + * This function finds the SDRAM size available in the system + * based on DMM section configurations + * This is needed because the size of memory installed may be + * different on different versions of the board + */ +u32 omap_sdram_size(void) +{ + u32 section, i, valid; + u64 sdram_start = 0, sdram_end = 0, addr, + size, total_size = 0, trap_size = 0, trap_start = 0; + + for (i = 0; i < 4; i++) { + section = __raw_readl(DMM_BASE + i*4); + valid = (section & EMIF_SDRC_ADDRSPC_MASK) >> + (EMIF_SDRC_ADDRSPC_SHIFT); + addr = section & EMIF_SYS_ADDR_MASK; + + /* See if the address is valid */ + if ((addr >= TI_ARMV7_DRAM_ADDR_SPACE_START) && + (addr < TI_ARMV7_DRAM_ADDR_SPACE_END)) { + size = ((section & EMIF_SYS_SIZE_MASK) >> + EMIF_SYS_SIZE_SHIFT); + size = 1 << size; + size *= SZ_16M; + + if (valid != DMM_SDRC_ADDR_SPC_INVALID) { + if (!sdram_start || (addr < sdram_start)) + sdram_start = addr; + if (!sdram_end || ((addr + size) > sdram_end)) + sdram_end = addr + size; + } else { + trap_size = size; + trap_start = addr; + } + } + } + + if ((trap_start >= sdram_start) && (trap_start < sdram_end)) + total_size = (sdram_end - sdram_start) - (trap_size); + else + total_size = sdram_end - sdram_start; + + return total_size; +} + + +/* + * Routine: dram_init + * Description: sets uboots idea of sdram size + */ +int dram_init(void) +{ + sdram_init(); + gd->ram_size = omap_sdram_size(); + return 0; +} + +/* + * Print board information + */ +int checkboard(void) +{ + puts(sysinfo.board_string); + return 0; +} + +/* + * get_device_type(): tell if GP/HS/EMU/TST + */ +u32 get_device_type(void) +{ + return (readl((*ctrl)->control_status) & + (DEVICE_TYPE_MASK)) >> DEVICE_TYPE_SHIFT; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +/* + * Print CPU information + */ +int print_cpuinfo(void) +{ + puts("CPU : "); + omap_rev_string(); + + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/omap-common/lowlevel_init.S new file mode 100644 index 0000000..746df92 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -0,0 +1,38 @@ +/* + * Board specific setup info + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arch/omap.h> +#include <asm/omap_common.h> +#include <asm/arch/spl.h> +#include <linux/linkage.h> + +#ifndef CONFIG_OMAP34XX +ENTRY(save_boot_params) + ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS + str r0, [r1] + b save_boot_params_ret +ENDPROC(save_boot_params) +#endif + +ENTRY(omap_smc1) + PUSH {r4-r12, lr} @ save registers - ROM code may pollute + @ our registers + MOV r12, r0 @ Service + MOV r0, r1 @ Argument + DSB + DMB + .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions + @ call ROM Code API for the service requested + + POP {r4-r12, pc} +ENDPROC(omap_smc1)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/mem-common.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/mem-common.c new file mode 100644 index 0000000..fc4290c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/mem-common.c
@@ -0,0 +1,144 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Mansoor Ahamed <mansoor.ahamed@ti.com> + * + * Initial Code from: + * Manikandan Pillai <mani.pillai@ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <command.h> +#include <linux/mtd/omap_gpmc.h> + +struct gpmc *gpmc_cfg; + +#if defined(CONFIG_OMAP34XX) +/******************************************************** + * mem_ok() - test used to see if timings are correct + * for a part. Helps in guessing which part + * we are currently using. + *******************************************************/ +u32 mem_ok(u32 cs) +{ + u32 val1, val2, addr; + u32 pattern = 0x12345678; + + addr = OMAP34XX_SDRC_CS0 + get_sdr_cs_offset(cs); + + writel(0x0, addr + 0x400); /* clear pos A */ + writel(pattern, addr); /* pattern to pos B */ + writel(0x0, addr + 4); /* remove pattern off the bus */ + val1 = readl(addr + 0x400); /* get pos A value */ + val2 = readl(addr); /* get val2 */ + writel(0x0, addr + 0x400); /* clear pos A */ + + if ((val1 != 0) || (val2 != pattern)) /* see if pos A val changed */ + return 0; + else + return 1; +} +#endif + +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base, + u32 size) +{ + writel(0, &cs->config7); + sdelay(1000); + /* Delay for settling */ + writel(gpmc_config[0], &cs->config1); + writel(gpmc_config[1], &cs->config2); + writel(gpmc_config[2], &cs->config3); + writel(gpmc_config[3], &cs->config4); + writel(gpmc_config[4], &cs->config5); + writel(gpmc_config[5], &cs->config6); + /* Enable the config */ + writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) | + (1 << 6)), &cs->config7); + sdelay(2000); +} + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ + /* putting a blanket check on GPMC based on ZeBu for now */ + gpmc_cfg = (struct gpmc *)GPMC_BASE; +#if defined(CONFIG_NOR) +/* configure GPMC for NOR */ + const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1, + STNOR_GPMC_CONFIG2, + STNOR_GPMC_CONFIG3, + STNOR_GPMC_CONFIG4, + STNOR_GPMC_CONFIG5, + STNOR_GPMC_CONFIG6, + STNOR_GPMC_CONFIG7 + }; + u32 base = CONFIG_SYS_FLASH_BASE; + u32 size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M : + /* > 64MB */ ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M : + /* > 32MB */ ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M : + /* > 16MB */ ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M : + /* min 16MB */ GPMC_SIZE_16M))); +#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND) +/* configure GPMC for NAND */ + const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1, + M_NAND_GPMC_CONFIG2, + M_NAND_GPMC_CONFIG3, + M_NAND_GPMC_CONFIG4, + M_NAND_GPMC_CONFIG5, + M_NAND_GPMC_CONFIG6, + 0 + }; + u32 base = CONFIG_SYS_NAND_BASE; + u32 size = GPMC_SIZE_16M; + +#elif defined(CONFIG_CMD_ONENAND) + const u32 gpmc_regs[GPMC_MAX_REG] = { ONENAND_GPMC_CONFIG1, + ONENAND_GPMC_CONFIG2, + ONENAND_GPMC_CONFIG3, + ONENAND_GPMC_CONFIG4, + ONENAND_GPMC_CONFIG5, + ONENAND_GPMC_CONFIG6, + 0 + }; + u32 size = GPMC_SIZE_128M; + u32 base = CONFIG_SYS_ONENAND_BASE; +#else + const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 }; + u32 size = 0; + u32 base = 0; +#endif + /* global settings */ + writel(0x00000008, &gpmc_cfg->sysconfig); + writel(0x00000000, &gpmc_cfg->irqstatus); + writel(0x00000000, &gpmc_cfg->irqenable); + /* disable timeout, set a safe reset value */ + writel(0x00001ff0, &gpmc_cfg->timeout_control); +#ifdef CONFIG_NOR + writel(0x00000200, &gpmc_cfg->config); +#else + writel(0x00000012, &gpmc_cfg->config); +#endif + /* + * Disable the GPMC0 config set by ROM code + */ + writel(0, &gpmc_cfg->cs[0].config7); + sdelay(1000); + /* enable chip-select specific configurations */ + if (base != 0) + enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/omap-cache.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/omap-cache.c new file mode 100644 index 0000000..579bebf --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/omap-cache.c
@@ -0,0 +1,56 @@ +/* + * + * Common functions for OMAP4/5 based boards + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * Steve Sakoman <steve@sakoman.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cache.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define ARMV7_DCACHE_WRITEBACK 0xe +#define ARMV7_DOMAIN_CLIENT 1 +#define ARMV7_DOMAIN_MASK (0x3 << 0) + +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} + +void dram_bank_mmu_setup(int bank) +{ + bd_t *bd = gd->bd; + int i; + + u32 start = bd->bi_dram[bank].start >> 20; + u32 size = bd->bi_dram[bank].size >> 20; + u32 end = start + size; + + debug("%s: bank: %d\n", __func__, bank); + for (i = start; i < end; i++) + set_section_dcache(i, ARMV7_DCACHE_WRITEBACK); +} + +void arm_init_domains(void) +{ + u32 reg; + + reg = get_dacr(); + /* + * Set DOMAIN to client access so that all permissions + * set in pagetables are validated by the mmu. + */ + reg &= ~ARMV7_DOMAIN_MASK; + reg |= ARMV7_DOMAIN_CLIENT; + set_dacr(reg); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.c new file mode 100644 index 0000000..b71d769 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.c
@@ -0,0 +1,231 @@ +/* + * TI PIPE3 PHY + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <sata.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/errno.h> +#include "pipe3-phy.h" + +/* PLLCTRL Registers */ +#define PLL_STATUS 0x00000004 +#define PLL_GO 0x00000008 +#define PLL_CONFIGURATION1 0x0000000C +#define PLL_CONFIGURATION2 0x00000010 +#define PLL_CONFIGURATION3 0x00000014 +#define PLL_CONFIGURATION4 0x00000020 + +#define PLL_REGM_MASK 0x001FFE00 +#define PLL_REGM_SHIFT 9 +#define PLL_REGM_F_MASK 0x0003FFFF +#define PLL_REGM_F_SHIFT 0 +#define PLL_REGN_MASK 0x000001FE +#define PLL_REGN_SHIFT 1 +#define PLL_SELFREQDCO_MASK 0x0000000E +#define PLL_SELFREQDCO_SHIFT 1 +#define PLL_SD_MASK 0x0003FC00 +#define PLL_SD_SHIFT 10 +#define SET_PLL_GO 0x1 +#define PLL_TICOPWDN BIT(16) +#define PLL_LDOPWDN BIT(15) +#define PLL_LOCK 0x2 +#define PLL_IDLE 0x1 + +/* PHY POWER CONTROL Register */ +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE + +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 + +#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 +#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 + + +#define PLL_IDLE_TIME 100 /* in milliseconds */ +#define PLL_LOCK_TIME 100 /* in milliseconds */ + +static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset) +{ + return __raw_readl(addr + offset); +} + +static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset, + u32 data) +{ + __raw_writel(data, addr + offset); +} + +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3 + *pipe3) +{ + u32 rate; + struct pipe3_dpll_map *dpll_map = pipe3->dpll_map; + + rate = get_sys_clk_freq(); + + for (; dpll_map->rate; dpll_map++) { + if (rate == dpll_map->rate) + return &dpll_map->params; + } + + printf("%s: No DPLL configuration for %u Hz SYS CLK\n", + __func__, rate); + return NULL; +} + + +static int omap_pipe3_wait_lock(struct omap_pipe3 *phy) +{ + u32 val; + int timeout = PLL_LOCK_TIME; + + do { + mdelay(1); + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if (val & PLL_LOCK) + break; + } while (--timeout); + + if (!(val & PLL_LOCK)) { + printf("%s: DPLL failed to lock\n", __func__); + return -EBUSY; + } + + return 0; +} + +static int omap_pipe3_dpll_program(struct omap_pipe3 *phy) +{ + u32 val; + struct pipe3_dpll_params *dpll_params; + + dpll_params = omap_pipe3_get_dpll_params(phy); + if (!dpll_params) { + printf("%s: Invalid DPLL parameters\n", __func__); + return -EINVAL; + } + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGN_MASK; + val |= dpll_params->n << PLL_REGN_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val &= ~PLL_SELFREQDCO_MASK; + val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGM_MASK; + val |= dpll_params->m << PLL_REGM_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); + val &= ~PLL_REGM_F_MASK; + val |= dpll_params->mf << PLL_REGM_F_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); + val &= ~PLL_SD_MASK; + val |= dpll_params->sd << PLL_SD_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); + + omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); + + return omap_pipe3_wait_lock(phy); +} + +static void omap_control_phy_power(struct omap_pipe3 *phy, int on) +{ + u32 val, rate; + + val = readl(phy->power_reg); + + rate = get_sys_clk_freq(); + rate = rate/1000000; + + if (on) { + val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); + val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + val |= rate << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; + } else { + val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; + val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + } + + writel(val, phy->power_reg); +} + +int phy_pipe3_power_on(struct omap_pipe3 *phy) +{ + int ret; + u32 val; + + /* Program the DPLL only if not locked */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if (!(val & PLL_LOCK)) { + ret = omap_pipe3_dpll_program(phy); + if (ret) + return ret; + } else { + /* else just bring it out of IDLE mode */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + if (val & PLL_IDLE) { + val &= ~PLL_IDLE; + omap_pipe3_writel(phy->pll_ctrl_base, + PLL_CONFIGURATION2, val); + ret = omap_pipe3_wait_lock(phy); + if (ret) + return ret; + } + } + + /* Power up the PHY */ + omap_control_phy_power(phy, 1); + + return 0; +} + +int phy_pipe3_power_off(struct omap_pipe3 *phy) +{ + u32 val; + int timeout = PLL_IDLE_TIME; + + /* Power down the PHY */ + omap_control_phy_power(phy, 0); + + /* Put DPLL in IDLE mode */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val |= PLL_IDLE; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + /* wait for LDO and Oscillator to power down */ + do { + mdelay(1); + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) + break; + } while (--timeout); + + if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { + printf("%s: Failed to power down DPLL: PLL_STATUS 0x%x\n", + __func__, val); + return -EBUSY; + } + + return 0; +} +
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.h b/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.h new file mode 100644 index 0000000..441f49a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/pipe3-phy.h
@@ -0,0 +1,36 @@ +/* + * TI PIPE3 PHY + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __OMAP_PIPE3_PHY_H +#define __OMAP_PIPE3_PHY_H + +struct pipe3_dpll_params { + u16 m; + u8 n; + u8 freq:3; + u8 sd; + u32 mf; +}; + +struct pipe3_dpll_map { + unsigned long rate; + struct pipe3_dpll_params params; +}; + +struct omap_pipe3 { + void __iomem *pll_ctrl_base; + void __iomem *power_reg; + struct pipe3_dpll_map *dpll_map; +}; + + +int phy_pipe3_power_on(struct omap_pipe3 *phy); +int phy_pipe3_power_off(struct omap_pipe3 *pipe3); + +#endif /* __OMAP_PIPE3_PHY_H */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/reset.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/reset.c new file mode 100644 index 0000000..91ad031 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/reset.c
@@ -0,0 +1,29 @@ +/* + * + * Common layer for reset related functionality of OMAP based socs. + * + * (C) Copyright 2012 + * Texas Instruments, <www.ti.com> + * + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <config.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <linux/compiler.h> + +void __weak reset_cpu(unsigned long ignored) +{ + writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL); +} + +u32 __weak warm_reset(void) +{ + return (readl(PRM_RSTST) & PRM_RSTST_WARM_RESET_MASK); +} + +void __weak setup_warmreset_time(void) +{ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/sata.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/sata.c new file mode 100644 index 0000000..d18bc50 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/sata.c
@@ -0,0 +1,93 @@ +/* + * TI SATA platform driver + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <ahci.h> +#include <scsi.h> +#include <asm/arch/clock.h> +#include <asm/arch/sata.h> +#include <sata.h> +#include <asm/io.h> +#include "pipe3-phy.h" + +static struct pipe3_dpll_map dpll_map_sata[] = { + {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ + {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ + {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ + {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ + {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ + {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ + { }, /* Terminator */ +}; + +struct omap_pipe3 sata_phy = { + .pll_ctrl_base = (void __iomem *)TI_SATA_PLLCTRL_BASE, + /* .power_reg is updated at runtime */ + .dpll_map = dpll_map_sata, +}; + +int init_sata(int dev) +{ + int ret; + u32 val; + + u32 const clk_domains_sata[] = { + 0 + }; + + u32 const clk_modules_hw_auto_sata[] = { + (*prcm)->cm_l3init_ocp2scp3_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_sata[] = { + (*prcm)->cm_l3init_sata_clkctrl, + 0 + }; + + do_enable_clocks(clk_domains_sata, + clk_modules_hw_auto_sata, + clk_modules_explicit_en_sata, + 0); + + /* Enable optional functional clock for SATA */ + setbits_le32((*prcm)->cm_l3init_sata_clkctrl, + SATA_CLKCTRL_OPTFCLKEN_MASK); + + sata_phy.power_reg = (void __iomem *)(*ctrl)->control_phy_power_sata; + + /* Power up the PHY */ + phy_pipe3_power_on(&sata_phy); + + /* Enable SATA module, No Idle, No Standby */ + val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO; + writel(val, TI_SATA_WRAPPER_BASE + TI_SATA_SYSCONFIG); + + ret = ahci_init(DWC_AHSATA_BASE); + + return ret; +} + +int reset_sata(int dev) +{ + return 0; +} + +/* On OMAP platforms SATA provides the SCSI subsystem */ +void scsi_init(void) +{ + init_sata(0); + scsi_scan(1); +} + +void scsi_bus_reset(void) +{ + ahci_reset(DWC_AHSATA_BASE); + ahci_init(DWC_AHSATA_BASE); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/timer.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/timer.c new file mode 100644 index 0000000..032bd2c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/timer.c
@@ -0,0 +1,103 @@ +/* + * (C) Copyright 2008 + * Texas Instruments + * + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Moahmmed Khasim <khasim@ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * Alex Zuepke <azu@sysgo.de> + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/clock.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE; + +/* + * Nothing really to do with interrupts, just starts up a counter. + */ + +#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) +#define TIMER_OVERFLOW_VAL 0xffffffff +#define TIMER_LOAD_VAL 0 + +int timer_init(void) +{ + /* start the counter ticking up, reload value on overflow */ + writel(TIMER_LOAD_VAL, &timer_base->tldr); + /* enable timer */ + writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST, + &timer_base->tclr); + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + long tmo = usec * (TIMER_CLOCK / 1000) / 1000; + unsigned long now, last = readl(&timer_base->tcrr); + + while (tmo > 0) { + now = readl(&timer_base->tcrr); + if (last > now) /* count up timer overflow */ + tmo -= TIMER_OVERFLOW_VAL - last + now + 1; + else + tmo -= now - last; + last = now; + } +} + +ulong get_timer_masked(void) +{ + /* current tick value */ + ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + + if (now >= gd->arch.lastinc) { /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + gd->arch.tbl += (now - gd->arch.lastinc); + } else { /* we have rollover of incrementer */ + gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK / + CONFIG_SYS_HZ)) - gd->arch.lastinc) + now; + } + gd->arch.lastinc = now; + return gd->arch.tbl; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds new file mode 100644 index 0000000..ccd0c83 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds
@@ -0,0 +1,57 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ + LENGTH = CONFIG_SPL_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + .text : + { + __start = .; + *(.vectors) + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*_i2c_*))); + } >.sram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } + + .bss : + { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/utils.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/utils.c new file mode 100644 index 0000000..1696c2d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/utils.c
@@ -0,0 +1,62 @@ +/* + * Copyright 2011 Linaro Limited + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/sys_proto.h> +static void do_cancel_out(u32 *num, u32 *den, u32 factor) +{ + while (1) { + if (((*num)/factor*factor == (*num)) && + ((*den)/factor*factor == (*den))) { + (*num) /= factor; + (*den) /= factor; + } else + break; + } +} + +/* + * Cancel out the denominator and numerator of a fraction + * to get smaller numerator and denominator. + */ +void cancel_out(u32 *num, u32 *den, u32 den_limit) +{ + do_cancel_out(num, den, 2); + do_cancel_out(num, den, 3); + do_cancel_out(num, den, 5); + do_cancel_out(num, den, 7); + do_cancel_out(num, den, 11); + do_cancel_out(num, den, 13); + do_cancel_out(num, den, 17); + while ((*den) > den_limit) { + *num /= 2; + /* + * Round up the denominator so that the final fraction + * (num/den) is always <= the desired value + */ + *den = (*den + 1) / 2; + } +} + +void __weak usb_fake_mac_from_die_id(u32 *id) +{ + uint8_t device_mac[6]; + + if (!getenv("usbethaddr")) { + /* + * create a fake MAC address from the processor ID code. + * first byte is 0x02 to signify locally administered. + */ + device_mac[0] = 0x02; + device_mac[1] = id[3] & 0xff; + device_mac[2] = id[2] & 0xff; + device_mac[3] = id[1] & 0xff; + device_mac[4] = id[0] & 0xff; + device_mac[5] = (id[0] >> 8) & 0xff; + + eth_setenv_enetaddr("usbethaddr", device_mac); + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap-common/vc.c b/u-boot-imx/arch/arm/cpu/armv7/omap-common/vc.c new file mode 100644 index 0000000..a68f1d1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap-common/vc.c
@@ -0,0 +1,151 @@ +/* + * Voltage Controller implementation for OMAP + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * Nishanth Menon + * + * 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. + */ + +#include <common.h> +#include <asm/omap_common.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/clock.h> + +/* + * Define Master code if there are multiple masters on the I2C_SR bus. + * Normally not required + */ +#ifndef CONFIG_OMAP_VC_I2C_HS_MCODE +#define CONFIG_OMAP_VC_I2C_HS_MCODE 0x0 +#endif + +/* Register defines and masks for VC IP Block */ +/* PRM_VC_CFG_I2C_MODE */ +#define PRM_VC_CFG_I2C_MODE_DFILTEREN_BIT (0x1 << 6) +#define PRM_VC_CFG_I2C_MODE_SRMODEEN_BIT (0x1 << 4) +#define PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT (0x1 << 3) +#define PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT 0x0 +#define PRM_VC_CFG_I2C_MODE_HSMCODE_MASK 0x3 + +/* PRM_VC_CFG_I2C_CLK */ +#define PRM_VC_CFG_I2C_CLK_HSCLL_SHIFT 24 +#define PRM_VC_CFG_I2C_CLK_HSCLL_MASK 0xFF +#define PRM_VC_CFG_I2C_CLK_HSCLH_SHIFT 16 +#define PRM_VC_CFG_I2C_CLK_HSCLH_MASK 0xFF +#define PRM_VC_CFG_I2C_CLK_SCLH_SHIFT 0 +#define PRM_VC_CFG_I2C_CLK_SCLH_MASK 0xFF +#define PRM_VC_CFG_I2C_CLK_SCLL_SHIFT 8 +#define PRM_VC_CFG_I2C_CLK_SCLL_MASK (0xFF << 8) + +/* PRM_VC_VAL_BYPASS */ +#define PRM_VC_VAL_BYPASS_VALID_BIT (0x1 << 24) +#define PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT 0 +#define PRM_VC_VAL_BYPASS_SLAVEADDR_MASK 0x7F +#define PRM_VC_VAL_BYPASS_REGADDR_SHIFT 8 +#define PRM_VC_VAL_BYPASS_REGADDR_MASK 0xFF +#define PRM_VC_VAL_BYPASS_DATA_SHIFT 16 +#define PRM_VC_VAL_BYPASS_DATA_MASK 0xFF + +/** + * omap_vc_init() - Initialization for Voltage controller + * @speed_khz: I2C buspeed in KHz + */ +static void omap_vc_init(u16 speed_khz) +{ + u32 val; + u32 sys_clk_khz, cycles_hi, cycles_low; + + sys_clk_khz = get_sys_clk_freq() / 1000; + + if (speed_khz > 400) { + puts("higher speed requested - throttle to 400Khz\n"); + speed_khz = 400; + } + + /* + * Setup the dedicated I2C controller for Voltage Control + * I2C clk - high period 40% low period 60% + */ + speed_khz /= 10; + cycles_hi = sys_clk_khz * 4 / speed_khz; + cycles_low = sys_clk_khz * 6 / speed_khz; + /* values to be set in register - less by 5 & 7 respectively */ + cycles_hi -= 5; + cycles_low -= 7; + val = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) | + (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT); + writel(val, (*prcm)->prm_vc_cfg_i2c_clk); + + val = CONFIG_OMAP_VC_I2C_HS_MCODE << + PRM_VC_CFG_I2C_MODE_HSMCODE_SHIFT; + /* No HS mode for now */ + val &= ~PRM_VC_CFG_I2C_MODE_HSMODEEN_BIT; + writel(val, (*prcm)->prm_vc_cfg_i2c_mode); +} + +/** + * omap_vc_bypass_send_value() - Send a data using VC Bypass command + * @sa: 7 bit I2C slave address of the PMIC + * @reg_addr: I2C register address(8 bit) address in PMIC + * @reg_data: what 8 bit data to write + */ +int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data) +{ + /* + * Unfortunately we need to loop here instead of a defined time + * use arbitary large value + */ + u32 timeout = 0xFFFF; + u32 reg_val; + + sa &= PRM_VC_VAL_BYPASS_SLAVEADDR_MASK; + reg_addr &= PRM_VC_VAL_BYPASS_REGADDR_MASK; + reg_data &= PRM_VC_VAL_BYPASS_DATA_MASK; + + /* program VC to send data */ + reg_val = sa << PRM_VC_VAL_BYPASS_SLAVEADDR_SHIFT | + reg_addr << PRM_VC_VAL_BYPASS_REGADDR_SHIFT | + reg_data << PRM_VC_VAL_BYPASS_DATA_SHIFT; + writel(reg_val, (*prcm)->prm_vc_val_bypass); + + /* Signal VC to send data */ + writel(reg_val | PRM_VC_VAL_BYPASS_VALID_BIT, + (*prcm)->prm_vc_val_bypass); + + /* Wait on VC to complete transmission */ + do { + reg_val = readl((*prcm)->prm_vc_val_bypass) & + PRM_VC_VAL_BYPASS_VALID_BIT; + if (!reg_val) + break; + + sdelay(100); + } while (--timeout); + + /* Optional: cleanup PRM_IRQSTATUS_Ax */ + /* In case we can do something about it in future.. */ + if (!timeout) + return -1; + + /* All good.. */ + return 0; +} + +void sri2c_init(void) +{ + static int sri2c = 1; + + if (sri2c) { + omap_vc_init(PRM_VC_I2C_CHANNEL_FREQ_KHZ); + sri2c = 0; + } + return; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/omap3/Kconfig new file mode 100644 index 0000000..1f96498 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/Kconfig
@@ -0,0 +1,136 @@ +if OMAP34XX + +choice + prompt "OMAP3 board select" + +config TARGET_AM3517_EVM + bool "AM3517 EVM" + select SUPPORT_SPL + +config TARGET_MT_VENTOUX + bool "TeeJet Mt.Ventoux" + select SUPPORT_SPL + +config TARGET_OMAP3_SDP3430 + bool "TI OMAP3430 SDP" + +config TARGET_OMAP3_BEAGLE + bool "TI OMAP3 BeagleBoard" + select SUPPORT_SPL + +config TARGET_CM_T35 + bool "CompuLab CM-T3530 and CM-T3730 boards" + select SUPPORT_SPL + +config TARGET_CM_T3517 + bool "CompuLab CM-T3517 boards" + +config TARGET_DEVKIT8000 + bool "TimLL OMAP3 Devkit8000" + select SUPPORT_SPL + +config TARGET_OMAP3_EVM + bool "TI OMAP3 EVM" + select SUPPORT_SPL + +config TARGET_OMAP3_EVM_QUICK_MMC + bool "TI OMAP3 EVM Quick MMC" + select SUPPORT_SPL + +config TARGET_OMAP3_EVM_QUICK_NAND + bool "TI OMAP3 EVM Quick NAND" + select SUPPORT_SPL + +config TARGET_OMAP3_IGEP00X0 + bool "IGEP" + select SUPPORT_SPL + +config TARGET_OMAP3_OVERO + bool "OMAP35xx Gumstix Overo" + select SUPPORT_SPL + +config TARGET_OMAP3_ZOOM1 + bool "TI Zoom1" + +config TARGET_AM3517_CRANE + bool "am3517_crane" + select SUPPORT_SPL + +config TARGET_OMAP3_PANDORA + bool "OMAP3 Pandora" + +config TARGET_ECO5PK + bool "ECO5PK" + select SUPPORT_SPL + +config TARGET_DIG297 + bool "DIG297" + +config TARGET_TRICORDER + bool "Tricorder" + select SUPPORT_SPL + +config TARGET_MCX + bool "MCX" + select SUPPORT_SPL + +config TARGET_OMAP3_LOGIC + bool "OMAP3 Logic" + +config TARGET_OMAP3_MVBLX + bool "OMAP3 MVBLX" + +config TARGET_NOKIA_RX51 + bool "Nokia RX51" + +config TARGET_TAO3530 + bool "TAO3530" + select SUPPORT_SPL + +config TARGET_TWISTER + bool "Twister" + select SUPPORT_SPL + +config TARGET_OMAP3_CAIRO + bool "QUIPOS CAIRO" + select SUPPORT_SPL + +endchoice + +config DM + default y + +config DM_GPIO + default y if DM + +config DM_SERIAL + default y if DM + +config SYS_SOC + default "omap3" + +source "board/logicpd/am3517evm/Kconfig" +source "board/teejet/mt_ventoux/Kconfig" +source "board/ti/sdp3430/Kconfig" +source "board/ti/beagle/Kconfig" +source "board/compulab/cm_t35/Kconfig" +source "board/compulab/cm_t3517/Kconfig" +source "board/timll/devkit8000/Kconfig" +source "board/ti/evm/Kconfig" +source "board/isee/igep00x0/Kconfig" +source "board/overo/Kconfig" +source "board/logicpd/zoom1/Kconfig" +source "board/ti/am3517crane/Kconfig" +source "board/pandora/Kconfig" +source "board/8dtech/eco5pk/Kconfig" +source "board/comelit/dig297/Kconfig" +source "board/corscience/tricorder/Kconfig" +source "board/htkw/mcx/Kconfig" +source "board/logicpd/omap3som/Kconfig" +source "board/matrix_vision/mvblx/Kconfig" +source "board/nokia/rx51/Kconfig" +source "board/technexion/tao3530/Kconfig" +source "board/technexion/twister/Kconfig" +source "board/quipos/cairo/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/Makefile b/u-boot-imx/arch/arm/cpu/armv7/omap3/Makefile new file mode 100644 index 0000000..cf86046 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/Makefile
@@ -0,0 +1,20 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := lowlevel_init.o + +obj-y += board.o +obj-y += clock.o +obj-y += sys_info.o +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_OMAP3_ID_NAND) += spl_id_nand.o +endif + +obj-$(CONFIG_DRIVER_TI_EMAC) += emac.o +obj-$(CONFIG_EMIF4) += emif4.o +obj-$(CONFIG_SDRC) += sdrc.o +obj-$(CONFIG_USB_MUSB_AM35X) += am35x_musb.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/am35x_musb.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/am35x_musb.c new file mode 100644 index 0000000..74dd105 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/am35x_musb.c
@@ -0,0 +1,61 @@ +/* + * This file configures the internal USB PHY in AM35X. + * + * Copyright (C) 2012 Ilya Yanok <ilya.yanok@gmail.com> + * + * Based on omap_phy_internal.c code from Linux by + * Hema HK <hemahk@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/am35x_def.h> + +void am35x_musb_reset(void) +{ + /* Reset the musb interface */ + clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset, + 0, USBOTGSS_SW_RST); + clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset, + USBOTGSS_SW_RST, 0); +} + +void am35x_musb_phy_power(u8 on) +{ + unsigned long start = get_timer(0); + + if (on) { + /* + * Start the on-chip PHY and its PLL. + */ + clrsetbits_le32(&am35x_scm_general_regs->devconf2, + CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN, + CONF2_PHY_PLLON); + + debug("Waiting for PHY clock good...\n"); + while (!(readl(&am35x_scm_general_regs->devconf2) + & CONF2_PHYCLKGD)) { + + if (get_timer(start) > CONFIG_SYS_HZ / 10) { + printf("musb PHY clock good timed out\n"); + break; + } + } + } else { + /* + * Power down the on-chip PHY. + */ + clrsetbits_le32(&am35x_scm_general_regs->devconf2, + CONF2_PHY_PLLON, + CONF2_PHYPWRDN | CONF2_OTGPWRDN); + } +} + +void am35x_musb_clear_irq(void) +{ + clrsetbits_le32(&am35x_scm_general_regs->lvl_intr_clr, + 0, USBOTGSS_INT_CLR); + readl(&am35x_scm_general_regs->lvl_intr_clr); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/board.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/board.c new file mode 100644 index 0000000..b064c0c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/board.c
@@ -0,0 +1,491 @@ +/* + * + * Common board functions for OMAP3 based boards. + * + * (C) Copyright 2004-2008 + * Texas Instruments, <www.ti.com> + * + * Author : + * Sunil Kumar <sunilsaini05@gmail.com> + * Shashi Ranjan <shashiranjanmca05@gmail.com> + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/mem.h> +#include <asm/cache.h> +#include <asm/armv7.h> +#include <asm/gpio.h> +#include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> +#include <i2c.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Declarations */ +extern omap3_sysinfo sysinfo; +#ifndef CONFIG_SYS_L2CACHE_OFF +static void omap3_invalidate_l2_cache_secure(void); +#endif + +#ifdef CONFIG_DM_GPIO +static const struct omap_gpio_platdata omap34xx_gpio[] = { + { 0, OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { 1, OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { 2, OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { 3, OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { 4, OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { 5, OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, +}; + +U_BOOT_DEVICES(am33xx_gpios) = { + { "gpio_omap", &omap34xx_gpio[0] }, + { "gpio_omap", &omap34xx_gpio[1] }, + { "gpio_omap", &omap34xx_gpio[2] }, + { "gpio_omap", &omap34xx_gpio[3] }, + { "gpio_omap", &omap34xx_gpio[4] }, + { "gpio_omap", &omap34xx_gpio[5] }, +}; + +#else + +static const struct gpio_bank gpio_bank_34xx[6] = { + { (void *)OMAP34XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP34XX_GPIO6_BASE, METHOD_GPIO_24XX }, +}; + +const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; + +#endif + +#ifdef CONFIG_SPL_BUILD +/* +* We use static variables because global data is not ready yet. +* Initialized data is available in SPL right from the beginning. +* We would not typically need to save these parameters in regular +* U-Boot. This is needed only in SPL at the moment. +*/ +u32 omap3_boot_device = BOOT_DEVICE_NAND; + +/* auto boot mode detection is not possible for OMAP3 - hard code */ +u32 spl_boot_mode(void) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC2: + return MMCSD_MODE_RAW; + case BOOT_DEVICE_MMC1: + return MMCSD_MODE_FS; + break; + default: + puts("spl: ERROR: unknown device - can't select boot mode\n"); + hang(); + } +} + +u32 spl_boot_device(void) +{ + return omap3_boot_device; +} + +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0, -1, -1); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0, -1, -1); + break; + } + return 0; +} + +void spl_board_init(void) +{ + preloader_console_init(); +#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT) + gpmc_init(); +#endif +#ifdef CONFIG_SPL_I2C_SUPPORT + i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE); +#endif +} +#endif /* CONFIG_SPL_BUILD */ + + +/****************************************************************************** + * Routine: secure_unlock + * Description: Setup security registers for access + * (GP Device only) + *****************************************************************************/ +void secure_unlock_mem(void) +{ + struct pm *pm_rt_ape_base = (struct pm *)PM_RT_APE_BASE_ADDR_ARM; + struct pm *pm_gpmc_base = (struct pm *)PM_GPMC_BASE_ADDR_ARM; + struct pm *pm_ocm_ram_base = (struct pm *)PM_OCM_RAM_BASE_ADDR_ARM; + struct pm *pm_iva2_base = (struct pm *)PM_IVA2_BASE_ADDR_ARM; + struct sms *sms_base = (struct sms *)OMAP34XX_SMS_BASE; + + /* Protection Module Register Target APE (PM_RT) */ + writel(UNLOCK_1, &pm_rt_ape_base->req_info_permission_1); + writel(UNLOCK_1, &pm_rt_ape_base->read_permission_0); + writel(UNLOCK_1, &pm_rt_ape_base->wirte_permission_0); + writel(UNLOCK_2, &pm_rt_ape_base->addr_match_1); + + writel(UNLOCK_3, &pm_gpmc_base->req_info_permission_0); + writel(UNLOCK_3, &pm_gpmc_base->read_permission_0); + writel(UNLOCK_3, &pm_gpmc_base->wirte_permission_0); + + writel(UNLOCK_3, &pm_ocm_ram_base->req_info_permission_0); + writel(UNLOCK_3, &pm_ocm_ram_base->read_permission_0); + writel(UNLOCK_3, &pm_ocm_ram_base->wirte_permission_0); + writel(UNLOCK_2, &pm_ocm_ram_base->addr_match_2); + + /* IVA Changes */ + writel(UNLOCK_3, &pm_iva2_base->req_info_permission_0); + writel(UNLOCK_3, &pm_iva2_base->read_permission_0); + writel(UNLOCK_3, &pm_iva2_base->wirte_permission_0); + + /* SDRC region 0 public */ + writel(UNLOCK_1, &sms_base->rg_att0); +} + +/****************************************************************************** + * Routine: secureworld_exit() + * Description: If chip is EMU and boot type is external + * configure secure registers and exit secure world + * general use. + *****************************************************************************/ +void secureworld_exit(void) +{ + unsigned long i; + + /* configure non-secure access control register */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i)); + /* enabling co-processor CP10 and CP11 accesses in NS world */ + __asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i)); + /* + * allow allocation of locked TLBs and L2 lines in NS world + * allow use of PLE registers in NS world also + */ + __asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i)); + + /* Enable ASA in ACR register */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x10":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); + + /* Exiting secure world */ + __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x31":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i)); +} + +/****************************************************************************** + * Routine: try_unlock_sram() + * Description: If chip is GP/EMU(special) type, unlock the SRAM for + * general use. + *****************************************************************************/ +void try_unlock_memory(void) +{ + int mode; + int in_sdram = is_running_in_sdram(); + + /* + * 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_mem(); + + /* + * If device is EMU and boot is XIP external booting + * Unlock firewalls and disable L2 and put chip + * out of secure world + * + * Assuming memories are unlocked by the demon who put us in SDRAM + */ + if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F) + && (!in_sdram)) { + secure_unlock_mem(); + secureworld_exit(); + } + + return; +} + +/****************************************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called path is with SRAM stack. + *****************************************************************************/ +void s_init(void) +{ + watchdog_init(); + + try_unlock_memory(); + +#ifndef CONFIG_SYS_L2CACHE_OFF + /* Invalidate L2-cache from secure mode */ + omap3_invalidate_l2_cache_secure(); +#endif + + set_muxconf_regs(); + sdelay(100); + + prcm_init(); + + per_clocks_enable(); + +#ifdef CONFIG_USB_EHCI_OMAP + ehci_clocks_enable(); +#endif +} + +#ifdef CONFIG_SPL_BUILD +void board_init_f(ulong dummy) +{ + mem_init(); +} +#endif + +/* + * Routine: misc_init_r + * Description: A basic misc_init_r that just displays the die ID + */ +int __weak misc_init_r(void) +{ + dieid_num_r(); + + return 0; +} + +/****************************************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + *****************************************************************************/ +static void wait_for_command_complete(struct watchdog *wd_base) +{ + int pending = 1; + do { + pending = readl(&wd_base->wwps); + } while (pending); +} + +/****************************************************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************************************************/ +void watchdog_init(void) +{ + struct watchdog *wd2_base = (struct watchdog *)WD2_BASE; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* + * 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. + */ + + setbits_le32(&prcm_base->fclken_wkup, 0x20); + setbits_le32(&prcm_base->iclken_wkup, 0x20); + wait_on_value(ST_WDT2, 0x20, &prcm_base->idlest_wkup, 5); + + writel(WD_UNLOCK1, &wd2_base->wspr); + wait_for_command_complete(wd2_base); + writel(WD_UNLOCK2, &wd2_base->wspr); +} + +/****************************************************************************** + * Dummy function to handle errors for EABI incompatibility + *****************************************************************************/ +void abort(void) +{ +} + +#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD) +/****************************************************************************** + * OMAP3 specific command to switch between NAND HW and SW ecc + *****************************************************************************/ +static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2 || argc > 3) + goto usage; + + if (strncmp(argv[1], "hw", 2) == 0) { + if (argc == 2) { + omap_nand_switch_ecc(1, 1); + } else { + if (strncmp(argv[2], "hamming", 7) == 0) + omap_nand_switch_ecc(1, 1); + else if (strncmp(argv[2], "bch8", 4) == 0) + omap_nand_switch_ecc(1, 8); + else + goto usage; + } + } else if (strncmp(argv[1], "sw", 2) == 0) { + if (argc == 2) { + omap_nand_switch_ecc(0, 1); + } else { + if (strncmp(argv[2], "hamming", 7) == 0) + omap_nand_switch_ecc(0, 1); + else if (strncmp(argv[2], "bch8", 4) == 0) + omap_nand_switch_ecc(0, 8); + else + goto usage; + } + } else { + goto usage; + } + + return 0; + +usage: + printf ("Usage: nandecc %s\n", cmdtp->usage); + return 1; +} + +U_BOOT_CMD( + nandecc, 3, 1, do_switch_ecc, + "switch OMAP3 NAND ECC calculation algorithm", + "hw [hamming|bch8] - Switch between NAND hardware 1-bit hamming and" + " 8-bit BCH\n" + " ecc calculation (second parameter may" + " be omitted).\n" + "nandecc sw - Switch to NAND software ecc algorithm." +); + +#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */ + +#ifdef CONFIG_DISPLAY_BOARDINFO +/** + * Print board information + */ +int checkboard (void) +{ + char *mem_s ; + + if (is_mem_sdr()) + mem_s = "mSDR"; + else + mem_s = "LPDDR"; + + printf("%s + %s/%s\n", sysinfo.board_string, mem_s, + sysinfo.nand_string); + + return 0; +} +#endif /* CONFIG_DISPLAY_BOARDINFO */ + +static void omap3_emu_romcode_call(u32 service_id, u32 *parameters) +{ + u32 i, num_params = *parameters; + u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA; + + /* + * copy the parameters to an un-cached area to avoid coherency + * issues + */ + for (i = 0; i < num_params; i++) { + __raw_writel(*parameters, sram_scratch_space); + parameters++; + sram_scratch_space++; + } + + /* Now make the PPA call */ + do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA); +} + +void __weak omap3_set_aux_cr_secure(u32 acr) +{ + struct emu_hal_params emu_romcode_params; + + emu_romcode_params.num_params = 1; + emu_romcode_params.param1 = acr; + omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR, + (u32 *)&emu_romcode_params); +} + +void v7_arch_cp15_set_acr(u32 acr, u32 cpu_midr, u32 cpu_rev_comb, + u32 cpu_variant, u32 cpu_rev) +{ + /* Write ACR - affects secure banked bits */ + if (get_device_type() == GP_DEVICE) + omap_smc1(OMAP3_GP_ROMCODE_API_WRITE_ACR, acr); + else + omap3_set_aux_cr_secure(acr); + + /* Write ACR - affects non-secure banked bits - some erratas need it */ + asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (acr)); +} + + +#ifndef CONFIG_SYS_L2CACHE_OFF +static void omap3_update_aux_cr(u32 set_bits, u32 clear_bits) +{ + u32 acr; + + /* Read ACR */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); + acr &= ~clear_bits; + acr |= set_bits; + v7_arch_cp15_set_acr(acr, 0, 0, 0, 0); + +} + +/* Invalidate the entire L2 cache from secure mode */ +static void omap3_invalidate_l2_cache_secure(void) +{ + if (get_device_type() == GP_DEVICE) { + omap_smc1(OMAP3_GP_ROMCODE_API_L2_INVAL, 0); + } else { + struct emu_hal_params emu_romcode_params; + emu_romcode_params.num_params = 1; + emu_romcode_params.param1 = 0; + omap3_emu_romcode_call(OMAP3_EMU_HAL_API_L2_INVAL, + (u32 *)&emu_romcode_params); + } +} + +void v7_outer_cache_enable(void) +{ + + /* + * Set L2EN + * On some revisions L2EN bit is banked on some revisions it's not + * No harm in setting both banked bits(in fact this is required + * by an erratum) + */ + omap3_update_aux_cr(0x2, 0); +} + +void omap3_outer_cache_disable(void) +{ + /* + * Clear L2EN + * On some revisions L2EN bit is banked on some revisions it's not + * No harm in clearing both banked bits(in fact this is required + * by an erratum) + */ + omap3_update_aux_cr(0, 0x2); +} +#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/clock.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/clock.c new file mode 100644 index 0000000..006969e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/clock.c
@@ -0,0 +1,799 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * + * Author : + * Manikandan Pillai <mani.pillai@ti.com> + * + * Derived from Beagle Board and OMAP3 SDP code by + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/clocks_omap3.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <environment.h> +#include <command.h> + +/****************************************************************************** + * 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; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + struct prm *prm_base = (struct prm *)PRM_BASE; + struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1; + struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE; + + val = readl(&prm_base->clksrc_ctrl); + + if (val & SYSCLKDIV_2) + cdiv = 2; + else + cdiv = 1; + + /* enable timer2 */ + val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1; + + /* select sys_clk for GPT1 */ + writel(val, &prcm_base->clksel_wkup); + + /* Enable I and F Clocks for GPT1 */ + val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC; + writel(val, &prcm_base->iclken_wkup); + + val = readl(&prcm_base->fclken_wkup) | EN_GPT1; + writel(val, &prcm_base->fclken_wkup); + + writel(0, &gpt1_base->tldr); /* start counting at 0 */ + writel(GPT_EN, &gpt1_base->tclr); /* enable clock */ + + /* enable 32kHz source, determine sys_clk via gauging */ + + /* start time in 20 cycles */ + start = 20 + readl(&s32k_base->s32k_cr); + + /* dead loop till start time */ + while (readl(&s32k_base->s32k_cr) < start); + + /* get start sys_clk count */ + cstart = readl(&gpt1_base->tcrr); + + /* wait for 40 cycles */ + while (readl(&s32k_base->s32k_cr) < (start + 20)) ; + cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */ + cdiff = cend - cstart; /* get elapsed ticks */ + cdiff *= cdiv; + + /* 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) +{ + switch(osc_clk) { + case S38_4M: + *sys_clkin_sel = 4; + break; + case S26M: + *sys_clkin_sel = 3; + break; + case S19_2M: + *sys_clkin_sel = 2; + break; + case S13M: + *sys_clkin_sel = 1; + break; + case S12M: + default: + *sys_clkin_sel = 0; + } +} + +/* + * OMAP34XX/35XX specific functions + */ + +static void dpll3_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_core_dpll_param(); + void (*f_lock_pll) (u32, u32, u32, u32); + int xip_safe, p0, p1, p2, p3; + + xip_safe = is_running_in_sram(); + + /* Moving to the right sysclk and ES rev base */ + ptr = ptr + (3 * clk_index) + sil_index; + + if (xip_safe) { + /* + * CORE DPLL + */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x00000007, PLL_FAST_RELOCK_BYPASS); + wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen, + LDELAY); + + /* + * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't + * work. write another value and then default value. + */ + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + clrsetbits_le32(&prcm_base->clksel1_emu, + 0x001F0000, (CORE_M3X2 + 1) << 16) ; + clrsetbits_le32(&prcm_base->clksel1_emu, + 0x001F0000, CORE_M3X2 << 16); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0xF8000000, ptr->m2 << 27); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0x07FF0000, ptr->m << 16); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0x00007F00, ptr->n << 8); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + clrbits_le32(&prcm_base->clksel1_pll, 0x00000040); + + /* SSI */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000F00, CORE_SSI_DIV << 8); + /* FSUSB */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000030, CORE_FUSB_DIV << 4); + /* L4 */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x0000000C, CORE_L4_DIV << 2); + /* L3 */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000003, CORE_L3_DIV); + /* GFX */ + clrsetbits_le32(&prcm_base->clksel_gfx, + 0x00000007, GFX_DIV); + /* RESET MGR */ + clrsetbits_le32(&prcm_base->clksel_wkup, + 0x00000006, WKUP_RSM << 1); + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x000000F0, ptr->fsel << 4); + /* LOCK MODE */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x00000007, PLL_LOCK); + + wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen, + LDELAY); + } else if (is_running_in_flash()) { + /* + * if running from flash, jump to small relocated code + * area in SRAM. + */ + f_lock_pll = (void *) (SRAM_CLK_CODE); + + p0 = readl(&prcm_base->clken_pll); + clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS); + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4); + + p1 = readl(&prcm_base->clksel1_pll); + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27); + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16); + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8); + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + clrbits_le32(&p1, 0x00000040); + + p2 = readl(&prcm_base->clksel_core); + /* SSI */ + clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8); + /* FSUSB */ + clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4); + /* L4 */ + clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2); + /* L3 */ + clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV); + + p3 = (u32)&prcm_base->idlest_ckgen; + + (*f_lock_pll) (p0, p1, p2, p3); + } +} + +static void dpll4_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *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] */ + clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16); + wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); + + /* + * Errata 1.50 Workaround for OMAP3 ES1.0 only + * If using default divisors, write default divisor + 1 + * and then the actual divisor value + */ + /* M6 */ + clrsetbits_le32(&prcm_base->clksel1_emu, + 0x1F000000, (PER_M6X2 + 1) << 24); + clrsetbits_le32(&prcm_base->clksel1_emu, + 0x1F000000, PER_M6X2 << 24); + /* M5 */ + clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, (PER_M5X2 + 1)); + clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, PER_M5X2); + /* M4 */ + clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, (PER_M4X2 + 1)); + clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, PER_M4X2); + /* M3 */ + clrsetbits_le32(&prcm_base->clksel_dss, + 0x00001F00, (PER_M3X2 + 1) << 8); + clrsetbits_le32(&prcm_base->clksel_dss, + 0x00001F00, PER_M3X2 << 8); + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, (ptr->m2 + 1)); + clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2); + /* Workaround end */ + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */ + clrsetbits_le32(&prcm_base->clksel2_pll, + 0x0007FF00, ptr->m << 8); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n); + + /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */ + clrsetbits_le32(&prcm_base->clken_pll, 0x00F00000, ptr->fsel << 20); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16); + wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); +} + +static void dpll5_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_per2_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* PER2 DPLL (DPLL5) */ + clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP); + wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY); + /* set M2 (usbtll_fck) */ + clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2); + /* set m (11-bit multiplier) */ + clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8); + /* set n (7-bit divider)*/ + clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n); + /* FREQSEL */ + clrsetbits_le32(&prcm_base->clken_pll, 0x000000F0, ptr->fsel << 4); + /* lock mode */ + clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK); + wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY); +} + +static void mpu_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_mpu_dpll_param(); + + /* Moving to the right sysclk and ES rev base */ + ptr = ptr + (3 * clk_index) + sil_index; + + /* MPU DPLL (unlocked already) */ + + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + clrsetbits_le32(&prcm_base->clksel2_pll_mpu, + 0x0000001F, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + clrsetbits_le32(&prcm_base->clksel1_pll_mpu, + 0x0007FF00, ptr->m << 8); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + clrsetbits_le32(&prcm_base->clksel1_pll_mpu, + 0x0000007F, ptr->n); + + /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */ + clrsetbits_le32(&prcm_base->clken_pll_mpu, + 0x000000F0, ptr->fsel << 4); +} + +static void iva_init_34xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_iva_dpll_param(); + + /* Moving to the right sysclk and ES rev base */ + ptr = ptr + (3 * clk_index) + sil_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + clrsetbits_le32(&prcm_base->clken_pll_iva2, + 0x00000007, PLL_STOP); + wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + clrsetbits_le32(&prcm_base->clksel2_pll_iva2, + 0x0000001F, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + clrsetbits_le32(&prcm_base->clksel1_pll_iva2, + 0x0007FF00, ptr->m << 8); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + clrsetbits_le32(&prcm_base->clksel1_pll_iva2, + 0x0000007F, ptr->n); + + /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */ + clrsetbits_le32(&prcm_base->clken_pll_iva2, + 0x000000F0, ptr->fsel << 4); + + /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + clrsetbits_le32(&prcm_base->clken_pll_iva2, + 0x00000007, PLL_LOCK); + + wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY); +} + +/* + * OMAP3630 specific functions + */ + +static void dpll3_init_36xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param(); + void (*f_lock_pll) (u32, u32, u32, u32); + int xip_safe, p0, p1, p2, p3; + + xip_safe = is_running_in_sram(); + + /* Moving it to the right sysclk base */ + ptr += clk_index; + + if (xip_safe) { + /* CORE DPLL */ + + /* Select relock bypass: CM_CLKEN_PLL[0:2] */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x00000007, PLL_FAST_RELOCK_BYPASS); + wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen, + LDELAY); + + /* CM_CLKSEL1_EMU[DIV_DPLL3] */ + clrsetbits_le32(&prcm_base->clksel1_emu, + 0x001F0000, CORE_M3X2 << 16); + + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0xF8000000, ptr->m2 << 27); + + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0x07FF0000, ptr->m << 16); + + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + clrsetbits_le32(&prcm_base->clksel1_pll, + 0x00007F00, ptr->n << 8); + + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + clrbits_le32(&prcm_base->clksel1_pll, 0x00000040); + + /* SSI */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000F00, CORE_SSI_DIV << 8); + /* FSUSB */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000030, CORE_FUSB_DIV << 4); + /* L4 */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x0000000C, CORE_L4_DIV << 2); + /* L3 */ + clrsetbits_le32(&prcm_base->clksel_core, + 0x00000003, CORE_L3_DIV); + /* GFX */ + clrsetbits_le32(&prcm_base->clksel_gfx, + 0x00000007, GFX_DIV_36X); + /* RESET MGR */ + clrsetbits_le32(&prcm_base->clksel_wkup, + 0x00000006, WKUP_RSM << 1); + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x000000F0, ptr->fsel << 4); + /* LOCK MODE */ + clrsetbits_le32(&prcm_base->clken_pll, + 0x00000007, PLL_LOCK); + + wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen, + LDELAY); + } else if (is_running_in_flash()) { + /* + * if running from flash, jump to small relocated code + * area in SRAM. + */ + f_lock_pll = (void *) (SRAM_CLK_CODE); + + p0 = readl(&prcm_base->clken_pll); + clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS); + /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */ + clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4); + + p1 = readl(&prcm_base->clksel1_pll); + /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */ + clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27); + /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */ + clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16); + /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */ + clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8); + /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */ + clrbits_le32(&p1, 0x00000040); + + p2 = readl(&prcm_base->clksel_core); + /* SSI */ + clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8); + /* FSUSB */ + clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4); + /* L4 */ + clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2); + /* L3 */ + clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV); + + p3 = (u32)&prcm_base->idlest_ckgen; + + (*f_lock_pll) (p0, p1, p2, p3); + } +} + +static void dpll4_init_36xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + 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] */ + clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16); + wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY); + + /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */ + clrsetbits_le32(&prcm_base->clksel1_emu, 0x3F000000, ptr->m6 << 24); + + /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */ + clrsetbits_le32(&prcm_base->clksel_cam, 0x0000003F, ptr->m5); + + /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */ + clrsetbits_le32(&prcm_base->clksel_dss, 0x0000003F, ptr->m4); + + /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */ + clrsetbits_le32(&prcm_base->clksel_dss, 0x00003F00, ptr->m3 << 8); + + /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */ + clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2); + + /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */ + clrsetbits_le32(&prcm_base->clksel2_pll, 0x000FFF00, ptr->m << 8); + + /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */ + clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n); + + /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */ + clrsetbits_le32(&prcm_base->clksel_core, 0x00003000, ptr->m2div << 12); + + /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */ + clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16); + wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY); +} + +static void dpll5_init_36xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_36x_per2_dpll_param(); + + /* Moving it to the right sysclk base */ + ptr = ptr + clk_index; + + /* PER2 DPLL (DPLL5) */ + clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP); + wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY); + /* set M2 (usbtll_fck) */ + clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2); + /* set m (11-bit multiplier) */ + clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8); + /* set n (7-bit divider)*/ + clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n); + /* lock mode */ + clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK); + wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY); +} + +static void mpu_init_36xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param(); + + /* Moving to the right sysclk */ + ptr += clk_index; + + /* MPU DPLL (unlocked already */ + + /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */ + clrsetbits_le32(&prcm_base->clksel2_pll_mpu, 0x0000001F, ptr->m2); + + /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */ + clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0007FF00, ptr->m << 8); + + /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */ + clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0000007F, ptr->n); +} + +static void iva_init_36xx(u32 sil_index, u32 clk_index) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param(); + + /* Moving to the right sysclk */ + ptr += clk_index; + + /* IVA DPLL */ + /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */ + clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_STOP); + wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY); + + /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */ + clrsetbits_le32(&prcm_base->clksel2_pll_iva2, 0x0000001F, ptr->m2); + + /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */ + clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0007FF00, ptr->m << 8); + + /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */ + clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0000007F, ptr->n); + + /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */ + clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_LOCK); + + wait_on_value(ST_IVA2_CLK, 1, &prcm_base->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 = 0; + struct prm *prm_base = (struct prm *)PRM_BASE; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* + * 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); + + /* set input crystal speed */ + clrsetbits_le32(&prm_base->clksel, 0x00000007, sys_clkin_sel); + + /* If the input clock is greater than 19.2M always divide/2 */ + if (sys_clkin_sel > 2) { + /* input clock divider */ + clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 2 << 6); + clk_index = sys_clkin_sel / 2; + } else { + /* input clock divider */ + clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 1 << 6); + clk_index = sys_clkin_sel; + } + + if (get_cpu_family() == CPU_OMAP36XX) { + /* + * In warm reset conditions on OMAP36xx/AM/DM37xx + * the rom code incorrectly sets the DPLL4 clock + * input divider to /6.5. Section 3.5.3.3.3.2.1 of + * the AM/DM37x TRM explains that the /6.5 divider + * is used only when the input clock is 13MHz. + * + * If the part is in this cpu family *and* the input + * clock *is not* 13 MHz, then reset the DPLL4 clock + * input divider to /1 as it should never set to /6.5 + * in this case. + */ + if (sys_clkin_sel != 1) { /* 13 MHz */ + /* Bit 8: DPLL4_CLKINP_DIV */ + clrbits_le32(&prm_base->clksrc_ctrl, 0x00000100); + } + + /* Unlock MPU DPLL (slows things down, and needed later) */ + clrsetbits_le32(&prcm_base->clken_pll_mpu, + 0x00000007, PLL_LOW_POWER_BYPASS); + wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, + LDELAY); + + dpll3_init_36xx(0, clk_index); + dpll4_init_36xx(0, clk_index); + dpll5_init_36xx(0, clk_index); + iva_init_36xx(0, clk_index); + mpu_init_36xx(0, clk_index); + + /* Lock MPU DPLL to set frequency */ + clrsetbits_le32(&prcm_base->clken_pll_mpu, + 0x00000007, PLL_LOCK); + wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, + LDELAY); + } else { + /* + * 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 (((get_cpu_family() == CPU_OMAP34XX) + && (get_cpu_rev() >= CPU_3XX_ES20)) || + (get_cpu_family() == CPU_AM35XX)) + sil_index = 1; + + /* Unlock MPU DPLL (slows things down, and needed later) */ + clrsetbits_le32(&prcm_base->clken_pll_mpu, + 0x00000007, PLL_LOW_POWER_BYPASS); + wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, + LDELAY); + + dpll3_init_34xx(sil_index, clk_index); + dpll4_init_34xx(sil_index, clk_index); + dpll5_init_34xx(sil_index, clk_index); + if (get_cpu_family() != CPU_AM35XX) + iva_init_34xx(sil_index, clk_index); + + mpu_init_34xx(sil_index, clk_index); + + /* Lock MPU DPLL to set frequency */ + clrsetbits_le32(&prcm_base->clken_pll_mpu, + 0x00000007, PLL_LOCK); + wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, + LDELAY); + } + + /* Set up GPTimers to sys_clk source only */ + setbits_le32(&prcm_base->clksel_per, 0x000000FF); + setbits_le32(&prcm_base->clksel_wkup, 1); + + sdelay(5000); +} + +/* + * Enable usb ehci uhh, tll clocks + */ +void ehci_clocks_enable(void) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */ + setbits_le32(&prcm_base->iclken_usbhost, 1); + /* + * Enable USBHOST_48M_FCLK (USBHOST_FCLK1) + * and USBHOST_120M_FCLK (USBHOST_FCLK2) + */ + setbits_le32(&prcm_base->fclken_usbhost, 0x00000003); + /* Enable USBTTL_ICLK */ + setbits_le32(&prcm_base->iclken3_core, 0x00000004); + /* Enable USBTTL_FCLK */ + setbits_le32(&prcm_base->fclken3_core, 0x00000004); +} + +/****************************************************************************** + * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...) + *****************************************************************************/ +void per_clocks_enable(void) +{ + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + /* Enable GP2 timer. */ + setbits_le32(&prcm_base->clksel_per, 0x01); /* GPT2 = sys clk */ + setbits_le32(&prcm_base->iclken_per, 0x08); /* ICKen GPT2 */ + setbits_le32(&prcm_base->fclken_per, 0x08); /* FCKen GPT2 */ + + /* Enable GP9 timer. */ + setbits_le32(&prcm_base->clksel_per, 0x80); /* GPT9 = 32kHz clk */ + setbits_le32(&prcm_base->iclken_per, 0x400); /* ICKen GPT9 */ + setbits_le32(&prcm_base->fclken_per, 0x400); /* FCKen GPT9 */ + +#ifdef CONFIG_SYS_NS16550 + /* Enable UART1 clocks */ + setbits_le32(&prcm_base->fclken1_core, 0x00002000); + setbits_le32(&prcm_base->iclken1_core, 0x00002000); + + /* Enable UART2 clocks */ + setbits_le32(&prcm_base->fclken1_core, 0x00004000); + setbits_le32(&prcm_base->iclken1_core, 0x00004000); + + /* UART 3 Clocks */ + setbits_le32(&prcm_base->fclken_per, 0x00000800); + setbits_le32(&prcm_base->iclken_per, 0x00000800); +#endif + +#ifdef CONFIG_OMAP3_GPIO_2 + setbits_le32(&prcm_base->fclken_per, 0x00002000); + setbits_le32(&prcm_base->iclken_per, 0x00002000); +#endif +#ifdef CONFIG_OMAP3_GPIO_3 + setbits_le32(&prcm_base->fclken_per, 0x00004000); + setbits_le32(&prcm_base->iclken_per, 0x00004000); +#endif +#ifdef CONFIG_OMAP3_GPIO_4 + setbits_le32(&prcm_base->fclken_per, 0x00008000); + setbits_le32(&prcm_base->iclken_per, 0x00008000); +#endif +#ifdef CONFIG_OMAP3_GPIO_5 + setbits_le32(&prcm_base->fclken_per, 0x00010000); + setbits_le32(&prcm_base->iclken_per, 0x00010000); +#endif +#ifdef CONFIG_OMAP3_GPIO_6 + setbits_le32(&prcm_base->fclken_per, 0x00020000); + setbits_le32(&prcm_base->iclken_per, 0x00020000); +#endif + +#ifdef CONFIG_SYS_I2C_OMAP34XX + /* Turn on all 3 I2C clocks */ + setbits_le32(&prcm_base->fclken1_core, 0x00038000); + setbits_le32(&prcm_base->iclken1_core, 0x00038000); /* I2C1,2,3 = on */ +#endif + /* Enable the ICLK for 32K Sync Timer as its used in udelay */ + setbits_le32(&prcm_base->iclken_wkup, 0x00000004); + + if (get_cpu_family() != CPU_AM35XX) + out_le32(&prcm_base->fclken_iva2, FCK_IVA2_ON); + + out_le32(&prcm_base->fclken1_core, FCK_CORE1_ON); + out_le32(&prcm_base->iclken1_core, ICK_CORE1_ON); + out_le32(&prcm_base->iclken2_core, ICK_CORE2_ON); + out_le32(&prcm_base->fclken_wkup, FCK_WKUP_ON); + out_le32(&prcm_base->iclken_wkup, ICK_WKUP_ON); + out_le32(&prcm_base->fclken_dss, FCK_DSS_ON); + out_le32(&prcm_base->iclken_dss, ICK_DSS_ON); + if (get_cpu_family() != CPU_AM35XX) { + out_le32(&prcm_base->fclken_cam, FCK_CAM_ON); + out_le32(&prcm_base->iclken_cam, ICK_CAM_ON); + } + + sdelay(1000); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/config.mk b/u-boot-imx/arch/arm/cpu/armv7/omap3/config.mk new file mode 100644 index 0000000..ad44d63 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/config.mk
@@ -0,0 +1,15 @@ +# +# Copyright 2011 Linaro Limited +# +# (C) Copyright 2010 +# Texas Instruments, <www.ti.com> +# +# Aneesh V <aneesh@ti.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +ALL-y += MLO +else +ALL-y += u-boot.img +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/emac.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/emac.c new file mode 100644 index 0000000..37f4b8b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/emac.c
@@ -0,0 +1,29 @@ +/* + * + * DaVinci EMAC initialization. + * + * (C) Copyright 2011, Ilya Yanok, Emcraft Systems + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <netdev.h> +#include <asm/io.h> +#include <asm/arch/am35x_def.h> + +/* + * Initializes on-chip ethernet controllers. + * to override, implement board_eth_init() + */ +int cpu_eth_init(bd_t *bis) +{ + u32 reset; + + /* ensure that the module is out of reset */ + reset = readl(&am35x_scm_general_regs->ip_sw_reset); + reset &= ~CPGMACSS_SW_RST; + writel(reset, &am35x_scm_general_regs->ip_sw_reset); + + return davinci_emac_initialize(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/emif4.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/emif4.c new file mode 100644 index 0000000..a2aadc9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/emif4.c
@@ -0,0 +1,165 @@ +/* + * Author : + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * Based on mem.c and sdrc.c + * + * Copyright (C) 2010 + * Texas Instruments Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/emif4.h> + +DECLARE_GLOBAL_DATA_PTR; +extern omap3_sysinfo sysinfo; + +static emif4_t *emif4_base = (emif4_t *)OMAP34XX_SDRC_BASE; + +/* + * is_mem_sdr - + * - Return 1 if mem type in use is SDR + */ +u32 is_mem_sdr(void) +{ + return 0; +} + +/* + * get_sdr_cs_size - + * - Get size of chip select 0/1 + */ +u32 get_sdr_cs_size(u32 cs) +{ + u32 size = 0; + + /* TODO: Calculate the size based on EMIF4 configuration */ + if (cs == CS0) + size = CONFIG_SYS_CS0_SIZE; + + return size; +} + +/* + * get_sdr_cs_offset - + * - Get offset of cs from cs0 start + */ +u32 get_sdr_cs_offset(u32 cs) +{ + u32 offset = 0; + + return offset; +} + +/* + * do_emif4_init - + * - Init the emif4 module for DDR access + * - Early init routines, called from flash or SRAM. + */ +static void do_emif4_init(void) +{ + unsigned int regval; + /* Set the DDR PHY parameters in PHY ctrl registers */ + regval = (EMIF4_DDR1_READ_LAT | EMIF4_DDR1_PWRDN_DIS | + EMIF4_DDR1_EXT_STRB_DIS); + writel(regval, &emif4_base->ddr_phyctrl1); + writel(regval, &emif4_base->ddr_phyctrl1_shdw); + writel(0, &emif4_base->ddr_phyctrl2); + + /* Reset the DDR PHY and wait till completed */ + regval = readl(&emif4_base->sdram_iodft_tlgc); + regval |= (1<<10); + writel(regval, &emif4_base->sdram_iodft_tlgc); + /*Wait till that bit clears*/ + while ((readl(&emif4_base->sdram_iodft_tlgc) & (1<<10)) == 0x1); + /*Re-verify the DDR PHY status*/ + while ((readl(&emif4_base->sdram_sts) & (1<<2)) == 0x0); + + regval |= (1<<0); + writel(regval, &emif4_base->sdram_iodft_tlgc); + /* Set SDR timing registers */ + regval = (EMIF4_TIM1_T_WTR | EMIF4_TIM1_T_RRD | + EMIF4_TIM1_T_RC | EMIF4_TIM1_T_RAS | + EMIF4_TIM1_T_WR | EMIF4_TIM1_T_RCD | + EMIF4_TIM1_T_RP); + writel(regval, &emif4_base->sdram_time1); + writel(regval, &emif4_base->sdram_time1_shdw); + + regval = (EMIF4_TIM2_T_CKE | EMIF4_TIM2_T_RTP | + EMIF4_TIM2_T_XSRD | EMIF4_TIM2_T_XSNR | + EMIF4_TIM2_T_ODT | EMIF4_TIM2_T_XP); + writel(regval, &emif4_base->sdram_time2); + writel(regval, &emif4_base->sdram_time2_shdw); + + regval = (EMIF4_TIM3_T_RAS_MAX | EMIF4_TIM3_T_RFC); + writel(regval, &emif4_base->sdram_time3); + writel(regval, &emif4_base->sdram_time3_shdw); + + /* Set the PWR control register */ + regval = (EMIF4_PWR_PM_TIM | EMIF4_PWR_LP_MODE | + EMIF4_PWR_DPD_DIS | EMIF4_PWR_IDLE_MODE); + writel(regval, &emif4_base->sdram_pwr_mgmt); + writel(regval, &emif4_base->sdram_pwr_mgmt_shdw); + + /* Set the DDR refresh rate control register */ + regval = (EMIF4_REFRESH_RATE | EMIF4_INITREF_DIS); + writel(regval, &emif4_base->sdram_refresh_ctrl); + writel(regval, &emif4_base->sdram_refresh_ctrl_shdw); + + /* set the SDRAM configuration register */ + regval = (EMIF4_CFG_PGSIZE | EMIF4_CFG_EBANK | + EMIF4_CFG_IBANK | EMIF4_CFG_ROWSIZE | + EMIF4_CFG_CL | EMIF4_CFG_NARROW_MD | + EMIF4_CFG_SDR_DRV | EMIF4_CFG_DDR_DIS_DLL | + EMIF4_CFG_DDR2_DDQS | EMIF4_CFG_DDR_TERM | + EMIF4_CFG_IBANK_POS | EMIF4_CFG_SDRAM_TYP); + writel(regval, &emif4_base->sdram_config); +} + +/* + * dram_init - + * - Sets uboots idea of sdram size + */ +int dram_init(void) +{ + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + /* + * If a second bank of DDR is attached to CS1 this is + * where it can be started. Early init code will init + * memory on CS0. + */ + if ((sysinfo.mtype == DDR_COMBO) || (sysinfo.mtype == DDR_STACKED)) + size1 = get_sdr_cs_size(CS1); + + gd->ram_size = size0 + size1; + return 0; +} + +void dram_init_banksize (void) +{ + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); + gd->bd->bi_dram[1].size = size1; +} + +/* + * mem_init() - + * - Initialize memory subsystem + */ +void mem_init(void) +{ + do_emif4_init(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/omap3/lowlevel_init.S new file mode 100644 index 0000000..2497613 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/lowlevel_init.S
@@ -0,0 +1,486 @@ +/* + * Board specific setup info + * + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * + * Initial Code by: + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks_omap3.h> +#include <linux/linkage.h> + +#ifdef CONFIG_SPL_BUILD +ENTRY(save_boot_params) + ldr r4, =omap3_boot_device + ldr r5, [r0, #0x4] + and r5, r5, #0xff + str r5, [r4] + b save_boot_params_ret +ENDPROC(save_boot_params) +#endif + +/* + * Funtion for making PPA HAL API calls in secure devices + * Input: + * R0 - Service ID + * R1 - paramer list + */ +ENTRY(do_omap3_emu_romcode_call) + PUSH {r4-r12, lr} @ Save all registers from ROM code! + MOV r12, r0 @ Copy the Secure Service ID in R12 + MOV r3, r1 @ Copy the pointer to va_list in R3 + MOV r1, #0 @ Process ID - 0 + MOV r2, #OMAP3_EMU_HAL_START_HAL_CRITICAL @ Copy the pointer + @ to va_list in R3 + MOV r6, #0xFF @ Indicate new Task call + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c10, 5 @ DMB + .word 0xe1600071 @ SMC #1 to call PPA service - hand assembled + @ because we use -march=armv5 + POP {r4-r12, pc} +ENDPROC(do_omap3_emu_romcode_call) + +#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT) +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +ENTRY(cpy_clk_code) + /* Copy DPLL code into SRAM */ + adr r0, go_to_speed /* copy from start of go_to_speed... */ + adr r2, lowlevel_init /* ... up to start of low_level_init */ +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] */ + blo next2 + mov pc, lr /* back to caller */ +ENDPROC(cpy_clk_code) + +/* *************************************************************************** + * 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. + ****************************************************************************/ +ENTRY(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 */ +ENDPROC(go_to_speed) + +_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_BASE + GPMC_CONFIG1) +flash_cfg3_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG3) +flash_cfg3_val: + .word STNOR_GPMC_CONFIG3 +flash_cfg4_addr: + .word (GPMC_CONFIG_CS0_BASE + GPMC_CONFIG4) +flash_cfg4_val: + .word STNOR_GPMC_CONFIG4 +flash_cfg5_val: + .word STNOR_GPMC_CONFIG5 +flash_cfg5_addr: + .word (GPMC_CONFIG_CS0_BASE + 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 + +ENTRY(lowlevel_init) + ldr sp, SRAM_STACK + str ip, [sp] /* stash ip register */ + mov ip, lr /* save link reg across call */ +#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT) +/* + * No need to copy/exec the clock code - DPLL adjust already done + * in NAND/oneNAND Boot. + */ + ldr r1, =SRAM_CLK_CODE + bl cpy_clk_code +#endif /* NAND Boot */ + mov lr, ip /* restore link reg */ + ldr ip, [sp] /* restore save ip */ + /* tail-call s_init to setup pll, mux, memory */ + b s_init + +ENDPROC(lowlevel_init) + + /* 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 MPU_M_12_ES1, MPU_N_12_ES1, MPU_FSEL_12_ES1, MPU_M2_12_ES1 +/* ES2 */ +.word MPU_M_12_ES2, MPU_N_12_ES2, MPU_FSEL_12_ES2, MPU_M2_ES2 +/* 3410 */ +.word MPU_M_12, MPU_N_12, MPU_FSEL_12, MPU_M2_12 + +/* 13MHz */ +/* ES1 */ +.word MPU_M_13_ES1, MPU_N_13_ES1, MPU_FSEL_13_ES1, MPU_M2_13_ES1 +/* ES2 */ +.word MPU_M_13_ES2, MPU_N_13_ES2, MPU_FSEL_13_ES2, MPU_M2_13_ES2 +/* 3410 */ +.word MPU_M_13, MPU_N_13, MPU_FSEL_13, MPU_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word MPU_M_19P2_ES1, MPU_N_19P2_ES1, MPU_FSEL_19P2_ES1, MPU_M2_19P2_ES1 +/* ES2 */ +.word MPU_M_19P2_ES2, MPU_N_19P2_ES2, MPU_FSEL_19P2_ES2, MPU_M2_19P2_ES2 +/* 3410 */ +.word MPU_M_19P2, MPU_N_19P2, MPU_FSEL_19P2, MPU_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word MPU_M_26_ES1, MPU_N_26_ES1, MPU_FSEL_26_ES1, MPU_M2_26_ES1 +/* ES2 */ +.word MPU_M_26_ES2, MPU_N_26_ES2, MPU_FSEL_26_ES2, MPU_M2_26_ES2 +/* 3410 */ +.word MPU_M_26, MPU_N_26, MPU_FSEL_26, MPU_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word MPU_M_38P4_ES1, MPU_N_38P4_ES1, MPU_FSEL_38P4_ES1, MPU_M2_38P4_ES1 +/* ES2 */ +.word MPU_M_38P4_ES2, MPU_N_38P4_ES2, MPU_FSEL_38P4_ES2, MPU_M2_38P4_ES2 +/* 3410 */ +.word MPU_M_38P4, MPU_N_38P4, MPU_FSEL_38P4, MPU_M2_38P4 + + +.globl get_mpu_dpll_param +get_mpu_dpll_param: + adr r0, mpu_dpll_param + mov pc, lr + +iva_dpll_param: +/* 12MHz */ +/* ES1 */ +.word IVA_M_12_ES1, IVA_N_12_ES1, IVA_FSEL_12_ES1, IVA_M2_12_ES1 +/* ES2 */ +.word IVA_M_12_ES2, IVA_N_12_ES2, IVA_FSEL_12_ES2, IVA_M2_12_ES2 +/* 3410 */ +.word IVA_M_12, IVA_N_12, IVA_FSEL_12, IVA_M2_12 + +/* 13MHz */ +/* ES1 */ +.word IVA_M_13_ES1, IVA_N_13_ES1, IVA_FSEL_13_ES1, IVA_M2_13_ES1 +/* ES2 */ +.word IVA_M_13_ES2, IVA_N_13_ES2, IVA_FSEL_13_ES2, IVA_M2_13_ES2 +/* 3410 */ +.word IVA_M_13, IVA_N_13, IVA_FSEL_13, IVA_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word IVA_M_19P2_ES1, IVA_N_19P2_ES1, IVA_FSEL_19P2_ES1, IVA_M2_19P2_ES1 +/* ES2 */ +.word IVA_M_19P2_ES2, IVA_N_19P2_ES2, IVA_FSEL_19P2_ES2, IVA_M2_19P2_ES2 +/* 3410 */ +.word IVA_M_19P2, IVA_N_19P2, IVA_FSEL_19P2, IVA_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word IVA_M_26_ES1, IVA_N_26_ES1, IVA_FSEL_26_ES1, IVA_M2_26_ES1 +/* ES2 */ +.word IVA_M_26_ES2, IVA_N_26_ES2, IVA_FSEL_26_ES2, IVA_M2_26_ES2 +/* 3410 */ +.word IVA_M_26, IVA_N_26, IVA_FSEL_26, IVA_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word IVA_M_38P4_ES1, IVA_N_38P4_ES1, IVA_FSEL_38P4_ES1, IVA_M2_38P4_ES1 +/* ES2 */ +.word IVA_M_38P4_ES2, IVA_N_38P4_ES2, IVA_FSEL_38P4_ES2, IVA_M2_38P4_ES2 +/* 3410 */ +.word IVA_M_38P4, IVA_N_38P4, IVA_FSEL_38P4, IVA_M2_38P4 + + +.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 CORE_M_12_ES1, CORE_N_12_ES1, CORE_FSL_12_ES1, CORE_M2_12_ES1 +/* ES2 */ +.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 +/* 3410 */ +.word CORE_M_12, CORE_N_12, CORE_FSEL_12, CORE_M2_12 + +/* 13MHz */ +/* ES1 */ +.word CORE_M_13_ES1, CORE_N_13_ES1, CORE_FSL_13_ES1, CORE_M2_13_ES1 +/* ES2 */ +.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 +/* 3410 */ +.word CORE_M_13, CORE_N_13, CORE_FSEL_13, CORE_M2_13 + +/* 19.2MHz */ +/* ES1 */ +.word CORE_M_19P2_ES1, CORE_N_19P2_ES1, CORE_FSL_19P2_ES1, CORE_M2_19P2_ES1 +/* ES2 */ +.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 +/* 3410 */ +.word CORE_M_19P2, CORE_N_19P2, CORE_FSEL_19P2, CORE_M2_19P2 + +/* 26MHz */ +/* ES1 */ +.word CORE_M_26_ES1, CORE_N_26_ES1, CORE_FSL_26_ES1, CORE_M2_26_ES1 +/* ES2 */ +.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 +/* 3410 */ +.word CORE_M_26, CORE_N_26, CORE_FSEL_26, CORE_M2_26 + +/* 38.4MHz */ +/* ES1 */ +.word CORE_M_38P4_ES1, CORE_N_38P4_ES1, CORE_FSL_38P4_ES1, CORE_M2_38P4_ES1 +/* ES2 */ +.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_M2_38P4 +/* 3410 */ +.word CORE_M_38P4, CORE_N_38P4, CORE_FSEL_38P4, CORE_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 PER_M_12, PER_N_12, PER_FSEL_12, PER_M2_12 + +/* 13MHz */ +.word PER_M_13, PER_N_13, PER_FSEL_13, PER_M2_13 + +/* 19.2MHz */ +.word PER_M_19P2, PER_N_19P2, PER_FSEL_19P2, PER_M2_19P2 + +/* 26MHz */ +.word PER_M_26, PER_N_26, PER_FSEL_26, PER_M2_26 + +/* 38.4MHz */ +.word PER_M_38P4, PER_N_38P4, PER_FSEL_38P4, PER_M2_38P4 + +.globl get_per_dpll_param +get_per_dpll_param: + adr r0, per_dpll_param + mov pc, lr + +/* PER2 DPLL values */ +per2_dpll_param: +/* 12MHz */ +.word PER2_M_12, PER2_N_12, PER2_FSEL_12, PER2_M2_12 + +/* 13MHz */ +.word PER2_M_13, PER2_N_13, PER2_FSEL_13, PER2_M2_13 + +/* 19.2MHz */ +.word PER2_M_19P2, PER2_N_19P2, PER2_FSEL_19P2, PER2_M2_19P2 + +/* 26MHz */ +.word PER2_M_26, PER2_N_26, PER2_FSEL_26, PER2_M2_26 + +/* 38.4MHz */ +.word PER2_M_38P4, PER2_N_38P4, PER2_FSEL_38P4, PER2_M2_38P4 + +.globl get_per2_dpll_param +get_per2_dpll_param: + adr r0, per2_dpll_param + mov pc, lr + +/* + * Tables for 36XX/37XX devices + * + */ +mpu_36x_dpll_param: +/* 12MHz */ +.word 50, 0, 0, 1 +/* 13MHz */ +.word 600, 12, 0, 1 +/* 19.2MHz */ +.word 125, 3, 0, 1 +/* 26MHz */ +.word 300, 12, 0, 1 +/* 38.4MHz */ +.word 125, 7, 0, 1 + +iva_36x_dpll_param: +/* 12MHz */ +.word 130, 2, 0, 1 +/* 13MHz */ +.word 20, 0, 0, 1 +/* 19.2MHz */ +.word 325, 11, 0, 1 +/* 26MHz */ +.word 10, 0, 0, 1 +/* 38.4MHz */ +.word 325, 23, 0, 1 + +core_36x_dpll_param: +/* 12MHz */ +.word 100, 2, 0, 1 +/* 13MHz */ +.word 400, 12, 0, 1 +/* 19.2MHz */ +.word 375, 17, 0, 1 +/* 26MHz */ +.word 200, 12, 0, 1 +/* 38.4MHz */ +.word 375, 35, 0, 1 + +per_36x_dpll_param: +/* SYSCLK M N M2 M3 M4 M5 M6 m2DIV */ +.word 12000, 360, 4, 9, 16, 5, 4, 3, 1 +.word 13000, 864, 12, 9, 16, 9, 4, 3, 1 +.word 19200, 360, 7, 9, 16, 5, 4, 3, 1 +.word 26000, 432, 12, 9, 16, 9, 4, 3, 1 +.word 38400, 360, 15, 9, 16, 5, 4, 3, 1 + +per2_36x_dpll_param: +/* 12MHz */ +.word PER2_36XX_M_12, PER2_36XX_N_12, 0, PER2_36XX_M2_12 +/* 13MHz */ +.word PER2_36XX_M_13, PER2_36XX_N_13, 0, PER2_36XX_M2_13 +/* 19.2MHz */ +.word PER2_36XX_M_19P2, PER2_36XX_N_19P2, 0, PER2_36XX_M2_19P2 +/* 26MHz */ +.word PER2_36XX_M_26, PER2_36XX_N_26, 0, PER2_36XX_M2_26 +/* 38.4MHz */ +.word PER2_36XX_M_38P4, PER2_36XX_N_38P4, 0, PER2_36XX_M2_38P4 + + +ENTRY(get_36x_mpu_dpll_param) + adr r0, mpu_36x_dpll_param + mov pc, lr +ENDPROC(get_36x_mpu_dpll_param) + +ENTRY(get_36x_iva_dpll_param) + adr r0, iva_36x_dpll_param + mov pc, lr +ENDPROC(get_36x_iva_dpll_param) + +ENTRY(get_36x_core_dpll_param) + adr r0, core_36x_dpll_param + mov pc, lr +ENDPROC(get_36x_core_dpll_param) + +ENTRY(get_36x_per_dpll_param) + adr r0, per_36x_dpll_param + mov pc, lr +ENDPROC(get_36x_per_dpll_param) + +ENTRY(get_36x_per2_dpll_param) + adr r0, per2_36x_dpll_param + mov pc, lr +ENDPROC(get_36x_per2_dpll_param)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/sdrc.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/sdrc.c new file mode 100644 index 0000000..4f15ac9 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/sdrc.c
@@ -0,0 +1,241 @@ +/* + * Functions related to OMAP3 SDRC. + * + * This file has been created after exctracting and consolidating + * the SDRC related content from mem.c and board.c, also created + * generic init function (mem_init). + * + * Copyright (C) 2004-2010 + * Texas Instruments Incorporated - http://www.ti.com/ + * + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * + * Author : + * Vaibhav Hiremath <hvaibhav@ti.com> + * + * Original implementation by (mem.c, board.c) : + * Sunil Kumar <sunilsaini05@gmail.com> + * Shashi Ranjan <shashiranjanmca05@gmail.com> + * Manikandan Pillai <mani.pillai@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/mem.h> +#include <asm/arch/sys_proto.h> + +DECLARE_GLOBAL_DATA_PTR; +extern omap3_sysinfo sysinfo; + +static struct sdrc *sdrc_base = (struct sdrc *)OMAP34XX_SDRC_BASE; + +/* + * is_mem_sdr - + * - Return 1 if mem type in use is SDR + */ +u32 is_mem_sdr(void) +{ + if (readl(&sdrc_base->cs[CS0].mr) == SDRC_MR_0_SDR) + return 1; + return 0; +} + +/* + * make_cs1_contiguous - + * - When we have CS1 populated we want to have it mapped after cs0 to allow + * command line mem=xyz use all memory with out discontinuous support + * compiled in. We could do it in the ATAG, but there really is two banks... + */ +void make_cs1_contiguous(void) +{ + u32 size, a_add_low, a_add_high; + + size = get_sdr_cs_size(CS0); + size >>= 25; /* divide by 32 MiB to 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 */ + writel((a_add_high | a_add_low), &sdrc_base->cs_cfg); + +} + + +/* + * get_sdr_cs_size - + * - Get size of chip select 0/1 + */ +u32 get_sdr_cs_size(u32 cs) +{ + u32 size; + + /* get ram size field */ + size = readl(&sdrc_base->cs[cs].mcfg) >> 8; + size &= 0x3FF; /* remove unwanted bits */ + size <<= 21; /* multiply by 2 MiB to find size in MB */ + return size; +} + +/* + * get_sdr_cs_offset - + * - Get offset of cs from cs0 start + */ +u32 get_sdr_cs_offset(u32 cs) +{ + u32 offset; + + if (!cs) + return 0; + + offset = readl(&sdrc_base->cs_cfg); + offset = (offset & 15) << 27 | (offset & 0x300) << 17; + + return offset; +} + +/* + * write_sdrc_timings - + * - Takes CS and associated timings and initalize SDRAM + * - Test CS to make sure it's OK for use + */ +static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base, + struct board_sdrc_timings *timings) +{ + /* Setup timings we got from the board. */ + writel(timings->mcfg, &sdrc_base->cs[cs].mcfg); + writel(timings->ctrla, &sdrc_actim_base->ctrla); + writel(timings->ctrlb, &sdrc_actim_base->ctrlb); + writel(timings->rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl); + writel(CMD_NOP, &sdrc_base->cs[cs].manual); + writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual); + writel(timings->mr, &sdrc_base->cs[cs].mr); + + /* + * Test ram in this bank + * Disable if bad or not present + */ + if (!mem_ok(cs)) + writel(0, &sdrc_base->cs[cs].mcfg); +} + +/* + * do_sdrc_init - + * - Code called once in C-Stack only context for CS0 and with early being + * true and a possible 2nd time depending on memory configuration from + * stack+global context. + */ +void do_sdrc_init(u32 cs, u32 early) +{ + struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1; + struct board_sdrc_timings timings; + + sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE; + sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE; + + /* set some default timings */ + timings.sharing = SDRC_SHARING; + + /* + * When called in the early context this may be SPL and we will + * need to set all of the timings. This ends up being board + * specific so we call a helper function to take care of this + * for us. Otherwise, to be safe, we need to copy the settings + * from the first bank to the second. We will setup CS0, + * then set cs_cfg to the appropriate value then try and + * setup CS1. + */ +#ifdef CONFIG_SPL_BUILD + /* set/modify board-specific timings */ + get_board_mem_timings(&timings); +#endif + if (early) { + /* reset sdrc controller */ + writel(SOFTRESET, &sdrc_base->sysconfig); + wait_on_value(RESETDONE, RESETDONE, &sdrc_base->status, + 12000000); + writel(0, &sdrc_base->sysconfig); + + /* setup sdrc to ball mux */ + writel(timings.sharing, &sdrc_base->sharing); + + /* Disable Power Down of CKE because of 1 CKE on combo part */ + writel(WAKEUPPROC | SRFRONRESET | PAGEPOLICY_HIGH, + &sdrc_base->power); + + writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl); + sdelay(0x20000); +#ifdef CONFIG_SPL_BUILD + write_sdrc_timings(CS0, sdrc_actim_base0, &timings); + make_cs1_contiguous(); + write_sdrc_timings(CS1, sdrc_actim_base1, &timings); +#endif + + } + + /* + * If we aren't using SPL we have been loaded by some + * other means which may not have correctly initialized + * both CS0 and CS1 (such as some older versions of x-loader) + * so we may be asked now to setup CS1. + */ + if (cs == CS1) { + timings.mcfg = readl(&sdrc_base->cs[CS0].mcfg), + timings.rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl); + timings.ctrla = readl(&sdrc_actim_base0->ctrla); + timings.ctrlb = readl(&sdrc_actim_base0->ctrlb); + timings.mr = readl(&sdrc_base->cs[CS0].mr); + write_sdrc_timings(cs, sdrc_actim_base1, &timings); + } +} + +/* + * dram_init - + * - Sets uboots idea of sdram size + */ +int dram_init(void) +{ + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + /* + * We always need to have cs_cfg point at where the second + * bank would be, if present. Failure to do so can lead to + * strange situations where memory isn't detected and + * configured correctly. CS0 will already have been setup + * at this point. + */ + make_cs1_contiguous(); + do_sdrc_init(CS1, NOT_EARLY); + size1 = get_sdr_cs_size(CS1); + + gd->ram_size = size0 + size1; + + return 0; +} + +void dram_init_banksize (void) +{ + unsigned int size0 = 0, size1 = 0; + + size0 = get_sdr_cs_size(CS0); + size1 = get_sdr_cs_size(CS1); + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = size0; + gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + get_sdr_cs_offset(CS1); + gd->bd->bi_dram[1].size = size1; +} + +/* + * mem_init - + * - Init the sdrc chip, + * - Selects CS0 and CS1, + */ +void mem_init(void) +{ + /* only init up first bank here */ + do_sdrc_init(CS0, EARLY_INIT); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/spl_id_nand.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/spl_id_nand.c new file mode 100644 index 0000000..db6de09 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/spl_id_nand.c
@@ -0,0 +1,74 @@ +/* + * (C) Copyright 2011 + * Texas Instruments, <www.ti.com> + * + * Author : + * Tom Rini <trini@ti.com> + * + * Initial Code from: + * Richard Woodruff <r-woodruff2@ti.com> + * Jian Zhang <jzhang@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/mtd/nand.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/mem.h> + +static struct gpmc *gpmc_config = (struct gpmc *)GPMC_BASE; + +/* nand_command: Send a flash command to the flash chip */ +static void nand_command(u8 command) +{ + writeb(command, &gpmc_config->cs[0].nand_cmd); + + if (command == NAND_CMD_RESET) { + unsigned char ret_val; + writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd); + do { + /* Wait until ready */ + ret_val = readl(&gpmc_config->cs[0].nand_dat); + } while ((ret_val & NAND_STATUS_READY) != NAND_STATUS_READY); + } +} + +/* + * Many boards will want to know the results of the NAND_CMD_READID command + * in order to decide what to do about DDR initialization. This function + * allows us to do that very early and to pass those results back to the + * board so it can make whatever decisions need to be made. + */ +void identify_nand_chip(int *mfr, int *id) +{ + /* Make sure that we have setup GPMC for NAND correctly. */ + writel(M_NAND_GPMC_CONFIG1, &gpmc_config->cs[0].config1); + writel(M_NAND_GPMC_CONFIG2, &gpmc_config->cs[0].config2); + writel(M_NAND_GPMC_CONFIG3, &gpmc_config->cs[0].config3); + writel(M_NAND_GPMC_CONFIG4, &gpmc_config->cs[0].config4); + writel(M_NAND_GPMC_CONFIG5, &gpmc_config->cs[0].config5); + writel(M_NAND_GPMC_CONFIG6, &gpmc_config->cs[0].config6); + + /* + * Enable the config. The CS size goes in bits 11:8. We set + * bit 6 to enable the CS and the base address goes into bits 5:0. + */ + writel((GPMC_SIZE_128M << 8) | (GPMC_CS_ENABLE << 6) | + ((NAND_BASE >> 24) & GPMC_BASEADDR_MASK), + &gpmc_config->cs[0].config7); + + sdelay(2000); + + /* Issue a RESET and then READID */ + nand_command(NAND_CMD_RESET); + nand_command(NAND_CMD_READID); + + /* Set the address to read to 0x0 */ + writeb(0x0, &gpmc_config->cs[0].nand_adr); + + /* Read off the manufacturer and device id. */ + *mfr = readb(&gpmc_config->cs[0].nand_dat); + *id = readb(&gpmc_config->cs[0].nand_dat); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap3/sys_info.c b/u-boot-imx/arch/arm/cpu/armv7/omap3/sys_info.c new file mode 100644 index 0000000..bbb65bb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -0,0 +1,366 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, <www.ti.com> + * + * Author : + * Manikandan Pillai <mani.pillai@ti.com> + * + * Derived from Beagle Board and 3430 SDP code by + * Richard Woodruff <r-woodruff2@ti.com> + * Syed Mohammed Khasim <khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/mem.h> /* get mem tables */ +#include <asm/arch/sys_proto.h> +#include <asm/bootm.h> + +#include <i2c.h> +#include <linux/compiler.h> + +extern omap3_sysinfo sysinfo; +static struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; + +#ifdef CONFIG_DISPLAY_CPUINFO +static char *rev_s[CPU_3XX_MAX_REV] = { + "1.0", + "2.0", + "2.1", + "3.0", + "3.1", + "UNKNOWN", + "UNKNOWN", + "3.1.2"}; + +/* this is the revision table for 37xx CPUs */ +static char *rev_s_37xx[CPU_37XX_MAX_REV] = { + "1.0", + "1.1", + "1.2"}; +#endif /* CONFIG_DISPLAY_CPUINFO */ + +/***************************************************************** + * get_dieid(u32 *id) - read die ID + *****************************************************************/ +void get_dieid(u32 *id) +{ + struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; + + id[3] = readl(&id_base->die_id_0); + id[2] = readl(&id_base->die_id_1); + id[1] = readl(&id_base->die_id_2); + id[0] = readl(&id_base->die_id_3); +} + +/***************************************************************** + * dieid_num_r(void) - read and set die ID + *****************************************************************/ +void dieid_num_r(void) +{ + char *uid_s, die_id[34]; + u32 id[4]; + + memset(die_id, 0, sizeof(die_id)); + + uid_s = getenv("dieid#"); + + if (uid_s == NULL) { + get_dieid(id); + sprintf(die_id, "%08x%08x%08x%08x", id[0], id[1], id[2], id[3]); + setenv("dieid#", die_id); + uid_s = die_id; + } + + printf("Die ID #%s\n", uid_s); +} + +/****************************************** + * get_cpu_type(void) - extract cpu info + ******************************************/ +u32 get_cpu_type(void) +{ + return readl(&ctrl_base->ctrl_omap_stat); +} + +/****************************************** + * get_cpu_id(void) - extract cpu id + * returns 0 for ES1.0, cpuid otherwise + ******************************************/ +u32 get_cpu_id(void) +{ + struct ctrl_id *id_base; + u32 cpuid = 0; + + /* + * On ES1.0 the IDCODE register is not exposed on L4 + * so using CPU ID to differentiate between ES1.0 and > ES1.0. + */ + __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(cpuid)); + if ((cpuid & 0xf) == 0x0) { + return 0; + } else { + /* Decode the IDs on > ES1.0 */ + id_base = (struct ctrl_id *) OMAP34XX_ID_L4_IO_BASE; + + cpuid = readl(&id_base->idcode); + } + + return cpuid; +} + +/****************************************** + * get_cpu_family(void) - extract cpu info + ******************************************/ +u32 get_cpu_family(void) +{ + u16 hawkeye; + u32 cpu_family; + u32 cpuid = get_cpu_id(); + + if (cpuid == 0) + return CPU_OMAP34XX; + + 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; + } + + return cpu_family; +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ + u32 cpuid = get_cpu_id(); + + if (cpuid == 0) + return CPU_3XX_ES10; + else + return (cpuid >> CPU_3XX_ID_SHIFT) & 0xf; +} + +/***************************************************************** + * get_sku_id(void) - read sku_id to get info on max clock rate + *****************************************************************/ +u32 get_sku_id(void) +{ + struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; + return readl(&id_base->sku_id) & SKUID_CLK_MASK; +} + +/*************************************************************************** + * get_gpmc0_base() - Return current address hardware will be + * fetching from. The below effectively gives what is correct, its a bit + * mis-leading compared to the TRM. For the most general case the mask + * needs to be also taken into account this does work in practice. + * - for u-boot we currently map: + * -- 0 to nothing, + * -- 4 to flash + * -- 8 to enent + * -- c to wifi + ****************************************************************************/ +u32 get_gpmc0_base(void) +{ + u32 b; + + b = readl(&gpmc_cfg->cs[0].config7); + b &= 0x1F; /* keep base [5:0] */ + b = b << 24; /* ret 0x0b000000 */ + return b; +} + +/******************************************************************* + * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) + *******************************************************************/ +u32 get_gpmc0_width(void) +{ + return WIDTH_16BIT; +} + +/************************************************************************* + * get_board_rev() - setup to pass kernel board revision information + * returns:(bit[0-3] sub version, higher bit[7-4] is higher version) + *************************************************************************/ +u32 __weak get_board_rev(void) +{ + return 0x20; +} + +/******************************************************** + * get_base(); get upper addr of current execution + *******************************************************/ +static u32 get_base(void) +{ + u32 val; + + __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); + val &= 0xF0000000; + val >>= 28; + return val; +} + +/******************************************************** + * is_running_in_flash() - tell if currently running in + * FLASH. + *******************************************************/ +u32 is_running_in_flash(void) +{ + if (get_base() < 4) + return 1; /* in FLASH */ + + return 0; /* running in SRAM or SDRAM */ +} + +/******************************************************** + * is_running_in_sram() - tell if currently running in + * SRAM. + *******************************************************/ +u32 is_running_in_sram(void) +{ + if (get_base() == 4) + return 1; /* in SRAM */ + + return 0; /* running in FLASH or SDRAM */ +} + +/******************************************************** + * is_running_in_sdram() - tell if currently running in + * SDRAM. + *******************************************************/ +u32 is_running_in_sdram(void) +{ + if (get_base() > 4) + return 1; /* in SDRAM */ + + return 0; /* running in SRAM or FLASH */ +} + +/*************************************************************** + * get_boot_type() - Is this an XIP type device or a stream one + * bits 4-0 specify type. Bit 5 says mem/perif + ***************************************************************/ +u32 get_boot_type(void) +{ + return (readl(&ctrl_base->status) & SYSBOOT_MASK); +} + +/************************************************************* + * get_device_type(): tell if GP/HS/EMU/TST + *************************************************************/ +u32 get_device_type(void) +{ + return ((readl(&ctrl_base->status) & (DEVICE_MASK)) >> 8); +} + +#ifdef CONFIG_DISPLAY_CPUINFO +/** + * Print CPU information + */ +int print_cpuinfo (void) +{ + char *cpu_family_s, *cpu_s, *sec_s, *max_clk; + + switch (get_cpu_family()) { + case CPU_OMAP34XX: + cpu_family_s = "OMAP"; + switch (get_cpu_type()) { + case OMAP3503: + cpu_s = "3503"; + break; + case OMAP3515: + cpu_s = "3515"; + break; + case OMAP3525: + cpu_s = "3525"; + break; + case OMAP3530: + cpu_s = "3530"; + break; + default: + cpu_s = "35XX"; + break; + } + if ((get_cpu_rev() >= CPU_3XX_ES31) && + (get_sku_id() == SKUID_CLK_720MHZ)) + max_clk = "720 MHz"; + else + max_clk = "600 MHz"; + + break; + case CPU_AM35XX: + cpu_family_s = "AM"; + switch (get_cpu_type()) { + case AM3505: + cpu_s = "3505"; + break; + case AM3517: + cpu_s = "3517"; + break; + default: + cpu_s = "35XX"; + break; + } + max_clk = "600 Mhz"; + break; + case CPU_OMAP36XX: + cpu_family_s = "OMAP"; + switch (get_cpu_type()) { + case OMAP3730: + cpu_s = "3630/3730"; + break; + default: + cpu_s = "36XX/37XX"; + break; + } + max_clk = "1 Ghz"; + break; + default: + cpu_family_s = "OMAP"; + cpu_s = "35XX"; + max_clk = "600 Mhz"; + } + + switch (get_device_type()) { + case TST_DEVICE: + sec_s = "TST"; + break; + case EMU_DEVICE: + sec_s = "EMU"; + break; + case HS_DEVICE: + sec_s = "HS"; + break; + case GP_DEVICE: + sec_s = "GP"; + break; + default: + sec_s = "?"; + } + + if (CPU_OMAP36XX == get_cpu_family()) + printf("%s%s-%s ES%s, CPU-OPP2, L3-200MHz, Max CPU Clock %s\n", + cpu_family_s, cpu_s, sec_s, + rev_s_37xx[get_cpu_rev()], max_clk); + else + printf("%s%s-%s ES%s, CPU-OPP2, L3-165MHz, Max CPU Clock %s\n", + cpu_family_s, cpu_s, sec_s, + rev_s[get_cpu_rev()], max_clk); + + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/omap4/Kconfig new file mode 100644 index 0000000..eccf897 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/Kconfig
@@ -0,0 +1,24 @@ +if OMAP44XX + +choice + prompt "OMAP4 board select" + +config TARGET_DUOVERO + bool "OMAP4430 Gumstix Duovero" + +config TARGET_OMAP4_PANDA + bool "TI OMAP4 PandaBoard" + +config TARGET_OMAP4_SDP4430 + bool "TI OMAP4 SDP4430" + +endchoice + +config SYS_SOC + default "omap4" + +source "board/gumstix/duovero/Kconfig" +source "board/ti/panda/Kconfig" +source "board/ti/sdp4430/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/Makefile b/u-boot-imx/arch/arm/cpu/armv7/omap4/Makefile new file mode 100644 index 0000000..76a032a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/Makefile
@@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2010 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += sdram_elpida.o +obj-y += hwinit.o +obj-y += emif.o +obj-y += prcm-regs.o +obj-y += hw_data.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/config.mk b/u-boot-imx/arch/arm/cpu/armv7/omap4/config.mk new file mode 100644 index 0000000..ad44d63 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/config.mk
@@ -0,0 +1,15 @@ +# +# Copyright 2011 Linaro Limited +# +# (C) Copyright 2010 +# Texas Instruments, <www.ti.com> +# +# Aneesh V <aneesh@ti.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifdef CONFIG_SPL_BUILD +ALL-y += MLO +else +ALL-y += u-boot.img +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/emif.c b/u-boot-imx/arch/arm/cpu/armv7/omap4/emif.c new file mode 100644 index 0000000..e89032b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/emif.c
@@ -0,0 +1,112 @@ +/* + * EMIF programming + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> +#include <asm/utils.h> + +#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +u32 *const T_num = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_NUM; +u32 *const T_den = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_DEN; +#endif + +#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +/* Base AC Timing values specified by JESD209-2 for 400MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_400_mhz = { + .max_freq = 400000000, + .RL = 6, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* Base AC Timing values specified by JESD209-2 for 200 MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_200_mhz = { + .max_freq = 200000000, + .RL = 3, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 20, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* + * Min tCK values specified by JESD209-2 + * Min tCK specifies the minimum duration of some AC timing parameters in terms + * of the number of cycles. If the calculated number of cycles based on the + * absolute time value is less than the min tCK value, min tCK value should + * be used instead. This typically happens at low frequencies. + */ +static const struct lpddr2_min_tck min_tck_jedec = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings const* + jedec_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_200_mhz, + &timings_jedec_400_mhz +}; + +static const struct lpddr2_device_timings jedec_default_timings = { + .ac_timings = jedec_ac_timings, + .min_tck = &min_tck_jedec +}; + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Assume Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &jedec_default_timings; + *cs1_device_timings = &jedec_default_timings; +} +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/hw_data.c b/u-boot-imx/arch/arm/cpu/armv7/omap4/hw_data.c new file mode 100644 index 0000000..029533c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/hw_data.c
@@ -0,0 +1,457 @@ +/* + * + * HW data initialization for OMAP4 + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/omap.h> +#include <asm/arch/sys_proto.h> +#include <asm/omap_common.h> +#include <asm/arch/clock.h> +#include <asm/omap_gpio.h> +#include <asm/io.h> + +struct prcm_regs const **prcm = + (struct prcm_regs const **) OMAP_SRAM_SCRATCH_PRCM_PTR; +struct dplls const **dplls_data = + (struct dplls const **) OMAP_SRAM_SCRATCH_DPLLS_PTR; +struct vcores_data const **omap_vcores = + (struct vcores_data const **) OMAP_SRAM_SCRATCH_VCORES_PTR; +struct omap_sys_ctrl_regs const **ctrl = + (struct omap_sys_ctrl_regs const **)OMAP_SRAM_SCRATCH_SYS_CTRL; + +/* + * The M & N values in the following tables are created using the + * following tool: + * tools/omap/clocks_get_m_n.c + * Please use this tool for creating the table for any new frequency. + */ + +/* + * dpll locked at 1400 MHz MPU clk at 700 MHz(OPP100) - DCC OFF + * OMAP4460 OPP_NOM frequency + */ +static const struct dpll_params mpu_dpll_params_1400mhz[NUM_SYS_CLKS] = { + {175, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {700, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {125, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {401, 10, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {350, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {700, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {638, 34, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* + * dpll locked at 1600 MHz - MPU clk at 800 MHz(OPP Turbo 4430) + * OMAP4430 OPP_TURBO frequency + * OMAP4470 OPP_NOM frequency + */ +static const struct dpll_params mpu_dpll_params_1600mhz[NUM_SYS_CLKS] = { + {200, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {800, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {619, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {125, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {400, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {800, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {125, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* + * dpll locked at 1200 MHz - MPU clk at 600 MHz + * OMAP4430 OPP_NOM frequency + */ +static const struct dpll_params mpu_dpll_params_1200mhz[NUM_SYS_CLKS] = { + {50, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {600, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {250, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {125, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {300, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {200, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {125, 7, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OMAP4460 OPP_NOM frequency */ +/* OMAP4470 OPP_NOM (Low Power) frequency */ +static const struct dpll_params core_dpll_params_1600mhz[NUM_SYS_CLKS] = { + {200, 2, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 12 MHz */ + {800, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 13 MHz */ + {619, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 16.8 MHz */ + {125, 2, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 19.2 MHz */ + {400, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 26 MHz */ + {800, 26, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 27 MHz */ + {125, 5, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OMAP4430 ES1 OPP_NOM frequency */ +static const struct dpll_params core_dpll_params_es1_1524mhz[NUM_SYS_CLKS] = { + {127, 1, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 12 MHz */ + {762, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 13 MHz */ + {635, 13, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 16.8 MHz */ + {635, 15, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 19.2 MHz */ + {381, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 26 MHz */ + {254, 8, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 27 MHz */ + {496, 24, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OMAP4430 ES2.X OPP_NOM frequency */ +static const struct dpll_params + core_dpll_params_es2_1600mhz_ddr200mhz[NUM_SYS_CLKS] = { + {200, 2, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 12 MHz */ + {800, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 13 MHz */ + {619, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 16.8 MHz */ + {125, 2, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 19.2 MHz */ + {400, 12, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 26 MHz */ + {800, 26, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1}, /* 27 MHz */ + {125, 5, 2, 5, 8, 4, 6, 5, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params per_dpll_params_1536mhz[NUM_SYS_CLKS] = { + {64, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 12 MHz */ + {768, 12, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 13 MHz */ + {320, 6, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 16.8 MHz */ + {40, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 19.2 MHz */ + {384, 12, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 26 MHz */ + {256, 8, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1}, /* 27 MHz */ + {20, 0, 8, 6, 12, 9, 4, 5, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params iva_dpll_params_1862mhz[NUM_SYS_CLKS] = { + {931, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {931, 12, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {665, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {727, 14, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {931, 25, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {931, 26, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {291, 11, -1, -1, 4, 7, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* ABE M & N values with sys_clk as source */ +static const struct dpll_params + abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = { + {49, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {68, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {35, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {46, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {34, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {29, 7, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {64, 24, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* ABE M & N values with 32K clock as source */ +static const struct dpll_params abe_dpll_params_32k_196608khz = { + 750, 0, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = { + {80, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {960, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {400, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {50, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {480, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {320, 8, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {25, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +struct dplls omap4430_dplls_es1 = { + .mpu = mpu_dpll_params_1200mhz, + .core = core_dpll_params_es1_1524mhz, + .per = per_dpll_params_1536mhz, + .iva = iva_dpll_params_1862mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls omap4430_dplls_es20 = { + .mpu = mpu_dpll_params_1200mhz, + .core = core_dpll_params_es2_1600mhz_ddr200mhz, + .per = per_dpll_params_1536mhz, + .iva = iva_dpll_params_1862mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls omap4430_dplls = { + .mpu = mpu_dpll_params_1200mhz, + .core = core_dpll_params_1600mhz, + .per = per_dpll_params_1536mhz, + .iva = iva_dpll_params_1862mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls omap4460_dplls = { + .mpu = mpu_dpll_params_1400mhz, + .core = core_dpll_params_1600mhz, + .per = per_dpll_params_1536mhz, + .iva = iva_dpll_params_1862mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls omap4470_dplls = { + .mpu = mpu_dpll_params_1600mhz, + .core = core_dpll_params_1600mhz, + .per = per_dpll_params_1536mhz, + .iva = iva_dpll_params_1862mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct pmic_data twl6030_4430es1 = { + .base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV, + .step = 12660, /* 12.66 mV represented in uV */ + /* The code starts at 1 not 0 */ + .start_code = 1, + .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR, + .pmic_bus_init = sri2c_init, + .pmic_write = omap_vc_bypass_send_value, +}; + +/* twl6030 struct is used for TWL6030 and TWL6032 PMIC */ +struct pmic_data twl6030 = { + .base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV, + .step = 12660, /* 12.66 mV represented in uV */ + /* The code starts at 1 not 0 */ + .start_code = 1, + .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR, + .pmic_bus_init = sri2c_init, + .pmic_write = omap_vc_bypass_send_value, +}; + +struct pmic_data tps62361 = { + .base_offset = TPS62361_BASE_VOLT_MV, + .step = 10000, /* 10 mV represented in uV */ + .start_code = 0, + .gpio = TPS62361_VSEL0_GPIO, + .gpio_en = 1, + .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR, + .pmic_bus_init = sri2c_init, + .pmic_write = omap_vc_bypass_send_value, +}; + +struct vcores_data omap4430_volts_es1 = { + .mpu.value = 1325, + .mpu.addr = SMPS_REG_ADDR_VCORE1, + .mpu.pmic = &twl6030_4430es1, + + .core.value = 1200, + .core.addr = SMPS_REG_ADDR_VCORE3, + .core.pmic = &twl6030_4430es1, + + .mm.value = 1200, + .mm.addr = SMPS_REG_ADDR_VCORE2, + .mm.pmic = &twl6030_4430es1, +}; + +struct vcores_data omap4430_volts = { + .mpu.value = 1325, + .mpu.addr = SMPS_REG_ADDR_VCORE1, + .mpu.pmic = &twl6030, + + .core.value = 1200, + .core.addr = SMPS_REG_ADDR_VCORE3, + .core.pmic = &twl6030, + + .mm.value = 1200, + .mm.addr = SMPS_REG_ADDR_VCORE2, + .mm.pmic = &twl6030, +}; + +struct vcores_data omap4460_volts = { + .mpu.value = 1203, + .mpu.addr = TPS62361_REG_ADDR_SET1, + .mpu.pmic = &tps62361, + + .core.value = 1200, + .core.addr = SMPS_REG_ADDR_VCORE1, + .core.pmic = &twl6030, + + .mm.value = 1200, + .mm.addr = SMPS_REG_ADDR_VCORE2, + .mm.pmic = &twl6030, +}; + +/* + * Take closest integer part of the mV value corresponding to a TWL6032 SMPS + * voltage selection code. Aligned with OMAP4470 ES1.0 OCA V.0.7. + */ +struct vcores_data omap4470_volts = { + .mpu.value = 1202, + .mpu.addr = SMPS_REG_ADDR_SMPS1, + .mpu.pmic = &twl6030, + + .core.value = 1126, + .core.addr = SMPS_REG_ADDR_SMPS2, + .core.pmic = &twl6030, + + .mm.value = 1139, + .mm.addr = SMPS_REG_ADDR_SMPS5, + .mm.pmic = &twl6030, +}; + +/* + * Enable essential clock domains, modules and + * do some additional special settings needed + */ +void enable_basic_clocks(void) +{ + u32 const clk_domains_essential[] = { + (*prcm)->cm_l4per_clkstctrl, + (*prcm)->cm_l3init_clkstctrl, + (*prcm)->cm_memif_clkstctrl, + (*prcm)->cm_l4cfg_clkstctrl, + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_l3_gpmc_clkctrl, + (*prcm)->cm_memif_emif_1_clkctrl, + (*prcm)->cm_memif_emif_2_clkctrl, + (*prcm)->cm_l4cfg_l4_cfg_clkctrl, + (*prcm)->cm_wkup_gpio1_clkctrl, + (*prcm)->cm_l4per_gpio2_clkctrl, + (*prcm)->cm_l4per_gpio3_clkctrl, + (*prcm)->cm_l4per_gpio4_clkctrl, + (*prcm)->cm_l4per_gpio5_clkctrl, + (*prcm)->cm_l4per_gpio6_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_wkup_gptimer1_clkctrl, + (*prcm)->cm_l3init_hsmmc1_clkctrl, + (*prcm)->cm_l3init_hsmmc2_clkctrl, + (*prcm)->cm_l4per_gptimer2_clkctrl, + (*prcm)->cm_wkup_wdtimer2_clkctrl, + (*prcm)->cm_l4per_uart3_clkctrl, + 0 + }; + + /* Enable optional additional functional clock for GPIO4 */ + setbits_le32((*prcm)->cm_l4per_gpio4_clkctrl, + GPIO4_CLKCTRL_OPTFCLKEN_MASK); + + /* Enable 96 MHz clock for MMC1 & MMC2 */ + setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl, + HSMMC_CLKCTRL_CLKSEL_MASK); + setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl, + HSMMC_CLKCTRL_CLKSEL_MASK); + + /* Select 32KHz clock as the source of GPTIMER1 */ + setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl, + GPTIMER1_CLKCTRL_CLKSEL_MASK); + + /* Enable optional 48M functional clock for USB PHY */ + setbits_le32((*prcm)->cm_l3init_usbphy_clkctrl, + USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK); + + do_enable_clocks(clk_domains_essential, + clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, + 1); +} + +void enable_basic_uboot_clocks(void) +{ + u32 const clk_domains_essential[] = { + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_l3init_hsusbotg_clkctrl, + (*prcm)->cm_l3init_usbphy_clkctrl, + (*prcm)->cm_l3init_usbphy_clkctrl, + (*prcm)->cm_clksel_usb_60mhz, + (*prcm)->cm_l3init_hsusbtll_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_l4per_mcspi1_clkctrl, + (*prcm)->cm_l4per_i2c1_clkctrl, + (*prcm)->cm_l4per_i2c2_clkctrl, + (*prcm)->cm_l4per_i2c3_clkctrl, + (*prcm)->cm_l4per_i2c4_clkctrl, + (*prcm)->cm_l3init_hsusbhost_clkctrl, + 0 + }; + + do_enable_clocks(clk_domains_essential, + clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, + 1); +} + +void hw_data_init(void) +{ + u32 omap_rev = omap_revision(); + + (*prcm) = &omap4_prcm; + + switch (omap_rev) { + + case OMAP4430_ES1_0: + *dplls_data = &omap4430_dplls_es1; + *omap_vcores = &omap4430_volts_es1; + break; + + case OMAP4430_ES2_0: + *dplls_data = &omap4430_dplls_es20; + *omap_vcores = &omap4430_volts; + break; + + case OMAP4430_ES2_1: + case OMAP4430_ES2_2: + case OMAP4430_ES2_3: + *dplls_data = &omap4430_dplls; + *omap_vcores = &omap4430_volts; + break; + + case OMAP4460_ES1_0: + case OMAP4460_ES1_1: + *dplls_data = &omap4460_dplls; + *omap_vcores = &omap4460_volts; + break; + + case OMAP4470_ES1_0: + *dplls_data = &omap4470_dplls; + *omap_vcores = &omap4470_volts; + break; + + default: + printf("\n INVALID OMAP REVISION "); + } + + *ctrl = &omap4_ctrl; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/hwinit.c b/u-boot-imx/arch/arm/cpu/armv7/omap4/hwinit.c new file mode 100644 index 0000000..9792761 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/hwinit.c
@@ -0,0 +1,169 @@ +/* + * + * Common functions for OMAP4 based boards + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * Steve Sakoman <steve@sakoman.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/armv7.h> +#include <asm/arch/cpu.h> +#include <asm/arch/sys_proto.h> +#include <linux/sizes.h> +#include <asm/emif.h> +#include <asm/arch/gpio.h> +#include <asm/omap_common.h> + +DECLARE_GLOBAL_DATA_PTR; + +u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV; + +static const struct gpio_bank gpio_bank_44xx[6] = { + { (void *)OMAP44XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP44XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP44XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP44XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP44XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP44XX_GPIO6_BASE, METHOD_GPIO_24XX }, +}; + +const struct gpio_bank *const omap_gpio_bank = gpio_bank_44xx; + +#ifdef CONFIG_SPL_BUILD +/* + * Some tuning of IOs for optimal power and performance + */ +void do_io_settings(void) +{ + u32 lpddr2io; + + u32 omap4_rev = omap_revision(); + + if (omap4_rev == OMAP4430_ES1_0) + lpddr2io = CONTROL_LPDDR2IO_SLEW_125PS_DRV8_PULL_DOWN; + else if (omap4_rev == OMAP4430_ES2_0) + lpddr2io = CONTROL_LPDDR2IO_SLEW_325PS_DRV8_GATE_KEEPER; + else + lpddr2io = CONTROL_LPDDR2IO_SLEW_315PS_DRV12_PULL_DOWN; + + /* EMIF1 */ + writel(lpddr2io, (*ctrl)->control_lpddr2io1_0); + writel(lpddr2io, (*ctrl)->control_lpddr2io1_1); + /* No pull for GR10 as per hw team's recommendation */ + writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK, + (*ctrl)->control_lpddr2io1_2); + writel(CONTROL_LPDDR2IO_3_VAL, (*ctrl)->control_lpddr2io1_3); + + /* EMIF2 */ + writel(lpddr2io, (*ctrl)->control_lpddr2io2_0); + writel(lpddr2io, (*ctrl)->control_lpddr2io2_1); + /* No pull for GR10 as per hw team's recommendation */ + writel(lpddr2io & ~LPDDR2IO_GR10_WD_MASK, + (*ctrl)->control_lpddr2io2_2); + writel(CONTROL_LPDDR2IO_3_VAL, (*ctrl)->control_lpddr2io2_3); + + /* + * Some of these settings (TRIM values) come from eFuse and are + * in turn programmed in the eFuse at manufacturing time after + * calibration of the device. Do the software over-ride only if + * the device is not correctly trimmed + */ + if (!(readl((*ctrl)->control_std_fuse_opp_bgap) & 0xFFFF)) { + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + (*ctrl)->control_ldosram_iva_voltage_ctrl); + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + (*ctrl)->control_ldosram_mpu_voltage_ctrl); + + writel(LDOSRAM_VOLT_CTRL_OVERRIDE, + (*ctrl)->control_ldosram_core_voltage_ctrl); + } + + /* + * Over-ride the register + * i. unconditionally for all 4430 + * ii. only if un-trimmed for 4460 + */ + if (!readl((*ctrl)->control_efuse_1)) + writel(CONTROL_EFUSE_1_OVERRIDE, (*ctrl)->control_efuse_1); + + if ((omap4_rev < OMAP4460_ES1_0) || !readl((*ctrl)->control_efuse_2)) + writel(CONTROL_EFUSE_2_OVERRIDE, (*ctrl)->control_efuse_2); +} +#endif /* CONFIG_SPL_BUILD */ + +/* dummy fuction for omap4 */ +void config_data_eye_leveling_samples(u32 emif_base) +{ +} + +void init_omap_revision(void) +{ + /* + * For some of the ES2/ES1 boards ID_CODE is not reliable: + * Also, ES1 and ES2 have different ARM revisions + * So use ARM revision for identification + */ + unsigned int arm_rev = cortex_rev(); + + switch (arm_rev) { + case MIDR_CORTEX_A9_R0P1: + *omap_si_rev = OMAP4430_ES1_0; + break; + case MIDR_CORTEX_A9_R1P2: + switch (readl(CONTROL_ID_CODE)) { + case OMAP4_CONTROL_ID_CODE_ES2_0: + *omap_si_rev = OMAP4430_ES2_0; + break; + case OMAP4_CONTROL_ID_CODE_ES2_1: + *omap_si_rev = OMAP4430_ES2_1; + break; + case OMAP4_CONTROL_ID_CODE_ES2_2: + *omap_si_rev = OMAP4430_ES2_2; + break; + default: + *omap_si_rev = OMAP4430_ES2_0; + break; + } + break; + case MIDR_CORTEX_A9_R1P3: + *omap_si_rev = OMAP4430_ES2_3; + break; + case MIDR_CORTEX_A9_R2P10: + switch (readl(CONTROL_ID_CODE)) { + case OMAP4470_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = OMAP4470_ES1_0; + break; + case OMAP4460_CONTROL_ID_CODE_ES1_1: + *omap_si_rev = OMAP4460_ES1_1; + break; + case OMAP4460_CONTROL_ID_CODE_ES1_0: + default: + *omap_si_rev = OMAP4460_ES1_0; + break; + } + break; + default: + *omap_si_rev = OMAP4430_SILICON_ID_INVALID; + break; + } +} + +#ifndef CONFIG_SYS_L2CACHE_OFF +void v7_outer_cache_enable(void) +{ + omap_smc1(OMAP4_SERVICE_PL310_CONTROL_REG_SET, 1); +} + +void v7_outer_cache_disable(void) +{ + omap_smc1(OMAP4_SERVICE_PL310_CONTROL_REG_SET, 0); +} +#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/prcm-regs.c b/u-boot-imx/arch/arm/cpu/armv7/omap4/prcm-regs.c new file mode 100644 index 0000000..1ed146b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/prcm-regs.c
@@ -0,0 +1,302 @@ +/* + * + * HW regs data for OMAP4 + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/omap_common.h> + +struct prcm_regs const omap4_prcm = { + /* cm1.ckgen */ + .cm_clksel_core = 0x4a004100, + .cm_clksel_abe = 0x4a004108, + .cm_dll_ctrl = 0x4a004110, + .cm_clkmode_dpll_core = 0x4a004120, + .cm_idlest_dpll_core = 0x4a004124, + .cm_autoidle_dpll_core = 0x4a004128, + .cm_clksel_dpll_core = 0x4a00412c, + .cm_div_m2_dpll_core = 0x4a004130, + .cm_div_m3_dpll_core = 0x4a004134, + .cm_div_m4_dpll_core = 0x4a004138, + .cm_div_m5_dpll_core = 0x4a00413c, + .cm_div_m6_dpll_core = 0x4a004140, + .cm_div_m7_dpll_core = 0x4a004144, + .cm_ssc_deltamstep_dpll_core = 0x4a004148, + .cm_ssc_modfreqdiv_dpll_core = 0x4a00414c, + .cm_emu_override_dpll_core = 0x4a004150, + .cm_clkmode_dpll_mpu = 0x4a004160, + .cm_idlest_dpll_mpu = 0x4a004164, + .cm_autoidle_dpll_mpu = 0x4a004168, + .cm_clksel_dpll_mpu = 0x4a00416c, + .cm_div_m2_dpll_mpu = 0x4a004170, + .cm_ssc_deltamstep_dpll_mpu = 0x4a004188, + .cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c, + .cm_bypclk_dpll_mpu = 0x4a00419c, + .cm_clkmode_dpll_iva = 0x4a0041a0, + .cm_idlest_dpll_iva = 0x4a0041a4, + .cm_autoidle_dpll_iva = 0x4a0041a8, + .cm_clksel_dpll_iva = 0x4a0041ac, + .cm_div_m4_dpll_iva = 0x4a0041b8, + .cm_div_m5_dpll_iva = 0x4a0041bc, + .cm_ssc_deltamstep_dpll_iva = 0x4a0041c8, + .cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc, + .cm_bypclk_dpll_iva = 0x4a0041dc, + .cm_clkmode_dpll_abe = 0x4a0041e0, + .cm_idlest_dpll_abe = 0x4a0041e4, + .cm_autoidle_dpll_abe = 0x4a0041e8, + .cm_clksel_dpll_abe = 0x4a0041ec, + .cm_div_m2_dpll_abe = 0x4a0041f0, + .cm_div_m3_dpll_abe = 0x4a0041f4, + .cm_ssc_deltamstep_dpll_abe = 0x4a004208, + .cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c, + .cm_clkmode_dpll_ddrphy = 0x4a004220, + .cm_idlest_dpll_ddrphy = 0x4a004224, + .cm_autoidle_dpll_ddrphy = 0x4a004228, + .cm_clksel_dpll_ddrphy = 0x4a00422c, + .cm_div_m2_dpll_ddrphy = 0x4a004230, + .cm_div_m4_dpll_ddrphy = 0x4a004238, + .cm_div_m5_dpll_ddrphy = 0x4a00423c, + .cm_div_m6_dpll_ddrphy = 0x4a004240, + .cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248, + .cm_shadow_freq_config1 = 0x4a004260, + .cm_mpu_mpu_clkctrl = 0x4a004320, + + /* cm1.dsp */ + .cm_dsp_clkstctrl = 0x4a004400, + .cm_dsp_dsp_clkctrl = 0x4a004420, + + /* cm1.abe */ + .cm1_abe_clkstctrl = 0x4a004500, + .cm1_abe_l4abe_clkctrl = 0x4a004520, + .cm1_abe_aess_clkctrl = 0x4a004528, + .cm1_abe_pdm_clkctrl = 0x4a004530, + .cm1_abe_dmic_clkctrl = 0x4a004538, + .cm1_abe_mcasp_clkctrl = 0x4a004540, + .cm1_abe_mcbsp1_clkctrl = 0x4a004548, + .cm1_abe_mcbsp2_clkctrl = 0x4a004550, + .cm1_abe_mcbsp3_clkctrl = 0x4a004558, + .cm1_abe_slimbus_clkctrl = 0x4a004560, + .cm1_abe_timer5_clkctrl = 0x4a004568, + .cm1_abe_timer6_clkctrl = 0x4a004570, + .cm1_abe_timer7_clkctrl = 0x4a004578, + .cm1_abe_timer8_clkctrl = 0x4a004580, + .cm1_abe_wdt3_clkctrl = 0x4a004588, + + /* cm2.ckgen */ + .cm_clksel_mpu_m3_iss_root = 0x4a008100, + .cm_clksel_usb_60mhz = 0x4a008104, + .cm_scale_fclk = 0x4a008108, + .cm_core_dvfs_perf1 = 0x4a008110, + .cm_core_dvfs_perf2 = 0x4a008114, + .cm_core_dvfs_perf3 = 0x4a008118, + .cm_core_dvfs_perf4 = 0x4a00811c, + .cm_core_dvfs_current = 0x4a008124, + .cm_iva_dvfs_perf_tesla = 0x4a008128, + .cm_iva_dvfs_perf_ivahd = 0x4a00812c, + .cm_iva_dvfs_perf_abe = 0x4a008130, + .cm_iva_dvfs_current = 0x4a008138, + .cm_clkmode_dpll_per = 0x4a008140, + .cm_idlest_dpll_per = 0x4a008144, + .cm_autoidle_dpll_per = 0x4a008148, + .cm_clksel_dpll_per = 0x4a00814c, + .cm_div_m2_dpll_per = 0x4a008150, + .cm_div_m3_dpll_per = 0x4a008154, + .cm_div_m4_dpll_per = 0x4a008158, + .cm_div_m5_dpll_per = 0x4a00815c, + .cm_div_m6_dpll_per = 0x4a008160, + .cm_div_m7_dpll_per = 0x4a008164, + .cm_ssc_deltamstep_dpll_per = 0x4a008168, + .cm_ssc_modfreqdiv_dpll_per = 0x4a00816c, + .cm_emu_override_dpll_per = 0x4a008170, + .cm_clkmode_dpll_usb = 0x4a008180, + .cm_idlest_dpll_usb = 0x4a008184, + .cm_autoidle_dpll_usb = 0x4a008188, + .cm_clksel_dpll_usb = 0x4a00818c, + .cm_div_m2_dpll_usb = 0x4a008190, + .cm_ssc_deltamstep_dpll_usb = 0x4a0081a8, + .cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac, + .cm_clkdcoldo_dpll_usb = 0x4a0081b4, + .cm_clkmode_dpll_unipro = 0x4a0081c0, + .cm_idlest_dpll_unipro = 0x4a0081c4, + .cm_autoidle_dpll_unipro = 0x4a0081c8, + .cm_clksel_dpll_unipro = 0x4a0081cc, + .cm_div_m2_dpll_unipro = 0x4a0081d0, + .cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8, + .cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec, + + /* cm2.core */ + .cm_l3_1_clkstctrl = 0x4a008700, + .cm_l3_1_dynamicdep = 0x4a008708, + .cm_l3_1_l3_1_clkctrl = 0x4a008720, + .cm_l3_2_clkstctrl = 0x4a008800, + .cm_l3_2_dynamicdep = 0x4a008808, + .cm_l3_2_l3_2_clkctrl = 0x4a008820, + .cm_l3_gpmc_clkctrl = 0x4a008828, + .cm_l3_2_ocmc_ram_clkctrl = 0x4a008830, + .cm_mpu_m3_clkstctrl = 0x4a008900, + .cm_mpu_m3_staticdep = 0x4a008904, + .cm_mpu_m3_dynamicdep = 0x4a008908, + .cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920, + .cm_sdma_clkstctrl = 0x4a008a00, + .cm_sdma_staticdep = 0x4a008a04, + .cm_sdma_dynamicdep = 0x4a008a08, + .cm_sdma_sdma_clkctrl = 0x4a008a20, + .cm_memif_clkstctrl = 0x4a008b00, + .cm_memif_dmm_clkctrl = 0x4a008b20, + .cm_memif_emif_fw_clkctrl = 0x4a008b28, + .cm_memif_emif_1_clkctrl = 0x4a008b30, + .cm_memif_emif_2_clkctrl = 0x4a008b38, + .cm_memif_dll_clkctrl = 0x4a008b40, + .cm_memif_emif_h1_clkctrl = 0x4a008b50, + .cm_memif_emif_h2_clkctrl = 0x4a008b58, + .cm_memif_dll_h_clkctrl = 0x4a008b60, + .cm_c2c_clkstctrl = 0x4a008c00, + .cm_c2c_staticdep = 0x4a008c04, + .cm_c2c_dynamicdep = 0x4a008c08, + .cm_c2c_sad2d_clkctrl = 0x4a008c20, + .cm_c2c_modem_icr_clkctrl = 0x4a008c28, + .cm_c2c_sad2d_fw_clkctrl = 0x4a008c30, + .cm_l4cfg_clkstctrl = 0x4a008d00, + .cm_l4cfg_dynamicdep = 0x4a008d08, + .cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20, + .cm_l4cfg_hw_sem_clkctrl = 0x4a008d28, + .cm_l4cfg_mailbox_clkctrl = 0x4a008d30, + .cm_l4cfg_sar_rom_clkctrl = 0x4a008d38, + .cm_l3instr_clkstctrl = 0x4a008e00, + .cm_l3instr_l3_3_clkctrl = 0x4a008e20, + .cm_l3instr_l3_instr_clkctrl = 0x4a008e28, + .cm_l3instr_intrconn_wp1_clkct = 0x4a008e40, + .cm_ivahd_clkstctrl = 0x4a008f00, + + /* cm2.ivahd */ + .cm_ivahd_ivahd_clkctrl = 0x4a008f20, + .cm_ivahd_sl2_clkctrl = 0x4a008f28, + + /* cm2.cam */ + .cm_cam_clkstctrl = 0x4a009000, + .cm_cam_iss_clkctrl = 0x4a009020, + .cm_cam_fdif_clkctrl = 0x4a009028, + + /* cm2.dss */ + .cm_dss_clkstctrl = 0x4a009100, + .cm_dss_dss_clkctrl = 0x4a009120, + + /* cm2.sgx */ + .cm_sgx_clkstctrl = 0x4a009200, + .cm_sgx_sgx_clkctrl = 0x4a009220, + + /* cm2.l3init */ + .cm_l3init_clkstctrl = 0x4a009300, + .cm_l3init_hsmmc1_clkctrl = 0x4a009328, + .cm_l3init_hsmmc2_clkctrl = 0x4a009330, + .cm_l3init_hsi_clkctrl = 0x4a009338, + .cm_l3init_hsusbhost_clkctrl = 0x4a009358, + .cm_l3init_hsusbotg_clkctrl = 0x4a009360, + .cm_l3init_hsusbtll_clkctrl = 0x4a009368, + .cm_l3init_p1500_clkctrl = 0x4a009378, + .cm_l3init_fsusb_clkctrl = 0x4a0093d0, + .cm_l3init_usbphy_clkctrl = 0x4a0093e0, + + /* cm2.l4per */ + .cm_l4per_clkstctrl = 0x4a009400, + .cm_l4per_dynamicdep = 0x4a009408, + .cm_l4per_adc_clkctrl = 0x4a009420, + .cm_l4per_gptimer10_clkctrl = 0x4a009428, + .cm_l4per_gptimer11_clkctrl = 0x4a009430, + .cm_l4per_gptimer2_clkctrl = 0x4a009438, + .cm_l4per_gptimer3_clkctrl = 0x4a009440, + .cm_l4per_gptimer4_clkctrl = 0x4a009448, + .cm_l4per_gptimer9_clkctrl = 0x4a009450, + .cm_l4per_elm_clkctrl = 0x4a009458, + .cm_l4per_gpio2_clkctrl = 0x4a009460, + .cm_l4per_gpio3_clkctrl = 0x4a009468, + .cm_l4per_gpio4_clkctrl = 0x4a009470, + .cm_l4per_gpio5_clkctrl = 0x4a009478, + .cm_l4per_gpio6_clkctrl = 0x4a009480, + .cm_l4per_hdq1w_clkctrl = 0x4a009488, + .cm_l4per_hecc1_clkctrl = 0x4a009490, + .cm_l4per_hecc2_clkctrl = 0x4a009498, + .cm_l4per_i2c1_clkctrl = 0x4a0094a0, + .cm_l4per_i2c2_clkctrl = 0x4a0094a8, + .cm_l4per_i2c3_clkctrl = 0x4a0094b0, + .cm_l4per_i2c4_clkctrl = 0x4a0094b8, + .cm_l4per_l4per_clkctrl = 0x4a0094c0, + .cm_l4per_mcasp2_clkctrl = 0x4a0094d0, + .cm_l4per_mcasp3_clkctrl = 0x4a0094d8, + .cm_l4per_mcbsp4_clkctrl = 0x4a0094e0, + .cm_l4per_mgate_clkctrl = 0x4a0094e8, + .cm_l4per_mcspi1_clkctrl = 0x4a0094f0, + .cm_l4per_mcspi2_clkctrl = 0x4a0094f8, + .cm_l4per_mcspi3_clkctrl = 0x4a009500, + .cm_l4per_mcspi4_clkctrl = 0x4a009508, + .cm_l4per_mmcsd3_clkctrl = 0x4a009520, + .cm_l4per_mmcsd4_clkctrl = 0x4a009528, + .cm_l4per_msprohg_clkctrl = 0x4a009530, + .cm_l4per_slimbus2_clkctrl = 0x4a009538, + .cm_l4per_uart1_clkctrl = 0x4a009540, + .cm_l4per_uart2_clkctrl = 0x4a009548, + .cm_l4per_uart3_clkctrl = 0x4a009550, + .cm_l4per_uart4_clkctrl = 0x4a009558, + .cm_l4per_mmcsd5_clkctrl = 0x4a009560, + .cm_l4per_i2c5_clkctrl = 0x4a009568, + .cm_l4sec_clkstctrl = 0x4a009580, + .cm_l4sec_staticdep = 0x4a009584, + .cm_l4sec_dynamicdep = 0x4a009588, + .cm_l4sec_aes1_clkctrl = 0x4a0095a0, + .cm_l4sec_aes2_clkctrl = 0x4a0095a8, + .cm_l4sec_des3des_clkctrl = 0x4a0095b0, + .cm_l4sec_pkaeip29_clkctrl = 0x4a0095b8, + .cm_l4sec_rng_clkctrl = 0x4a0095c0, + .cm_l4sec_sha2md51_clkctrl = 0x4a0095c8, + .cm_l4sec_cryptodma_clkctrl = 0x4a0095d8, + + /* l4 wkup regs */ + .cm_abe_pll_ref_clksel = 0x4a30610c, + .cm_sys_clksel = 0x4a306110, + .cm_wkup_clkstctrl = 0x4a307800, + .cm_wkup_l4wkup_clkctrl = 0x4a307820, + .cm_wkup_wdtimer1_clkctrl = 0x4a307828, + .cm_wkup_wdtimer2_clkctrl = 0x4a307830, + .cm_wkup_gpio1_clkctrl = 0x4a307838, + .cm_wkup_gptimer1_clkctrl = 0x4a307840, + .cm_wkup_gptimer12_clkctrl = 0x4a307848, + .cm_wkup_synctimer_clkctrl = 0x4a307850, + .cm_wkup_usim_clkctrl = 0x4a307858, + .cm_wkup_sarram_clkctrl = 0x4a307860, + .cm_wkup_keyboard_clkctrl = 0x4a307878, + .cm_wkup_rtc_clkctrl = 0x4a307880, + .cm_wkup_bandgap_clkctrl = 0x4a307888, + .prm_vc_val_bypass = 0x4a307ba0, + .prm_vc_cfg_channel = 0x4a307ba4, + .prm_vc_cfg_i2c_mode = 0x4a307ba8, + .prm_vc_cfg_i2c_clk = 0x4a307bac, +}; + +struct omap_sys_ctrl_regs const omap4_ctrl = { + .control_id_code = 0x4A002204, + .control_std_fuse_opp_bgap = 0x4a002260, + .control_status = 0x4a0022c4, + .control_ldosram_iva_voltage_ctrl = 0x4A002320, + .control_ldosram_mpu_voltage_ctrl = 0x4A002324, + .control_ldosram_core_voltage_ctrl = 0x4A002328, + .control_usbotghs_ctrl = 0x4A00233C, + .control_padconf_core_base = 0x4A100000, + .control_pbiaslite = 0x4A100600, + .control_lpddr2io1_0 = 0x4A100638, + .control_lpddr2io1_1 = 0x4A10063C, + .control_lpddr2io1_2 = 0x4A100640, + .control_lpddr2io1_3 = 0x4A100644, + .control_lpddr2io2_0 = 0x4A100648, + .control_lpddr2io2_1 = 0x4A10064C, + .control_lpddr2io2_2 = 0x4A100650, + .control_lpddr2io2_3 = 0x4A100654, + .control_efuse_1 = 0x4A100700, + .control_efuse_2 = 0x4A100704, + .control_padconf_wkup_base = 0x4A31E000, +};
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/u-boot-imx/arch/arm/cpu/armv7/omap4/sdram_elpida.c new file mode 100644 index 0000000..4462c72 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap4/sdram_elpida.c
@@ -0,0 +1,324 @@ +/* + * Timing and Organization details of the Elpida parts used in OMAP4 + * SDPs and Panda + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> + +/* + * This file provides details of the LPDDR2 SDRAM parts used on OMAP4430 + * SDP and Panda. Since the parts used and geometry are identical for + * SDP and Panda for a given OMAP4 revision, this information is kept + * here instead of being in board directory. However the key functions + * exported are weakly linked so that they can be over-ridden in the board + * directory if there is a OMAP4 board in the future that uses a different + * memory device or geometry. + * + * For any new board with different memory devices over-ride one or more + * of the following functions as per the CONFIG flags you intend to enable: + * - emif_get_reg_dump() + * - emif_get_dmm_regs() + * - emif_get_device_details() + * - emif_get_device_timings() + */ + +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS + +const struct emif_regs emif_regs_elpida_200_mhz_2cs = { + .sdram_config_init = 0x80000eb9, + .sdram_config = 0x80001ab9, + .ref_ctrl = 0x0000030c, + .sdram_tim1 = 0x08648311, + .sdram_tim2 = 0x101b06ca, + .sdram_tim3 = 0x0048a19f, + .read_idle_ctrl = 0x000501ff, + .zq_config = 0x500b3214, + .temp_alert_config = 0xd8016893, + .emif_ddr_phy_ctlr_1_init = 0x049ffff5, + .emif_ddr_phy_ctlr_1 = 0x049ff808 +}; + +const struct emif_regs emif_regs_elpida_380_mhz_1cs = { + .sdram_config_init = 0x80000eb1, + .sdram_config = 0x80001ab1, + .ref_ctrl = 0x000005cd, + .sdram_tim1 = 0x10cb0622, + .sdram_tim2 = 0x20350d52, + .sdram_tim3 = 0x00b1431f, + .read_idle_ctrl = 0x000501ff, + .zq_config = 0x500b3214, + .temp_alert_config = 0x58016893, + .emif_ddr_phy_ctlr_1_init = 0x049ffff5, + .emif_ddr_phy_ctlr_1 = 0x049ff418 +}; + +const struct emif_regs emif_regs_elpida_400_mhz_1cs = { + .sdram_config_init = 0x80800eb2, + .sdram_config = 0x80801ab2, + .ref_ctrl = 0x00000618, + .sdram_tim1 = 0x10eb0662, + .sdram_tim2 = 0x20370dd2, + .sdram_tim3 = 0x00b1c33f, + .read_idle_ctrl = 0x000501ff, + .zq_config = 0x500b3215, + .temp_alert_config = 0x58016893, + .emif_ddr_phy_ctlr_1_init = 0x049ffff5, + .emif_ddr_phy_ctlr_1 = 0x049ff418 +}; + +const struct emif_regs emif_regs_elpida_400_mhz_2cs = { + .sdram_config_init = 0x80000eb9, + .sdram_config = 0x80001ab9, + .ref_ctrl = 0x00000618, + .sdram_tim1 = 0x10eb0662, + .sdram_tim2 = 0x20370dd2, + .sdram_tim3 = 0x00b1c33f, + .read_idle_ctrl = 0x000501ff, + .zq_config = 0xd00b3214, + .temp_alert_config = 0xd8016893, + .emif_ddr_phy_ctlr_1_init = 0x049ffff5, + .emif_ddr_phy_ctlr_1 = 0x049ff418 +}; + +const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { + .dmm_lisa_map_0 = 0xFF020100, + .dmm_lisa_map_1 = 0, + .dmm_lisa_map_2 = 0, + .dmm_lisa_map_3 = 0x80540300, + .is_ma_present = 0x0 +}; + +const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = { + .dmm_lisa_map_0 = 0xFF020100, + .dmm_lisa_map_1 = 0, + .dmm_lisa_map_2 = 0, + .dmm_lisa_map_3 = 0x80640300, + .is_ma_present = 0x0 +}; + +const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2 = { + .dmm_lisa_map_0 = 0xFF020100, + .dmm_lisa_map_1 = 0, + .dmm_lisa_map_2 = 0, + .dmm_lisa_map_3 = 0x80640300, + .is_ma_present = 0x1 +}; + +static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) +{ + u32 omap4_rev = omap_revision(); + + /* Same devices and geometry on both EMIFs */ + if (omap4_rev == OMAP4430_ES1_0) + *regs = &emif_regs_elpida_380_mhz_1cs; + else if (omap4_rev == OMAP4430_ES2_0) + *regs = &emif_regs_elpida_200_mhz_2cs; + else if (omap4_rev < OMAP4470_ES1_0) + *regs = &emif_regs_elpida_400_mhz_2cs; + else + *regs = &emif_regs_elpida_400_mhz_1cs; +} +void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) + __attribute__((weak, alias("emif_get_reg_dump_sdp"))); + +static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs + **dmm_lisa_regs) +{ + u32 omap_rev = omap_revision(); + + if (omap_rev == OMAP4430_ES1_0) + *dmm_lisa_regs = &lisa_map_2G_x_1_x_2; + else if (omap_rev < OMAP4460_ES1_0) + *dmm_lisa_regs = &lisa_map_2G_x_2_x_2; + else + *dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2; +} + +void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) + __attribute__((weak, alias("emif_get_dmm_regs_sdp"))); + +#else + +static const struct lpddr2_device_details elpida_2G_S4_details = { + .type = LPDDR2_TYPE_S4, + .density = LPDDR2_DENSITY_2Gb, + .io_width = LPDDR2_IO_WIDTH_32, + .manufacturer = LPDDR2_MANUFACTURER_ELPIDA +}; + +static const struct lpddr2_device_details elpida_4G_S4_details = { + .type = LPDDR2_TYPE_S4, + .density = LPDDR2_DENSITY_4Gb, + .io_width = LPDDR2_IO_WIDTH_32, + .manufacturer = LPDDR2_MANUFACTURER_ELPIDA +}; + +struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs, + struct lpddr2_device_details *lpddr2_dev_details) +{ + u32 omap_rev = omap_revision(); + + /* EMIF1 & EMIF2 have identical configuration */ + if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0)) + && (cs == CS1)) { + /* Nothing connected on CS1 for 4430/4470 ES1.0 */ + return NULL; + } else if (omap_rev < OMAP4470_ES1_0) { + /* In all other 4430/4460 cases Elpida 2G device */ + *lpddr2_dev_details = elpida_2G_S4_details; + } else { + /* 4470: 4G device */ + *lpddr2_dev_details = elpida_4G_S4_details; + } + return lpddr2_dev_details; +} + +struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs, + struct lpddr2_device_details *lpddr2_dev_details) + __attribute__((weak, alias("emif_get_device_details_sdp"))); + +#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ + +#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +static const struct lpddr2_ac_timings timings_elpida_400_mhz = { + .max_freq = 400000000, + .RL = 6, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +static const struct lpddr2_ac_timings timings_elpida_333_mhz = { + .max_freq = 333000000, + .RL = 5, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +static const struct lpddr2_ac_timings timings_elpida_200_mhz = { + .max_freq = 200000000, + .RL = 3, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 20, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +static const struct lpddr2_min_tck min_tck_elpida = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_elpida_200_mhz, + &timings_elpida_333_mhz, + &timings_elpida_400_mhz +}; + +static const struct lpddr2_device_timings elpida_2G_S4_timings = { + .ac_timings = elpida_ac_timings, + .min_tck = &min_tck_elpida, +}; + +void emif_get_device_timings_sdp(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + u32 omap_rev = omap_revision(); + + /* Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &elpida_2G_S4_timings; + + if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0)) + *cs1_device_timings = NULL; + else + *cs1_device_timings = &elpida_2G_S4_timings; +} + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) + __attribute__((weak, alias("emif_get_device_timings_sdp"))); + +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */ + +const struct lpddr2_mr_regs mr_regs = { + .mr1 = MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3, + .mr2 = 0x4, + .mr3 = -1, + .mr10 = MR10_ZQ_ZQINIT, + .mr16 = MR16_REF_FULL_ARRAY +}; + +void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs) +{ + *regs = &mr_regs; +} + +__weak const struct read_write_regs *get_bug_regs(u32 *iterations) +{ + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/omap5/Kconfig new file mode 100644 index 0000000..aca862d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/Kconfig
@@ -0,0 +1,28 @@ +if OMAP54XX + +choice + prompt "OMAP5 board select" + +config TARGET_CM_T54 + bool "CompuLab CM-T54" + +config TARGET_OMAP5_UEVM + bool "TI OMAP5 uEVM board" + +config TARGET_DRA7XX_EVM + bool "TI DRA7XX" + +config TARGET_BEAGLE_X15 + bool "BeagleBoard X15" + +endchoice + +config SYS_SOC + default "omap5" + +source "board/compulab/cm_t54/Kconfig" +source "board/ti/omap5_uevm/Kconfig" +source "board/ti/dra7xx/Kconfig" +source "board/ti/beagle_x15/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/Makefile b/u-boot-imx/arch/arm/cpu/armv7/omap5/Makefile new file mode 100644 index 0000000..64c6879 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/Makefile
@@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2010 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += hwinit.o +obj-y += emif.o +obj-y += sdram.o +obj-y += prcm-regs.o +obj-y += hw_data.o +obj-y += abb.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/abb.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/abb.c new file mode 100644 index 0000000..3bf8897 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/abb.c
@@ -0,0 +1,57 @@ +/* + * Adaptive Body Bias programming sequence for OMAP5 family + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/omap_common.h> +#include <asm/io.h> + +/* + * Setup LDOVBB for OMAP5. + * On OMAP5+ some ABB settings are fused. They are handled + * in the following way: + * + * 1. corresponding EFUSE register contains ABB enable bit + * and VSET value + * 2. If ABB enable bit is set to 1, than ABB should be + * enabled, otherwise ABB should be disabled + * 3. If ABB is enabled, than VSET value should be copied + * to corresponding MUX control register + */ +s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb) +{ + u32 vset; + u32 fuse_enable_mask = OMAP5_ABB_FUSE_ENABLE_MASK; + u32 fuse_vset_mask = OMAP5_ABB_FUSE_VSET_MASK; + + if (!is_omap54xx()) { + /* DRA7 */ + fuse_enable_mask = DRA7_ABB_FUSE_ENABLE_MASK; + fuse_vset_mask = DRA7_ABB_FUSE_VSET_MASK; + } + /* + * ABB parameters must be properly fused + * otherwise ABB should be disabled + */ + vset = readl(fuse); + if (!(vset & fuse_enable_mask)) + return -1; + + /* prepare VSET value for LDOVBB mux register */ + vset &= fuse_vset_mask; + vset >>= ffs(fuse_vset_mask) - 1; + vset <<= ffs(OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK) - 1; + vset |= OMAP5_ABB_LDOVBBMPU_MUX_CTRL_MASK; + + /* setup LDOVBB using fused value */ + clrsetbits_le32(ldovbb, OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK, vset); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/config.mk b/u-boot-imx/arch/arm/cpu/armv7/omap5/config.mk new file mode 100644 index 0000000..ef2725a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/config.mk
@@ -0,0 +1,13 @@ +# +# Copyright 2011 Linaro Limited +# +# Aneesh V <annesh@ti.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +ALL-y += MLO +else +ALL-y += u-boot.img +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/emif.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/emif.c new file mode 100644 index 0000000..b1203a3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/emif.c
@@ -0,0 +1,88 @@ +/* + * EMIF programming + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> for OMAP4 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> +#include <asm/utils.h> + +#ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +#define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) +static u32 *const T_num = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_NUM; +static u32 *const T_den = (u32 *)OMAP_SRAM_SCRATCH_EMIF_T_DEN; +#endif + +#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +/* Base AC Timing values specified by JESD209-2 for 532MHz operation */ +static const struct lpddr2_ac_timings timings_jedec_532_mhz = { + .max_freq = 532000000, + .RL = 8, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +/* + * Min tCK values specified by JESD209-2 + * Min tCK specifies the minimum duration of some AC timing parameters in terms + * of the number of cycles. If the calculated number of cycles based on the + * absolute time value is less than the min tCK value, min tCK value should + * be used instead. This typically happens at low frequencies. + */ +static const struct lpddr2_min_tck min_tck_jedec = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings const* + jedec_ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_532_mhz +}; + +static const struct lpddr2_device_timings jedec_default_timings = { + .ac_timings = jedec_ac_timings, + .min_tck = &min_tck_jedec +}; + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Assume Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &jedec_default_timings; + *cs1_device_timings = NULL; +} +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/hw_data.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/hw_data.c new file mode 100644 index 0000000..b9734fe --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -0,0 +1,669 @@ +/* + * + * HW data initialization for OMAP5 + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <palmas.h> +#include <asm/arch/omap.h> +#include <asm/arch/sys_proto.h> +#include <asm/omap_common.h> +#include <asm/arch/clock.h> +#include <asm/omap_gpio.h> +#include <asm/io.h> +#include <asm/emif.h> + +struct prcm_regs const **prcm = + (struct prcm_regs const **) OMAP_SRAM_SCRATCH_PRCM_PTR; +struct dplls const **dplls_data = + (struct dplls const **) OMAP_SRAM_SCRATCH_DPLLS_PTR; +struct vcores_data const **omap_vcores = + (struct vcores_data const **) OMAP_SRAM_SCRATCH_VCORES_PTR; +struct omap_sys_ctrl_regs const **ctrl = + (struct omap_sys_ctrl_regs const **)OMAP_SRAM_SCRATCH_SYS_CTRL; + +/* OPP HIGH FREQUENCY for ES2.0 */ +static const struct dpll_params mpu_dpll_params_1_5ghz[NUM_SYS_CLKS] = { + {125, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {625, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {625, 7, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {750, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {625, 15, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OPP NOM FREQUENCY for ES1.0 */ +static const struct dpll_params mpu_dpll_params_800mhz[NUM_SYS_CLKS] = { + {200, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {1000, 20, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {375, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {400, 12, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {375, 17, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OPP LOW FREQUENCY for ES1.0 */ +static const struct dpll_params mpu_dpll_params_400mhz[NUM_SYS_CLKS] = { + {200, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {1000, 20, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {375, 8, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {400, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {375, 17, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OPP LOW FREQUENCY for ES2.0 */ +static const struct dpll_params mpu_dpll_params_499mhz[NUM_SYS_CLKS] = { + {499, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {297, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {493, 18, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {499, 25, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {493, 37, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* OPP NOM FREQUENCY for OMAP5 ES2.0, and DRA7 ES1.0 */ +static const struct dpll_params mpu_dpll_params_1ghz[NUM_SYS_CLKS] = { + {250, 2, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {500, 9, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {119, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {625, 11, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {500, 12, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {625, 23, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params + core_dpll_params_2128mhz_ddr532[NUM_SYS_CLKS] = { + {266, 2, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {443, 6, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1}, /* 16.8 MHz */ + {277, 4, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1}, /* 19.2 MHz */ + {368, 8, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {277, 9, 2, 5, 8, 4, 62, 5, -1, 5, 7, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params + core_dpll_params_2128mhz_ddr532_es2[NUM_SYS_CLKS] = { + {266, 2, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {443, 6, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6}, /* 16.8 MHz */ + {277, 4, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6}, /* 19.2 MHz */ + {368, 8, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {277, 9, 2, 5, 8, 4, 62, 63, 6, 5, 7, 6} /* 38.4 MHz */ +}; + +static const struct dpll_params + core_dpll_params_2128mhz_dra7xx[NUM_SYS_CLKS] = { + {266, 2, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 12 MHz */ + {266, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 20 MHz */ + {443, 6, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 16.8 MHz */ + {277, 4, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 19.2 MHz */ + {368, 8, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {277, 9, 2, 1, -1, 4, 62, 5, -1, 5, 4, 6}, /* 38.4 MHz */ +}; + +static const struct dpll_params + core_dpll_params_2128mhz_ddr266[NUM_SYS_CLKS] = { + {266, 2, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {443, 6, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1}, /* 16.8 MHz */ + {277, 4, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1}, /* 19.2 MHz */ + {368, 8, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {277, 9, 4, 8, 8, 8, 62, 10, -1, 10, 14, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params + core_dpll_params_2128mhz_ddr266_es2[NUM_SYS_CLKS] = { + {266, 2, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {443, 6, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12}, /* 16.8 MHz */ + {277, 4, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12}, /* 19.2 MHz */ + {368, 8, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {277, 9, 4, 8, 8, 8, 62, 5, 12, 10, 14, 12} /* 38.4 MHz */ +}; + +static const struct dpll_params per_dpll_params_768mhz[NUM_SYS_CLKS] = { + {32, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {160, 6, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1}, /* 16.8 MHz */ + {20, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1}, /* 19.2 MHz */ + {192, 12, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {10, 0, 4, 3, 6, 4, -1, 2, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params per_dpll_params_768mhz_es2[NUM_SYS_CLKS] = { + {32, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {160, 6, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1}, /* 16.8 MHz */ + {20, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1}, /* 19.2 MHz */ + {192, 12, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {10, 0, 4, 3, 3, 4, -1, 2, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params per_dpll_params_768mhz_dra7xx[NUM_SYS_CLKS] = { + {32, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 12 MHz */ + {96, 4, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 20 MHz */ + {160, 6, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 16.8 MHz */ + {20, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 19.2 MHz */ + {192, 12, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {10, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params iva_dpll_params_2330mhz[NUM_SYS_CLKS] = { + {1165, 11, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {208, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {182, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {224, 4, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {91, 2, -1, -1, 5, 6, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +static const struct dpll_params iva_dpll_params_2330mhz_dra7xx[NUM_SYS_CLKS] = { + {1165, 11, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {233, 3, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {208, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {182, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {224, 4, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {91, 2, 3, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +/* ABE M & N values with sys_clk as source */ +static const struct dpll_params + abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = { + {49, 5, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 13 MHz */ + {35, 5, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {46, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {34, 8, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {64, 24, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1} /* 38.4 MHz */ +}; + +/* ABE M & N values with 32K clock as source */ +static const struct dpll_params abe_dpll_params_32k_196608khz = { + 750, 0, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* ABE M & N values with sysclk2(22.5792 MHz) as input */ +static const struct dpll_params + abe_dpll_params_sysclk2_361267khz[NUM_SYS_CLKS] = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {16, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = { + {400, 4, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {480, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {400, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {400, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {480, 12, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {400, 15, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params ddr_dpll_params_2664mhz[NUM_SYS_CLKS] = { + {111, 0, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {333, 4, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {555, 6, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {555, 7, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {666, 12, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {555, 15, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params ddr_dpll_params_2128mhz[NUM_SYS_CLKS] = { + {266, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 12 MHz */ + {266, 4, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 20 MHz */ + {190, 2, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {665, 11, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {532, 12, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {665, 23, 2, 1, 8, -1, -1, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +static const struct dpll_params gmac_dpll_params_2000mhz[NUM_SYS_CLKS] = { + {250, 2, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 12 MHz */ + {250, 4, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 20 MHz */ + {119, 1, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 16.8 MHz */ + {625, 11, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 19.2 MHz */ + {500, 12, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 26 MHz */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 27 MHz */ + {625, 23, 4, 10, 40, 8, 10, -1, -1, -1, -1, -1}, /* 38.4 MHz */ +}; + +struct dplls omap5_dplls_es1 = { + .mpu = mpu_dpll_params_800mhz, + .core = core_dpll_params_2128mhz_ddr532, + .per = per_dpll_params_768mhz, + .iva = iva_dpll_params_2330mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls omap5_dplls_es2 = { + .mpu = mpu_dpll_params_1ghz, + .core = core_dpll_params_2128mhz_ddr532_es2, + .per = per_dpll_params_768mhz_es2, + .iva = iva_dpll_params_2330mhz, +#ifdef CONFIG_SYS_OMAP_ABE_SYSCK + .abe = abe_dpll_params_sysclk_196608khz, +#else + .abe = &abe_dpll_params_32k_196608khz, +#endif + .usb = usb_dpll_params_1920mhz, + .ddr = NULL +}; + +struct dplls dra7xx_dplls = { + .mpu = mpu_dpll_params_1ghz, + .core = core_dpll_params_2128mhz_dra7xx, + .per = per_dpll_params_768mhz_dra7xx, + .abe = abe_dpll_params_sysclk2_361267khz, + .iva = iva_dpll_params_2330mhz_dra7xx, + .usb = usb_dpll_params_1920mhz, + .ddr = ddr_dpll_params_2128mhz, + .gmac = gmac_dpll_params_2000mhz, +}; + +struct dplls dra72x_dplls = { + .mpu = mpu_dpll_params_1ghz, + .core = core_dpll_params_2128mhz_dra7xx, + .per = per_dpll_params_768mhz_dra7xx, + .abe = abe_dpll_params_sysclk2_361267khz, + .iva = iva_dpll_params_2330mhz_dra7xx, + .usb = usb_dpll_params_1920mhz, + .ddr = ddr_dpll_params_2664mhz, + .gmac = gmac_dpll_params_2000mhz, +}; + +struct pmic_data palmas = { + .base_offset = PALMAS_SMPS_BASE_VOLT_UV, + .step = 10000, /* 10 mV represented in uV */ + /* + * Offset codes 1-6 all give the base voltage in Palmas + * Offset code 0 switches OFF the SMPS + */ + .start_code = 6, + .i2c_slave_addr = SMPS_I2C_SLAVE_ADDR, + .pmic_bus_init = sri2c_init, + .pmic_write = omap_vc_bypass_send_value, +}; + +/* The TPS659038 and TPS65917 are software-compatible, use common struct */ +struct pmic_data tps659038 = { + .base_offset = PALMAS_SMPS_BASE_VOLT_UV, + .step = 10000, /* 10 mV represented in uV */ + /* + * Offset codes 1-6 all give the base voltage in Palmas + * Offset code 0 switches OFF the SMPS + */ + .start_code = 6, + .i2c_slave_addr = TPS659038_I2C_SLAVE_ADDR, + .pmic_bus_init = gpi2c_init, + .pmic_write = palmas_i2c_write_u8, +}; + +struct vcores_data omap5430_volts = { + .mpu.value = VDD_MPU, + .mpu.addr = SMPS_REG_ADDR_12_MPU, + .mpu.pmic = &palmas, + + .core.value = VDD_CORE, + .core.addr = SMPS_REG_ADDR_8_CORE, + .core.pmic = &palmas, + + .mm.value = VDD_MM, + .mm.addr = SMPS_REG_ADDR_45_IVA, + .mm.pmic = &palmas, +}; + +struct vcores_data omap5430_volts_es2 = { + .mpu.value = VDD_MPU_ES2, + .mpu.addr = SMPS_REG_ADDR_12_MPU, + .mpu.pmic = &palmas, + + .core.value = VDD_CORE_ES2, + .core.addr = SMPS_REG_ADDR_8_CORE, + .core.pmic = &palmas, + + .mm.value = VDD_MM_ES2, + .mm.addr = SMPS_REG_ADDR_45_IVA, + .mm.pmic = &palmas, +}; + +struct vcores_data dra752_volts = { + .mpu.value = VDD_MPU_DRA752, + .mpu.efuse.reg = STD_FUSE_OPP_VMIN_MPU_NOM, + .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .mpu.addr = TPS659038_REG_ADDR_SMPS12, + .mpu.pmic = &tps659038, + + .eve.value = VDD_EVE_DRA752, + .eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM, + .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .eve.addr = TPS659038_REG_ADDR_SMPS45, + .eve.pmic = &tps659038, + + .gpu.value = VDD_GPU_DRA752, + .gpu.efuse.reg = STD_FUSE_OPP_VMIN_GPU_NOM, + .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .gpu.addr = TPS659038_REG_ADDR_SMPS6, + .gpu.pmic = &tps659038, + + .core.value = VDD_CORE_DRA752, + .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM, + .core.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .core.addr = TPS659038_REG_ADDR_SMPS7, + .core.pmic = &tps659038, + + .iva.value = VDD_IVA_DRA752, + .iva.efuse.reg = STD_FUSE_OPP_VMIN_IVA_NOM, + .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .iva.addr = TPS659038_REG_ADDR_SMPS8, + .iva.pmic = &tps659038, +}; + +struct vcores_data dra722_volts = { + .mpu.value = VDD_MPU_DRA72x, + .mpu.efuse.reg = STD_FUSE_OPP_VMIN_MPU_NOM, + .mpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .mpu.addr = TPS65917_REG_ADDR_SMPS1, + .mpu.pmic = &tps659038, + + .core.value = VDD_CORE_DRA72x, + .core.efuse.reg = STD_FUSE_OPP_VMIN_CORE_NOM, + .core.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .core.addr = TPS65917_REG_ADDR_SMPS2, + .core.pmic = &tps659038, + + /* + * The DSPEVE, GPU and IVA rails are usually grouped on DRA72x + * designs and powered by TPS65917 SMPS3, as on the J6Eco EVM. + */ + .gpu.value = VDD_GPU_DRA72x, + .gpu.efuse.reg = STD_FUSE_OPP_VMIN_GPU_NOM, + .gpu.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .gpu.addr = TPS65917_REG_ADDR_SMPS3, + .gpu.pmic = &tps659038, + + .eve.value = VDD_EVE_DRA72x, + .eve.efuse.reg = STD_FUSE_OPP_VMIN_DSPEVE_NOM, + .eve.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .eve.addr = TPS65917_REG_ADDR_SMPS3, + .eve.pmic = &tps659038, + + .iva.value = VDD_IVA_DRA72x, + .iva.efuse.reg = STD_FUSE_OPP_VMIN_IVA_NOM, + .iva.efuse.reg_bits = DRA752_EFUSE_REGBITS, + .iva.addr = TPS65917_REG_ADDR_SMPS3, + .iva.pmic = &tps659038, +}; + +/* + * Enable essential clock domains, modules and + * do some additional special settings needed + */ +void enable_basic_clocks(void) +{ + u32 const clk_domains_essential[] = { + (*prcm)->cm_l4per_clkstctrl, + (*prcm)->cm_l3init_clkstctrl, + (*prcm)->cm_memif_clkstctrl, + (*prcm)->cm_l4cfg_clkstctrl, +#ifdef CONFIG_DRIVER_TI_CPSW + (*prcm)->cm_gmac_clkstctrl, +#endif + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_l3_gpmc_clkctrl, + (*prcm)->cm_memif_emif_1_clkctrl, + (*prcm)->cm_memif_emif_2_clkctrl, + (*prcm)->cm_l4cfg_l4_cfg_clkctrl, + (*prcm)->cm_wkup_gpio1_clkctrl, + (*prcm)->cm_l4per_gpio2_clkctrl, + (*prcm)->cm_l4per_gpio3_clkctrl, + (*prcm)->cm_l4per_gpio4_clkctrl, + (*prcm)->cm_l4per_gpio5_clkctrl, + (*prcm)->cm_l4per_gpio6_clkctrl, + (*prcm)->cm_l4per_gpio7_clkctrl, + (*prcm)->cm_l4per_gpio8_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_wkup_gptimer1_clkctrl, + (*prcm)->cm_l3init_hsmmc1_clkctrl, + (*prcm)->cm_l3init_hsmmc2_clkctrl, + (*prcm)->cm_l4per_gptimer2_clkctrl, + (*prcm)->cm_wkup_wdtimer2_clkctrl, + (*prcm)->cm_l4per_uart3_clkctrl, + (*prcm)->cm_l4per_i2c1_clkctrl, +#ifdef CONFIG_DRIVER_TI_CPSW + (*prcm)->cm_gmac_gmac_clkctrl, +#endif + +#ifdef CONFIG_TI_QSPI + (*prcm)->cm_l4per_qspi_clkctrl, +#endif + 0 + }; + + /* Enable optional additional functional clock for GPIO4 */ + setbits_le32((*prcm)->cm_l4per_gpio4_clkctrl, + GPIO4_CLKCTRL_OPTFCLKEN_MASK); + + /* Enable 96 MHz clock for MMC1 & MMC2 */ + setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl, + HSMMC_CLKCTRL_CLKSEL_MASK); + setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl, + HSMMC_CLKCTRL_CLKSEL_MASK); + + /* Set the correct clock dividers for mmc */ + setbits_le32((*prcm)->cm_l3init_hsmmc1_clkctrl, + HSMMC_CLKCTRL_CLKSEL_DIV_MASK); + setbits_le32((*prcm)->cm_l3init_hsmmc2_clkctrl, + HSMMC_CLKCTRL_CLKSEL_DIV_MASK); + + /* Select 32KHz clock as the source of GPTIMER1 */ + setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl, + GPTIMER1_CLKCTRL_CLKSEL_MASK); + + do_enable_clocks(clk_domains_essential, + clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, + 1); + +#ifdef CONFIG_TI_QSPI + setbits_le32((*prcm)->cm_l4per_qspi_clkctrl, (1<<24)); +#endif + + /* Enable SCRM OPT clocks for PER and CORE dpll */ + setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl, + OPTFCLKEN_SCRM_PER_MASK); + setbits_le32((*prcm)->cm_wkupaon_scrm_clkctrl, + OPTFCLKEN_SCRM_CORE_MASK); +} + +void enable_basic_uboot_clocks(void) +{ + u32 const clk_domains_essential[] = { + 0 + }; + + u32 const clk_modules_hw_auto_essential[] = { + (*prcm)->cm_l3init_hsusbtll_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_essential[] = { + (*prcm)->cm_l4per_mcspi1_clkctrl, + (*prcm)->cm_l4per_i2c2_clkctrl, + (*prcm)->cm_l4per_i2c3_clkctrl, + (*prcm)->cm_l4per_i2c4_clkctrl, + (*prcm)->cm_l4per_i2c5_clkctrl, + (*prcm)->cm_l3init_hsusbhost_clkctrl, + (*prcm)->cm_l3init_fsusb_clkctrl, + 0 + }; + do_enable_clocks(clk_domains_essential, + clk_modules_hw_auto_essential, + clk_modules_explicit_en_essential, + 1); +} + +const struct ctrl_ioregs ioregs_omap5430 = { + .ctrl_ddrch = DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN, + .ctrl_lpddr2ch = DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN, + .ctrl_ddrio_0 = DDR_IO_0_DDR2_DQ_INT_EN_ALL_DDR3_CA_DIS_ALL, + .ctrl_ddrio_1 = DDR_IO_1_DQ_OUT_EN_ALL_DQ_INT_EN_ALL, + .ctrl_ddrio_2 = DDR_IO_2_CA_OUT_EN_ALL_CA_INT_EN_ALL, +}; + +const struct ctrl_ioregs ioregs_omap5432_es1 = { + .ctrl_ddrch = DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL, + .ctrl_lpddr2ch = 0x0, + .ctrl_ddr3ch = DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL, + .ctrl_ddrio_0 = DDR_IO_0_VREF_CELLS_DDR3_VALUE, + .ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE, + .ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE, + .ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES, + .ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES, +}; + +const struct ctrl_ioregs ioregs_omap5432_es2 = { + .ctrl_ddrch = DDR_IO_I_40OHM_SR_FAST_WD_DQ_NO_PULL_DQS_NO_PULL_ES2, + .ctrl_lpddr2ch = 0x0, + .ctrl_ddr3ch = DDR_IO_I_40OHM_SR_SLOWEST_WD_DQ_NO_PULL_DQS_NO_PULL_ES2, + .ctrl_ddrio_0 = DDR_IO_0_VREF_CELLS_DDR3_VALUE_ES2, + .ctrl_ddrio_1 = DDR_IO_1_VREF_CELLS_DDR3_VALUE_ES2, + .ctrl_ddrio_2 = DDR_IO_2_VREF_CELLS_DDR3_VALUE_ES2, + .ctrl_emif_sdram_config_ext = SDRAM_CONFIG_EXT_RD_LVL_11_SAMPLES, + .ctrl_emif_sdram_config_ext_final = SDRAM_CONFIG_EXT_RD_LVL_4_SAMPLES, +}; + +const struct ctrl_ioregs ioregs_dra7xx_es1 = { + .ctrl_ddrch = 0x40404040, + .ctrl_lpddr2ch = 0x40404040, + .ctrl_ddr3ch = 0x80808080, + .ctrl_ddrio_0 = 0xA2084210, + .ctrl_ddrio_1 = 0x84210840, + .ctrl_ddrio_2 = 0x84210000, + .ctrl_emif_sdram_config_ext = 0x0001C1A7, + .ctrl_emif_sdram_config_ext_final = 0x0001C1A7, + .ctrl_ddr_ctrl_ext_0 = 0xA2000000, +}; + +const struct ctrl_ioregs ioregs_dra72x_es1 = { + .ctrl_ddrch = 0x40404040, + .ctrl_lpddr2ch = 0x40404040, + .ctrl_ddr3ch = 0x60606080, + .ctrl_ddrio_0 = 0xA2084210, + .ctrl_ddrio_1 = 0x84210840, + .ctrl_ddrio_2 = 0x84210000, + .ctrl_emif_sdram_config_ext = 0x0001C1A7, + .ctrl_emif_sdram_config_ext_final = 0x0001C1A7, + .ctrl_ddr_ctrl_ext_0 = 0xA2000000, +}; + +void __weak hw_data_init(void) +{ + u32 omap_rev = omap_revision(); + + switch (omap_rev) { + + case OMAP5430_ES1_0: + case OMAP5432_ES1_0: + *prcm = &omap5_es1_prcm; + *dplls_data = &omap5_dplls_es1; + *omap_vcores = &omap5430_volts; + *ctrl = &omap5_ctrl; + break; + + case OMAP5430_ES2_0: + case OMAP5432_ES2_0: + *prcm = &omap5_es2_prcm; + *dplls_data = &omap5_dplls_es2; + *omap_vcores = &omap5430_volts_es2; + *ctrl = &omap5_ctrl; + break; + + case DRA752_ES1_0: + case DRA752_ES1_1: + *prcm = &dra7xx_prcm; + *dplls_data = &dra7xx_dplls; + *omap_vcores = &dra752_volts; + *ctrl = &dra7xx_ctrl; + break; + + case DRA722_ES1_0: + *prcm = &dra7xx_prcm; + *dplls_data = &dra72x_dplls; + *omap_vcores = &dra722_volts; + *ctrl = &dra7xx_ctrl; + break; + + default: + printf("\n INVALID OMAP REVISION "); + } +} + +void get_ioregs(const struct ctrl_ioregs **regs) +{ + u32 omap_rev = omap_revision(); + + switch (omap_rev) { + case OMAP5430_ES1_0: + case OMAP5430_ES2_0: + *regs = &ioregs_omap5430; + break; + case OMAP5432_ES1_0: + *regs = &ioregs_omap5432_es1; + break; + case OMAP5432_ES2_0: + *regs = &ioregs_omap5432_es2; + break; + case DRA752_ES1_0: + case DRA752_ES1_1: + *regs = &ioregs_dra7xx_es1; + break; + case DRA722_ES1_0: + *regs = &ioregs_dra72x_es1; + break; + + default: + printf("\n INVALID OMAP REVISION "); + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/hwinit.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/hwinit.c new file mode 100644 index 0000000..8d6b59e --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -0,0 +1,406 @@ +/* + * + * Functions for omap5 based boards. + * + * (C) Copyright 2011 + * Texas Instruments, <www.ti.com> + * + * Author : + * Aneesh V <aneesh@ti.com> + * Steve Sakoman <steve@sakoman.com> + * Sricharan <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/armv7.h> +#include <asm/arch/cpu.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/clock.h> +#include <linux/sizes.h> +#include <asm/utils.h> +#include <asm/arch/gpio.h> +#include <asm/emif.h> +#include <asm/omap_common.h> + +DECLARE_GLOBAL_DATA_PTR; + +u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV; + +static struct gpio_bank gpio_bank_54xx[8] = { + { (void *)OMAP54XX_GPIO1_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO2_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO3_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO4_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO5_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO6_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO7_BASE, METHOD_GPIO_24XX }, + { (void *)OMAP54XX_GPIO8_BASE, METHOD_GPIO_24XX }, +}; + +const struct gpio_bank *const omap_gpio_bank = gpio_bank_54xx; + +#ifdef CONFIG_SPL_BUILD +/* LPDDR2 specific IO settings */ +static void io_settings_lpddr2(void) +{ + const struct ctrl_ioregs *ioregs; + + get_ioregs(&ioregs); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_1); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_1); + writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_0); + writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1); + writel(ioregs->ctrl_ddrio_0, (*ctrl)->control_ddrio_0); + writel(ioregs->ctrl_ddrio_1, (*ctrl)->control_ddrio_1); + writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2); +} + +/* DDR3 specific IO settings */ +static void io_settings_ddr3(void) +{ + u32 io_settings = 0; + const struct ctrl_ioregs *ioregs; + + get_ioregs(&ioregs); + writel(ioregs->ctrl_ddr3ch, (*ctrl)->control_ddr3ch1_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch1_1); + + writel(ioregs->ctrl_ddr3ch, (*ctrl)->control_ddr3ch2_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_0); + writel(ioregs->ctrl_ddrch, (*ctrl)->control_ddrch2_1); + + writel(ioregs->ctrl_ddrio_0, (*ctrl)->control_ddrio_0); + writel(ioregs->ctrl_ddrio_1, (*ctrl)->control_ddrio_1); + writel(ioregs->ctrl_ddrio_2, (*ctrl)->control_ddrio_2); + + /* omap5432 does not use lpddr2 */ + writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_0); + writel(ioregs->ctrl_lpddr2ch, (*ctrl)->control_lpddr2ch1_1); + + writel(ioregs->ctrl_emif_sdram_config_ext, + (*ctrl)->control_emif1_sdram_config_ext); + writel(ioregs->ctrl_emif_sdram_config_ext, + (*ctrl)->control_emif2_sdram_config_ext); + + if (is_omap54xx()) { + /* Disable DLL select */ + io_settings = (readl((*ctrl)->control_port_emif1_sdram_config) + & 0xFFEFFFFF); + writel(io_settings, + (*ctrl)->control_port_emif1_sdram_config); + + io_settings = (readl((*ctrl)->control_port_emif2_sdram_config) + & 0xFFEFFFFF); + writel(io_settings, + (*ctrl)->control_port_emif2_sdram_config); + } else { + writel(ioregs->ctrl_ddr_ctrl_ext_0, + (*ctrl)->control_ddr_control_ext_0); + } +} + +/* + * Some tuning of IOs for optimal power and performance + */ +void do_io_settings(void) +{ + u32 io_settings = 0, mask = 0; + + /* Impedance settings EMMC, C2C 1,2, hsi2 */ + mask = (ds_mask << 2) | (ds_mask << 8) | + (ds_mask << 16) | (ds_mask << 18); + io_settings = readl((*ctrl)->control_smart1io_padconf_0) & + (~mask); + io_settings |= (ds_60_ohm << 8) | (ds_45_ohm << 16) | + (ds_45_ohm << 18) | (ds_60_ohm << 2); + writel(io_settings, (*ctrl)->control_smart1io_padconf_0); + + /* Impedance settings Mcspi2 */ + mask = (ds_mask << 30); + io_settings = readl((*ctrl)->control_smart1io_padconf_1) & + (~mask); + io_settings |= (ds_60_ohm << 30); + writel(io_settings, (*ctrl)->control_smart1io_padconf_1); + + /* Impedance settings C2C 3,4 */ + mask = (ds_mask << 14) | (ds_mask << 16); + io_settings = readl((*ctrl)->control_smart1io_padconf_2) & + (~mask); + io_settings |= (ds_45_ohm << 14) | (ds_45_ohm << 16); + writel(io_settings, (*ctrl)->control_smart1io_padconf_2); + + /* Slew rate settings EMMC, C2C 1,2 */ + mask = (sc_mask << 8) | (sc_mask << 16) | (sc_mask << 18); + io_settings = readl((*ctrl)->control_smart2io_padconf_0) & + (~mask); + io_settings |= (sc_fast << 8) | (sc_na << 16) | (sc_na << 18); + writel(io_settings, (*ctrl)->control_smart2io_padconf_0); + + /* Slew rate settings hsi2, Mcspi2 */ + mask = (sc_mask << 24) | (sc_mask << 28); + io_settings = readl((*ctrl)->control_smart2io_padconf_1) & + (~mask); + io_settings |= (sc_fast << 28) | (sc_fast << 24); + writel(io_settings, (*ctrl)->control_smart2io_padconf_1); + + /* Slew rate settings C2C 3,4 */ + mask = (sc_mask << 16) | (sc_mask << 18); + io_settings = readl((*ctrl)->control_smart2io_padconf_2) & + (~mask); + io_settings |= (sc_na << 16) | (sc_na << 18); + writel(io_settings, (*ctrl)->control_smart2io_padconf_2); + + /* impedance and slew rate settings for usb */ + mask = (usb_i_mask << 29) | (usb_i_mask << 26) | (usb_i_mask << 23) | + (usb_i_mask << 20) | (usb_i_mask << 17) | (usb_i_mask << 14); + io_settings = readl((*ctrl)->control_smart3io_padconf_1) & + (~mask); + io_settings |= (ds_60_ohm << 29) | (ds_60_ohm << 26) | + (ds_60_ohm << 23) | (sc_fast << 20) | + (sc_fast << 17) | (sc_fast << 14); + writel(io_settings, (*ctrl)->control_smart3io_padconf_1); + + if (emif_sdram_type() == EMIF_SDRAM_TYPE_LPDDR2) + io_settings_lpddr2(); + else + io_settings_ddr3(); +} + +static const struct srcomp_params srcomp_parameters[NUM_SYS_CLKS] = { + {0x45, 0x1}, /* 12 MHz */ + {-1, -1}, /* 13 MHz */ + {0x63, 0x2}, /* 16.8 MHz */ + {0x57, 0x2}, /* 19.2 MHz */ + {0x20, 0x1}, /* 26 MHz */ + {-1, -1}, /* 27 MHz */ + {0x41, 0x3} /* 38.4 MHz */ +}; + +void srcomp_enable(void) +{ + u32 srcomp_value, mul_factor, div_factor, clk_val, i; + u32 sysclk_ind = get_sys_clk_index(); + u32 omap_rev = omap_revision(); + + if (!is_omap54xx()) + return; + + mul_factor = srcomp_parameters[sysclk_ind].multiply_factor; + div_factor = srcomp_parameters[sysclk_ind].divide_factor; + + for (i = 0; i < 4; i++) { + srcomp_value = readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value &= + ~(MULTIPLY_FACTOR_XS_MASK | DIVIDE_FACTOR_XS_MASK); + srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) | + (div_factor << DIVIDE_FACTOR_XS_SHIFT); + writel(srcomp_value, (*ctrl)->control_srcomp_north_side + i*4); + } + + if ((omap_rev == OMAP5430_ES1_0) || (omap_rev == OMAP5432_ES1_0)) { + clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl); + clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK; + writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl); + + for (i = 0; i < 4; i++) { + srcomp_value = + readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value &= ~PWRDWN_XS_MASK; + writel(srcomp_value, + (*ctrl)->control_srcomp_north_side + i*4); + + while (((readl((*ctrl)->control_srcomp_north_side + i*4) + & SRCODE_READ_XS_MASK) >> + SRCODE_READ_XS_SHIFT) == 0) + ; + + srcomp_value = + readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value &= ~OVERRIDE_XS_MASK; + writel(srcomp_value, + (*ctrl)->control_srcomp_north_side + i*4); + } + } else { + srcomp_value = readl((*ctrl)->control_srcomp_east_side_wkup); + srcomp_value &= ~(MULTIPLY_FACTOR_XS_MASK | + DIVIDE_FACTOR_XS_MASK); + srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) | + (div_factor << DIVIDE_FACTOR_XS_SHIFT); + writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup); + + for (i = 0; i < 4; i++) { + srcomp_value = + readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK; + writel(srcomp_value, + (*ctrl)->control_srcomp_north_side + i*4); + + srcomp_value = + readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value &= ~OVERRIDE_XS_MASK; + writel(srcomp_value, + (*ctrl)->control_srcomp_north_side + i*4); + } + + srcomp_value = + readl((*ctrl)->control_srcomp_east_side_wkup); + srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK; + writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup); + + srcomp_value = + readl((*ctrl)->control_srcomp_east_side_wkup); + srcomp_value &= ~OVERRIDE_XS_MASK; + writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup); + + clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl); + clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK; + writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl); + + clk_val = readl((*prcm)->cm_wkupaon_io_srcomp_clkctrl); + clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK; + writel(clk_val, (*prcm)->cm_wkupaon_io_srcomp_clkctrl); + + for (i = 0; i < 4; i++) { + while (((readl((*ctrl)->control_srcomp_north_side + i*4) + & SRCODE_READ_XS_MASK) >> + SRCODE_READ_XS_SHIFT) == 0) + ; + + srcomp_value = + readl((*ctrl)->control_srcomp_north_side + i*4); + srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK; + writel(srcomp_value, + (*ctrl)->control_srcomp_north_side + i*4); + } + + while (((readl((*ctrl)->control_srcomp_east_side_wkup) & + SRCODE_READ_XS_MASK) >> SRCODE_READ_XS_SHIFT) == 0) + ; + + srcomp_value = + readl((*ctrl)->control_srcomp_east_side_wkup); + srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK; + writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup); + } +} +#endif + +void config_data_eye_leveling_samples(u32 emif_base) +{ + const struct ctrl_ioregs *ioregs; + + get_ioregs(&ioregs); + + /*EMIF_SDRAM_CONFIG_EXT-Read data eye leveling no of samples =4*/ + if (emif_base == EMIF1_BASE) + writel(ioregs->ctrl_emif_sdram_config_ext_final, + (*ctrl)->control_emif1_sdram_config_ext); + else if (emif_base == EMIF2_BASE) + writel(ioregs->ctrl_emif_sdram_config_ext_final, + (*ctrl)->control_emif2_sdram_config_ext); +} + +void init_cpu_configuration(void) +{ + u32 l2actlr; + + asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r"(l2actlr)); + /* + * L2ACTLR: Ensure to enable the following: + * 3: Disable clean/evict push to external + * 4: Disable WriteUnique and WriteLineUnique transactions from master + * 8: Disable DVM/CMO message broadcast + */ + l2actlr |= 0x118; + omap_smc1(OMAP5_SERVICE_L2ACTLR_SET, l2actlr); +} + +void init_omap_revision(void) +{ + /* + * For some of the ES2/ES1 boards ID_CODE is not reliable: + * Also, ES1 and ES2 have different ARM revisions + * So use ARM revision for identification + */ + unsigned int rev = cortex_rev(); + + switch (readl(CONTROL_ID_CODE)) { + case OMAP5430_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = OMAP5430_ES1_0; + if (rev == MIDR_CORTEX_A15_R2P2) + *omap_si_rev = OMAP5430_ES2_0; + break; + case OMAP5432_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = OMAP5432_ES1_0; + if (rev == MIDR_CORTEX_A15_R2P2) + *omap_si_rev = OMAP5432_ES2_0; + break; + case OMAP5430_CONTROL_ID_CODE_ES2_0: + *omap_si_rev = OMAP5430_ES2_0; + break; + case OMAP5432_CONTROL_ID_CODE_ES2_0: + *omap_si_rev = OMAP5432_ES2_0; + break; + case DRA752_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = DRA752_ES1_0; + break; + case DRA752_CONTROL_ID_CODE_ES1_1: + *omap_si_rev = DRA752_ES1_1; + break; + case DRA722_CONTROL_ID_CODE_ES1_0: + *omap_si_rev = DRA722_ES1_0; + break; + default: + *omap_si_rev = OMAP5430_SILICON_ID_INVALID; + } + init_cpu_configuration(); +} + +void reset_cpu(ulong ignored) +{ + u32 omap_rev = omap_revision(); + + /* + * WARM reset is not functional in case of OMAP5430 ES1.0 soc. + * So use cold reset in case instead. + */ + if (omap_rev == OMAP5430_ES1_0) + writel(PRM_RSTCTRL_RESET << 0x1, (*prcm)->prm_rstctrl); + else + writel(PRM_RSTCTRL_RESET, (*prcm)->prm_rstctrl); +} + +u32 warm_reset(void) +{ + return readl((*prcm)->prm_rstst) & PRM_RSTST_WARM_RESET_MASK; +} + +void setup_warmreset_time(void) +{ + u32 rst_time, rst_val; + +#ifndef CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC + rst_time = CONFIG_DEFAULT_OMAP_RESET_TIME_MAX_USEC; +#else + rst_time = CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC; +#endif + rst_time = usec_to_32k(rst_time) << RSTTIME1_SHIFT; + + if (rst_time > RSTTIME1_MASK) + rst_time = RSTTIME1_MASK; + + rst_val = readl((*prcm)->prm_rsttime) & ~RSTTIME1_MASK; + rst_val |= rst_time; + writel(rst_val, (*prcm)->prm_rsttime); +} + +void v7_arch_cp15_set_l2aux_ctrl(u32 l2auxctrl, u32 cpu_midr, + u32 cpu_rev_comb, u32 cpu_variant, + u32 cpu_rev) +{ + omap_smc1(OMAP5_SERVICE_L2ACTLR_SET, l2auxctrl); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/prcm-regs.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/prcm-regs.c new file mode 100644 index 0000000..0745d42 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -0,0 +1,981 @@ +/* + * + * HW regs data for OMAP5 Soc + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/omap_common.h> + +struct prcm_regs const omap5_es1_prcm = { + /* cm1.ckgen */ + .cm_clksel_core = 0x4a004100, + .cm_clksel_abe = 0x4a004108, + .cm_dll_ctrl = 0x4a004110, + .cm_clkmode_dpll_core = 0x4a004120, + .cm_idlest_dpll_core = 0x4a004124, + .cm_autoidle_dpll_core = 0x4a004128, + .cm_clksel_dpll_core = 0x4a00412c, + .cm_div_m2_dpll_core = 0x4a004130, + .cm_div_m3_dpll_core = 0x4a004134, + .cm_div_h11_dpll_core = 0x4a004138, + .cm_div_h12_dpll_core = 0x4a00413c, + .cm_div_h13_dpll_core = 0x4a004140, + .cm_div_h14_dpll_core = 0x4a004144, + .cm_ssc_deltamstep_dpll_core = 0x4a004148, + .cm_ssc_modfreqdiv_dpll_core = 0x4a00414c, + .cm_emu_override_dpll_core = 0x4a004150, + .cm_div_h22_dpllcore = 0x4a004154, + .cm_div_h23_dpll_core = 0x4a004158, + .cm_clkmode_dpll_mpu = 0x4a004160, + .cm_idlest_dpll_mpu = 0x4a004164, + .cm_autoidle_dpll_mpu = 0x4a004168, + .cm_clksel_dpll_mpu = 0x4a00416c, + .cm_div_m2_dpll_mpu = 0x4a004170, + .cm_ssc_deltamstep_dpll_mpu = 0x4a004188, + .cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c, + .cm_bypclk_dpll_mpu = 0x4a00419c, + .cm_clkmode_dpll_iva = 0x4a0041a0, + .cm_idlest_dpll_iva = 0x4a0041a4, + .cm_autoidle_dpll_iva = 0x4a0041a8, + .cm_clksel_dpll_iva = 0x4a0041ac, + .cm_div_h11_dpll_iva = 0x4a0041b8, + .cm_div_h12_dpll_iva = 0x4a0041bc, + .cm_ssc_deltamstep_dpll_iva = 0x4a0041c8, + .cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc, + .cm_bypclk_dpll_iva = 0x4a0041dc, + .cm_clkmode_dpll_abe = 0x4a0041e0, + .cm_idlest_dpll_abe = 0x4a0041e4, + .cm_autoidle_dpll_abe = 0x4a0041e8, + .cm_clksel_dpll_abe = 0x4a0041ec, + .cm_div_m2_dpll_abe = 0x4a0041f0, + .cm_div_m3_dpll_abe = 0x4a0041f4, + .cm_ssc_deltamstep_dpll_abe = 0x4a004208, + .cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c, + .cm_clkmode_dpll_ddrphy = 0x4a004220, + .cm_idlest_dpll_ddrphy = 0x4a004224, + .cm_autoidle_dpll_ddrphy = 0x4a004228, + .cm_clksel_dpll_ddrphy = 0x4a00422c, + .cm_div_m2_dpll_ddrphy = 0x4a004230, + .cm_div_h11_dpll_ddrphy = 0x4a004238, + .cm_div_h12_dpll_ddrphy = 0x4a00423c, + .cm_div_h13_dpll_ddrphy = 0x4a004240, + .cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248, + .cm_shadow_freq_config1 = 0x4a004260, + .cm_mpu_mpu_clkctrl = 0x4a004320, + + /* cm1.dsp */ + .cm_dsp_clkstctrl = 0x4a004400, + .cm_dsp_dsp_clkctrl = 0x4a004420, + + /* cm1.abe */ + .cm1_abe_clkstctrl = 0x4a004500, + .cm1_abe_l4abe_clkctrl = 0x4a004520, + .cm1_abe_aess_clkctrl = 0x4a004528, + .cm1_abe_pdm_clkctrl = 0x4a004530, + .cm1_abe_dmic_clkctrl = 0x4a004538, + .cm1_abe_mcasp_clkctrl = 0x4a004540, + .cm1_abe_mcbsp1_clkctrl = 0x4a004548, + .cm1_abe_mcbsp2_clkctrl = 0x4a004550, + .cm1_abe_mcbsp3_clkctrl = 0x4a004558, + .cm1_abe_slimbus_clkctrl = 0x4a004560, + .cm1_abe_timer5_clkctrl = 0x4a004568, + .cm1_abe_timer6_clkctrl = 0x4a004570, + .cm1_abe_timer7_clkctrl = 0x4a004578, + .cm1_abe_timer8_clkctrl = 0x4a004580, + .cm1_abe_wdt3_clkctrl = 0x4a004588, + + /* cm2.ckgen */ + .cm_clksel_mpu_m3_iss_root = 0x4a008100, + .cm_clksel_usb_60mhz = 0x4a008104, + .cm_scale_fclk = 0x4a008108, + .cm_core_dvfs_perf1 = 0x4a008110, + .cm_core_dvfs_perf2 = 0x4a008114, + .cm_core_dvfs_perf3 = 0x4a008118, + .cm_core_dvfs_perf4 = 0x4a00811c, + .cm_core_dvfs_current = 0x4a008124, + .cm_iva_dvfs_perf_tesla = 0x4a008128, + .cm_iva_dvfs_perf_ivahd = 0x4a00812c, + .cm_iva_dvfs_perf_abe = 0x4a008130, + .cm_iva_dvfs_current = 0x4a008138, + .cm_clkmode_dpll_per = 0x4a008140, + .cm_idlest_dpll_per = 0x4a008144, + .cm_autoidle_dpll_per = 0x4a008148, + .cm_clksel_dpll_per = 0x4a00814c, + .cm_div_m2_dpll_per = 0x4a008150, + .cm_div_m3_dpll_per = 0x4a008154, + .cm_div_h11_dpll_per = 0x4a008158, + .cm_div_h12_dpll_per = 0x4a00815c, + .cm_div_h14_dpll_per = 0x4a008164, + .cm_ssc_deltamstep_dpll_per = 0x4a008168, + .cm_ssc_modfreqdiv_dpll_per = 0x4a00816c, + .cm_emu_override_dpll_per = 0x4a008170, + .cm_clkmode_dpll_usb = 0x4a008180, + .cm_idlest_dpll_usb = 0x4a008184, + .cm_autoidle_dpll_usb = 0x4a008188, + .cm_clksel_dpll_usb = 0x4a00818c, + .cm_div_m2_dpll_usb = 0x4a008190, + .cm_ssc_deltamstep_dpll_usb = 0x4a0081a8, + .cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac, + .cm_clkdcoldo_dpll_usb = 0x4a0081b4, + .cm_clkmode_dpll_unipro = 0x4a0081c0, + .cm_idlest_dpll_unipro = 0x4a0081c4, + .cm_autoidle_dpll_unipro = 0x4a0081c8, + .cm_clksel_dpll_unipro = 0x4a0081cc, + .cm_div_m2_dpll_unipro = 0x4a0081d0, + .cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8, + .cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec, + + /* cm2.core */ + .cm_coreaon_bandgap_clkctrl = 0x4a008648, + .cm_coreaon_io_srcomp_clkctrl = 0x4a008650, + .cm_l3_1_clkstctrl = 0x4a008700, + .cm_l3_1_dynamicdep = 0x4a008708, + .cm_l3_1_l3_1_clkctrl = 0x4a008720, + .cm_l3_2_clkstctrl = 0x4a008800, + .cm_l3_2_dynamicdep = 0x4a008808, + .cm_l3_2_l3_2_clkctrl = 0x4a008820, + .cm_l3_gpmc_clkctrl = 0x4a008828, + .cm_l3_2_ocmc_ram_clkctrl = 0x4a008830, + .cm_mpu_m3_clkstctrl = 0x4a008900, + .cm_mpu_m3_staticdep = 0x4a008904, + .cm_mpu_m3_dynamicdep = 0x4a008908, + .cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920, + .cm_sdma_clkstctrl = 0x4a008a00, + .cm_sdma_staticdep = 0x4a008a04, + .cm_sdma_dynamicdep = 0x4a008a08, + .cm_sdma_sdma_clkctrl = 0x4a008a20, + .cm_memif_clkstctrl = 0x4a008b00, + .cm_memif_dmm_clkctrl = 0x4a008b20, + .cm_memif_emif_fw_clkctrl = 0x4a008b28, + .cm_memif_emif_1_clkctrl = 0x4a008b30, + .cm_memif_emif_2_clkctrl = 0x4a008b38, + .cm_memif_dll_clkctrl = 0x4a008b40, + .cm_memif_emif_h1_clkctrl = 0x4a008b50, + .cm_memif_emif_h2_clkctrl = 0x4a008b58, + .cm_memif_dll_h_clkctrl = 0x4a008b60, + .cm_c2c_clkstctrl = 0x4a008c00, + .cm_c2c_staticdep = 0x4a008c04, + .cm_c2c_dynamicdep = 0x4a008c08, + .cm_c2c_sad2d_clkctrl = 0x4a008c20, + .cm_c2c_modem_icr_clkctrl = 0x4a008c28, + .cm_c2c_sad2d_fw_clkctrl = 0x4a008c30, + .cm_l4cfg_clkstctrl = 0x4a008d00, + .cm_l4cfg_dynamicdep = 0x4a008d08, + .cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20, + .cm_l4cfg_hw_sem_clkctrl = 0x4a008d28, + .cm_l4cfg_mailbox_clkctrl = 0x4a008d30, + .cm_l4cfg_sar_rom_clkctrl = 0x4a008d38, + .cm_l3instr_clkstctrl = 0x4a008e00, + .cm_l3instr_l3_3_clkctrl = 0x4a008e20, + .cm_l3instr_l3_instr_clkctrl = 0x4a008e28, + .cm_l3instr_intrconn_wp1_clkctrl = 0x4a008e40, + + /* cm2.ivahd */ + .cm_ivahd_clkstctrl = 0x4a008f00, + .cm_ivahd_ivahd_clkctrl = 0x4a008f20, + .cm_ivahd_sl2_clkctrl = 0x4a008f28, + + /* cm2.cam */ + .cm_cam_clkstctrl = 0x4a009000, + .cm_cam_iss_clkctrl = 0x4a009020, + .cm_cam_fdif_clkctrl = 0x4a009028, + + /* cm2.dss */ + .cm_dss_clkstctrl = 0x4a009100, + .cm_dss_dss_clkctrl = 0x4a009120, + + /* cm2.sgx */ + .cm_sgx_clkstctrl = 0x4a009200, + .cm_sgx_sgx_clkctrl = 0x4a009220, + + /* cm2.l3init */ + .cm_l3init_clkstctrl = 0x4a009300, + .cm_l3init_hsmmc1_clkctrl = 0x4a009328, + .cm_l3init_hsmmc2_clkctrl = 0x4a009330, + .cm_l3init_hsi_clkctrl = 0x4a009338, + .cm_l3init_hsusbhost_clkctrl = 0x4a009358, + .cm_l3init_hsusbotg_clkctrl = 0x4a009360, + .cm_l3init_hsusbtll_clkctrl = 0x4a009368, + .cm_l3init_p1500_clkctrl = 0x4a009378, + .cm_l3init_sata_clkctrl = 0x4a009388, + .cm_l3init_fsusb_clkctrl = 0x4a0093d0, + .cm_l3init_ocp2scp1_clkctrl = 0x4a0093e0, + .cm_l3init_ocp2scp3_clkctrl = 0x4a0093e8, + + /* cm2.l4per */ + .cm_l4per_clkstctrl = 0x4a009400, + .cm_l4per_dynamicdep = 0x4a009408, + .cm_l4per_adc_clkctrl = 0x4a009420, + .cm_l4per_gptimer10_clkctrl = 0x4a009428, + .cm_l4per_gptimer11_clkctrl = 0x4a009430, + .cm_l4per_gptimer2_clkctrl = 0x4a009438, + .cm_l4per_gptimer3_clkctrl = 0x4a009440, + .cm_l4per_gptimer4_clkctrl = 0x4a009448, + .cm_l4per_gptimer9_clkctrl = 0x4a009450, + .cm_l4per_elm_clkctrl = 0x4a009458, + .cm_l4per_gpio2_clkctrl = 0x4a009460, + .cm_l4per_gpio3_clkctrl = 0x4a009468, + .cm_l4per_gpio4_clkctrl = 0x4a009470, + .cm_l4per_gpio5_clkctrl = 0x4a009478, + .cm_l4per_gpio6_clkctrl = 0x4a009480, + .cm_l4per_hdq1w_clkctrl = 0x4a009488, + .cm_l4per_hecc1_clkctrl = 0x4a009490, + .cm_l4per_hecc2_clkctrl = 0x4a009498, + .cm_l4per_i2c1_clkctrl = 0x4a0094a0, + .cm_l4per_i2c2_clkctrl = 0x4a0094a8, + .cm_l4per_i2c3_clkctrl = 0x4a0094b0, + .cm_l4per_i2c4_clkctrl = 0x4a0094b8, + .cm_l4per_l4per_clkctrl = 0x4a0094c0, + .cm_l4per_mcasp2_clkctrl = 0x4a0094d0, + .cm_l4per_mcasp3_clkctrl = 0x4a0094d8, + .cm_l4per_mgate_clkctrl = 0x4a0094e8, + .cm_l4per_mcspi1_clkctrl = 0x4a0094f0, + .cm_l4per_mcspi2_clkctrl = 0x4a0094f8, + .cm_l4per_mcspi3_clkctrl = 0x4a009500, + .cm_l4per_mcspi4_clkctrl = 0x4a009508, + .cm_l4per_gpio7_clkctrl = 0x4a009510, + .cm_l4per_gpio8_clkctrl = 0x4a009518, + .cm_l4per_mmcsd3_clkctrl = 0x4a009520, + .cm_l4per_mmcsd4_clkctrl = 0x4a009528, + .cm_l4per_msprohg_clkctrl = 0x4a009530, + .cm_l4per_slimbus2_clkctrl = 0x4a009538, + .cm_l4per_uart1_clkctrl = 0x4a009540, + .cm_l4per_uart2_clkctrl = 0x4a009548, + .cm_l4per_uart3_clkctrl = 0x4a009550, + .cm_l4per_uart4_clkctrl = 0x4a009558, + .cm_l4per_mmcsd5_clkctrl = 0x4a009560, + .cm_l4per_i2c5_clkctrl = 0x4a009568, + .cm_l4per_uart5_clkctrl = 0x4a009570, + .cm_l4per_uart6_clkctrl = 0x4a009578, + .cm_l4sec_clkstctrl = 0x4a009580, + .cm_l4sec_staticdep = 0x4a009584, + .cm_l4sec_dynamicdep = 0x4a009588, + .cm_l4sec_aes1_clkctrl = 0x4a0095a0, + .cm_l4sec_aes2_clkctrl = 0x4a0095a8, + .cm_l4sec_des3des_clkctrl = 0x4a0095b0, + .cm_l4sec_pkaeip29_clkctrl = 0x4a0095b8, + .cm_l4sec_rng_clkctrl = 0x4a0095c0, + .cm_l4sec_sha2md51_clkctrl = 0x4a0095c8, + .cm_l4sec_cryptodma_clkctrl = 0x4a0095d8, + + /* l4 wkup regs */ + .cm_abe_pll_ref_clksel = 0x4ae0610c, + .cm_sys_clksel = 0x4ae06110, + .cm_wkup_clkstctrl = 0x4ae07800, + .cm_wkup_l4wkup_clkctrl = 0x4ae07820, + .cm_wkup_wdtimer1_clkctrl = 0x4ae07828, + .cm_wkup_wdtimer2_clkctrl = 0x4ae07830, + .cm_wkup_gpio1_clkctrl = 0x4ae07838, + .cm_wkup_gptimer1_clkctrl = 0x4ae07840, + .cm_wkup_gptimer12_clkctrl = 0x4ae07848, + .cm_wkup_synctimer_clkctrl = 0x4ae07850, + .cm_wkup_usim_clkctrl = 0x4ae07858, + .cm_wkup_sarram_clkctrl = 0x4ae07860, + .cm_wkup_keyboard_clkctrl = 0x4ae07878, + .cm_wkup_rtc_clkctrl = 0x4ae07880, + .cm_wkup_bandgap_clkctrl = 0x4ae07888, + .cm_wkupaon_scrm_clkctrl = 0x4ae07890, + .cm_wkupaon_io_srcomp_clkctrl = 0x4ae07898, + .prm_rstctrl = 0x4ae07b00, + .prm_rstst = 0x4ae07b04, + .prm_rsttime = 0x4ae07b08, + .prm_vc_val_bypass = 0x4ae07ba0, + .prm_vc_cfg_i2c_mode = 0x4ae07bb4, + .prm_vc_cfg_i2c_clk = 0x4ae07bb8, + + /* SCRM stuff, used by some boards */ + .scrm_auxclk0 = 0x4ae0a310, + .scrm_auxclk1 = 0x4ae0a314, +}; + +struct omap_sys_ctrl_regs const omap5_ctrl = { + .control_status = 0x4A002134, + .control_std_fuse_opp_vdd_mpu_2 = 0x4A0021B4, + .control_phy_power_usb = 0x4A002370, + .control_phy_power_sata = 0x4A002374, + .control_padconf_core_base = 0x4A002800, + .control_paconf_global = 0x4A002DA0, + .control_paconf_mode = 0x4A002DA4, + .control_smart1io_padconf_0 = 0x4A002DA8, + .control_smart1io_padconf_1 = 0x4A002DAC, + .control_smart1io_padconf_2 = 0x4A002DB0, + .control_smart2io_padconf_0 = 0x4A002DB4, + .control_smart2io_padconf_1 = 0x4A002DB8, + .control_smart2io_padconf_2 = 0x4A002DBC, + .control_smart3io_padconf_0 = 0x4A002DC0, + .control_smart3io_padconf_1 = 0x4A002DC4, + .control_pbias = 0x4A002E00, + .control_i2c_0 = 0x4A002E04, + .control_camera_rx = 0x4A002E08, + .control_hdmi_tx_phy = 0x4A002E0C, + .control_uniportm = 0x4A002E10, + .control_dsiphy = 0x4A002E14, + .control_mcbsplp = 0x4A002E18, + .control_usb2phycore = 0x4A002E1C, + .control_hdmi_1 = 0x4A002E20, + .control_hsi = 0x4A002E24, + .control_ddr3ch1_0 = 0x4A002E30, + .control_ddr3ch2_0 = 0x4A002E34, + .control_ddrch1_0 = 0x4A002E38, + .control_ddrch1_1 = 0x4A002E3C, + .control_ddrch2_0 = 0x4A002E40, + .control_ddrch2_1 = 0x4A002E44, + .control_lpddr2ch1_0 = 0x4A002E48, + .control_lpddr2ch1_1 = 0x4A002E4C, + .control_ddrio_0 = 0x4A002E50, + .control_ddrio_1 = 0x4A002E54, + .control_ddrio_2 = 0x4A002E58, + .control_hyst_1 = 0x4A002E5C, + .control_usbb_hsic_control = 0x4A002E60, + .control_c2c = 0x4A002E64, + .control_core_control_spare_rw = 0x4A002E68, + .control_core_control_spare_r = 0x4A002E6C, + .control_core_control_spare_r_c0 = 0x4A002E70, + .control_srcomp_north_side = 0x4A002E74, + .control_srcomp_south_side = 0x4A002E78, + .control_srcomp_east_side = 0x4A002E7C, + .control_srcomp_west_side = 0x4A002E80, + .control_srcomp_code_latch = 0x4A002E84, + .control_port_emif1_sdram_config = 0x4AE0C110, + .control_port_emif1_lpddr2_nvm_config = 0x4AE0C114, + .control_port_emif2_sdram_config = 0x4AE0C118, + .control_emif1_sdram_config_ext = 0x4AE0C144, + .control_emif2_sdram_config_ext = 0x4AE0C148, + .control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C318, + .control_padconf_wkup_base = 0x4AE0C800, + .control_smart1nopmio_padconf_0 = 0x4AE0CDA0, + .control_smart1nopmio_padconf_1 = 0x4AE0CDA4, + .control_padconf_mode = 0x4AE0CDA8, + .control_xtal_oscillator = 0x4AE0CDAC, + .control_i2c_2 = 0x4AE0CDB0, + .control_ckobuffer = 0x4AE0CDB4, + .control_wkup_control_spare_rw = 0x4AE0CDB8, + .control_wkup_control_spare_r = 0x4AE0CDBC, + .control_wkup_control_spare_r_c0 = 0x4AE0CDC0, + .control_srcomp_east_side_wkup = 0x4AE0CDC4, + .control_efuse_1 = 0x4AE0CDC8, + .control_efuse_2 = 0x4AE0CDCC, + .control_efuse_3 = 0x4AE0CDD0, + .control_efuse_4 = 0x4AE0CDD4, + .control_efuse_5 = 0x4AE0CDD8, + .control_efuse_6 = 0x4AE0CDDC, + .control_efuse_7 = 0x4AE0CDE0, + .control_efuse_8 = 0x4AE0CDE4, + .control_efuse_9 = 0x4AE0CDE8, + .control_efuse_10 = 0x4AE0CDEC, + .control_efuse_11 = 0x4AE0CDF0, + .control_efuse_12 = 0x4AE0CDF4, + .control_efuse_13 = 0x4AE0CDF8, +}; + +struct omap_sys_ctrl_regs const dra7xx_ctrl = { + .control_status = 0x4A002134, + .control_phy_power_usb = 0x4A002370, + .control_phy_power_sata = 0x4A002374, + .control_core_mac_id_0_lo = 0x4A002514, + .control_core_mac_id_0_hi = 0x4A002518, + .control_core_mac_id_1_lo = 0x4A00251C, + .control_core_mac_id_1_hi = 0x4A002520, + .control_core_mmr_lock1 = 0x4A002540, + .control_core_mmr_lock2 = 0x4A002544, + .control_core_mmr_lock3 = 0x4A002548, + .control_core_mmr_lock4 = 0x4A00254C, + .control_core_mmr_lock5 = 0x4A002550, + .control_core_control_io1 = 0x4A002554, + .control_core_control_io2 = 0x4A002558, + .control_paconf_global = 0x4A002DA0, + .control_paconf_mode = 0x4A002DA4, + .control_smart1io_padconf_0 = 0x4A002DA8, + .control_smart1io_padconf_1 = 0x4A002DAC, + .control_smart1io_padconf_2 = 0x4A002DB0, + .control_smart2io_padconf_0 = 0x4A002DB4, + .control_smart2io_padconf_1 = 0x4A002DB8, + .control_smart2io_padconf_2 = 0x4A002DBC, + .control_smart3io_padconf_0 = 0x4A002DC0, + .control_smart3io_padconf_1 = 0x4A002DC4, + .control_pbias = 0x4A002E00, + .control_i2c_0 = 0x4A002E04, + .control_camera_rx = 0x4A002E08, + .control_hdmi_tx_phy = 0x4A002E0C, + .control_uniportm = 0x4A002E10, + .control_dsiphy = 0x4A002E14, + .control_mcbsplp = 0x4A002E18, + .control_usb2phycore = 0x4A002E1C, + .control_hdmi_1 = 0x4A002E20, + .control_hsi = 0x4A002E24, + .control_ddr3ch1_0 = 0x4A002E30, + .control_ddr3ch2_0 = 0x4A002E34, + .control_ddrch1_0 = 0x4A002E38, + .control_ddrch1_1 = 0x4A002E3C, + .control_ddrch2_0 = 0x4A002E40, + .control_ddrch2_1 = 0x4A002E44, + .control_lpddr2ch1_0 = 0x4A002E48, + .control_lpddr2ch1_1 = 0x4A002E4C, + .control_ddrio_0 = 0x4A002E50, + .control_ddrio_1 = 0x4A002E54, + .control_ddrio_2 = 0x4A002E58, + .control_hyst_1 = 0x4A002E5C, + .control_usbb_hsic_control = 0x4A002E60, + .control_c2c = 0x4A002E64, + .control_core_control_spare_rw = 0x4A002E68, + .control_core_control_spare_r = 0x4A002E6C, + .control_core_control_spare_r_c0 = 0x4A002E70, + .control_srcomp_north_side = 0x4A002E74, + .control_srcomp_south_side = 0x4A002E78, + .control_srcomp_east_side = 0x4A002E7C, + .control_srcomp_west_side = 0x4A002E80, + .control_srcomp_code_latch = 0x4A002E84, + .control_ddr_control_ext_0 = 0x4A002E88, + .control_padconf_core_base = 0x4A003400, + .control_std_fuse_opp_vdd_mpu_2 = 0x4A003B20, + .control_port_emif1_sdram_config = 0x4AE0C110, + .control_port_emif1_lpddr2_nvm_config = 0x4AE0C114, + .control_port_emif2_sdram_config = 0x4AE0C118, + .control_emif1_sdram_config_ext = 0x4AE0C144, + .control_emif2_sdram_config_ext = 0x4AE0C148, + .control_wkup_ldovbb_mpu_voltage_ctrl = 0x4AE0C158, + .control_padconf_mode = 0x4AE0C5A0, + .control_xtal_oscillator = 0x4AE0C5A4, + .control_i2c_2 = 0x4AE0C5A8, + .control_ckobuffer = 0x4AE0C5AC, + .control_wkup_control_spare_rw = 0x4AE0C5B0, + .control_wkup_control_spare_r = 0x4AE0C5B4, + .control_wkup_control_spare_r_c0 = 0x4AE0C5B8, + .control_srcomp_east_side_wkup = 0x4AE0C5BC, + .control_efuse_1 = 0x4AE0C5C8, + .control_efuse_2 = 0x4AE0C5CC, + .control_efuse_3 = 0x4AE0C5D0, + .control_efuse_4 = 0x4AE0C5D4, + .control_efuse_13 = 0x4AE0C5F0, +}; + +struct prcm_regs const omap5_es2_prcm = { + /* cm1.ckgen */ + .cm_clksel_core = 0x4a004100, + .cm_clksel_abe = 0x4a004108, + .cm_dll_ctrl = 0x4a004110, + .cm_clkmode_dpll_core = 0x4a004120, + .cm_idlest_dpll_core = 0x4a004124, + .cm_autoidle_dpll_core = 0x4a004128, + .cm_clksel_dpll_core = 0x4a00412c, + .cm_div_m2_dpll_core = 0x4a004130, + .cm_div_m3_dpll_core = 0x4a004134, + .cm_div_h11_dpll_core = 0x4a004138, + .cm_div_h12_dpll_core = 0x4a00413c, + .cm_div_h13_dpll_core = 0x4a004140, + .cm_div_h14_dpll_core = 0x4a004144, + .cm_ssc_deltamstep_dpll_core = 0x4a004148, + .cm_ssc_modfreqdiv_dpll_core = 0x4a00414c, + .cm_div_h21_dpll_core = 0x4a004150, + .cm_div_h22_dpllcore = 0x4a004154, + .cm_div_h23_dpll_core = 0x4a004158, + .cm_div_h24_dpll_core = 0x4a00415c, + .cm_clkmode_dpll_mpu = 0x4a004160, + .cm_idlest_dpll_mpu = 0x4a004164, + .cm_autoidle_dpll_mpu = 0x4a004168, + .cm_clksel_dpll_mpu = 0x4a00416c, + .cm_div_m2_dpll_mpu = 0x4a004170, + .cm_ssc_deltamstep_dpll_mpu = 0x4a004188, + .cm_ssc_modfreqdiv_dpll_mpu = 0x4a00418c, + .cm_bypclk_dpll_mpu = 0x4a00419c, + .cm_clkmode_dpll_iva = 0x4a0041a0, + .cm_idlest_dpll_iva = 0x4a0041a4, + .cm_autoidle_dpll_iva = 0x4a0041a8, + .cm_clksel_dpll_iva = 0x4a0041ac, + .cm_div_h11_dpll_iva = 0x4a0041b8, + .cm_div_h12_dpll_iva = 0x4a0041bc, + .cm_ssc_deltamstep_dpll_iva = 0x4a0041c8, + .cm_ssc_modfreqdiv_dpll_iva = 0x4a0041cc, + .cm_bypclk_dpll_iva = 0x4a0041dc, + .cm_clkmode_dpll_abe = 0x4a0041e0, + .cm_idlest_dpll_abe = 0x4a0041e4, + .cm_autoidle_dpll_abe = 0x4a0041e8, + .cm_clksel_dpll_abe = 0x4a0041ec, + .cm_div_m2_dpll_abe = 0x4a0041f0, + .cm_div_m3_dpll_abe = 0x4a0041f4, + .cm_ssc_deltamstep_dpll_abe = 0x4a004208, + .cm_ssc_modfreqdiv_dpll_abe = 0x4a00420c, + .cm_clkmode_dpll_ddrphy = 0x4a004220, + .cm_idlest_dpll_ddrphy = 0x4a004224, + .cm_autoidle_dpll_ddrphy = 0x4a004228, + .cm_clksel_dpll_ddrphy = 0x4a00422c, + .cm_div_m2_dpll_ddrphy = 0x4a004230, + .cm_div_h11_dpll_ddrphy = 0x4a004238, + .cm_div_h12_dpll_ddrphy = 0x4a00423c, + .cm_div_h13_dpll_ddrphy = 0x4a004240, + .cm_ssc_deltamstep_dpll_ddrphy = 0x4a004248, + .cm_shadow_freq_config1 = 0x4a004260, + .cm_mpu_mpu_clkctrl = 0x4a004320, + + /* cm1.dsp */ + .cm_dsp_clkstctrl = 0x4a004400, + .cm_dsp_dsp_clkctrl = 0x4a004420, + + /* cm1.abe */ + .cm1_abe_clkstctrl = 0x4a004500, + .cm1_abe_l4abe_clkctrl = 0x4a004520, + .cm1_abe_aess_clkctrl = 0x4a004528, + .cm1_abe_pdm_clkctrl = 0x4a004530, + .cm1_abe_dmic_clkctrl = 0x4a004538, + .cm1_abe_mcasp_clkctrl = 0x4a004540, + .cm1_abe_mcbsp1_clkctrl = 0x4a004548, + .cm1_abe_mcbsp2_clkctrl = 0x4a004550, + .cm1_abe_mcbsp3_clkctrl = 0x4a004558, + .cm1_abe_slimbus_clkctrl = 0x4a004560, + .cm1_abe_timer5_clkctrl = 0x4a004568, + .cm1_abe_timer6_clkctrl = 0x4a004570, + .cm1_abe_timer7_clkctrl = 0x4a004578, + .cm1_abe_timer8_clkctrl = 0x4a004580, + .cm1_abe_wdt3_clkctrl = 0x4a004588, + + /* cm2.ckgen */ + .cm_clksel_mpu_m3_iss_root = 0x4a008100, + .cm_clksel_usb_60mhz = 0x4a008104, + .cm_scale_fclk = 0x4a008108, + .cm_core_dvfs_perf1 = 0x4a008110, + .cm_core_dvfs_perf2 = 0x4a008114, + .cm_core_dvfs_perf3 = 0x4a008118, + .cm_core_dvfs_perf4 = 0x4a00811c, + .cm_core_dvfs_current = 0x4a008124, + .cm_iva_dvfs_perf_tesla = 0x4a008128, + .cm_iva_dvfs_perf_ivahd = 0x4a00812c, + .cm_iva_dvfs_perf_abe = 0x4a008130, + .cm_iva_dvfs_current = 0x4a008138, + .cm_clkmode_dpll_per = 0x4a008140, + .cm_idlest_dpll_per = 0x4a008144, + .cm_autoidle_dpll_per = 0x4a008148, + .cm_clksel_dpll_per = 0x4a00814c, + .cm_div_m2_dpll_per = 0x4a008150, + .cm_div_m3_dpll_per = 0x4a008154, + .cm_div_h11_dpll_per = 0x4a008158, + .cm_div_h12_dpll_per = 0x4a00815c, + .cm_div_h13_dpll_per = 0x4a008160, + .cm_div_h14_dpll_per = 0x4a008164, + .cm_ssc_deltamstep_dpll_per = 0x4a008168, + .cm_ssc_modfreqdiv_dpll_per = 0x4a00816c, + .cm_emu_override_dpll_per = 0x4a008170, + .cm_clkmode_dpll_usb = 0x4a008180, + .cm_idlest_dpll_usb = 0x4a008184, + .cm_autoidle_dpll_usb = 0x4a008188, + .cm_clksel_dpll_usb = 0x4a00818c, + .cm_div_m2_dpll_usb = 0x4a008190, + .cm_ssc_deltamstep_dpll_usb = 0x4a0081a8, + .cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac, + .cm_clkdcoldo_dpll_usb = 0x4a0081b4, + .cm_clkmode_dpll_unipro = 0x4a0081c0, + .cm_idlest_dpll_unipro = 0x4a0081c4, + .cm_autoidle_dpll_unipro = 0x4a0081c8, + .cm_clksel_dpll_unipro = 0x4a0081cc, + .cm_div_m2_dpll_unipro = 0x4a0081d0, + .cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8, + .cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec, + .cm_coreaon_usb_phy_core_clkctrl = 0x4A008640, + .cm_coreaon_bandgap_clkctrl = 0x4a008648, + .cm_coreaon_io_srcomp_clkctrl = 0x4a008650, + + /* cm2.core */ + .cm_l3_1_clkstctrl = 0x4a008700, + .cm_l3_1_dynamicdep = 0x4a008708, + .cm_l3_1_l3_1_clkctrl = 0x4a008720, + .cm_l3_2_clkstctrl = 0x4a008800, + .cm_l3_2_dynamicdep = 0x4a008808, + .cm_l3_2_l3_2_clkctrl = 0x4a008820, + .cm_l3_gpmc_clkctrl = 0x4a008828, + .cm_l3_2_ocmc_ram_clkctrl = 0x4a008830, + .cm_mpu_m3_clkstctrl = 0x4a008900, + .cm_mpu_m3_staticdep = 0x4a008904, + .cm_mpu_m3_dynamicdep = 0x4a008908, + .cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920, + .cm_sdma_clkstctrl = 0x4a008a00, + .cm_sdma_staticdep = 0x4a008a04, + .cm_sdma_dynamicdep = 0x4a008a08, + .cm_sdma_sdma_clkctrl = 0x4a008a20, + .cm_memif_clkstctrl = 0x4a008b00, + .cm_memif_dmm_clkctrl = 0x4a008b20, + .cm_memif_emif_fw_clkctrl = 0x4a008b28, + .cm_memif_emif_1_clkctrl = 0x4a008b30, + .cm_memif_emif_2_clkctrl = 0x4a008b38, + .cm_memif_dll_clkctrl = 0x4a008b40, + .cm_memif_emif_h1_clkctrl = 0x4a008b50, + .cm_memif_emif_h2_clkctrl = 0x4a008b58, + .cm_memif_dll_h_clkctrl = 0x4a008b60, + .cm_c2c_clkstctrl = 0x4a008c00, + .cm_c2c_staticdep = 0x4a008c04, + .cm_c2c_dynamicdep = 0x4a008c08, + .cm_c2c_sad2d_clkctrl = 0x4a008c20, + .cm_c2c_modem_icr_clkctrl = 0x4a008c28, + .cm_c2c_sad2d_fw_clkctrl = 0x4a008c30, + .cm_l4cfg_clkstctrl = 0x4a008d00, + .cm_l4cfg_dynamicdep = 0x4a008d08, + .cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20, + .cm_l4cfg_hw_sem_clkctrl = 0x4a008d28, + .cm_l4cfg_mailbox_clkctrl = 0x4a008d30, + .cm_l4cfg_sar_rom_clkctrl = 0x4a008d38, + .cm_l3instr_clkstctrl = 0x4a008e00, + .cm_l3instr_l3_3_clkctrl = 0x4a008e20, + .cm_l3instr_l3_instr_clkctrl = 0x4a008e28, + .cm_l3instr_intrconn_wp1_clkctrl = 0x4a008e40, + .cm_l4per_clkstctrl = 0x4a009000, + .cm_l4per_dynamicdep = 0x4a009008, + .cm_l4per_adc_clkctrl = 0x4a009020, + .cm_l4per_gptimer10_clkctrl = 0x4a009028, + .cm_l4per_gptimer11_clkctrl = 0x4a009030, + .cm_l4per_gptimer2_clkctrl = 0x4a009038, + .cm_l4per_gptimer3_clkctrl = 0x4a009040, + .cm_l4per_gptimer4_clkctrl = 0x4a009048, + .cm_l4per_gptimer9_clkctrl = 0x4a009050, + .cm_l4per_elm_clkctrl = 0x4a009058, + .cm_l4per_gpio2_clkctrl = 0x4a009060, + .cm_l4per_gpio3_clkctrl = 0x4a009068, + .cm_l4per_gpio4_clkctrl = 0x4a009070, + .cm_l4per_gpio5_clkctrl = 0x4a009078, + .cm_l4per_gpio6_clkctrl = 0x4a009080, + .cm_l4per_hdq1w_clkctrl = 0x4a009088, + .cm_l4per_hecc1_clkctrl = 0x4a009090, + .cm_l4per_hecc2_clkctrl = 0x4a009098, + .cm_l4per_i2c1_clkctrl = 0x4a0090a0, + .cm_l4per_i2c2_clkctrl = 0x4a0090a8, + .cm_l4per_i2c3_clkctrl = 0x4a0090b0, + .cm_l4per_i2c4_clkctrl = 0x4a0090b8, + .cm_l4per_l4per_clkctrl = 0x4a0090c0, + .cm_l4per_mcasp2_clkctrl = 0x4a0090d0, + .cm_l4per_mcasp3_clkctrl = 0x4a0090d8, + .cm_l4per_mgate_clkctrl = 0x4a0090e8, + .cm_l4per_mcspi1_clkctrl = 0x4a0090f0, + .cm_l4per_mcspi2_clkctrl = 0x4a0090f8, + .cm_l4per_mcspi3_clkctrl = 0x4a009100, + .cm_l4per_mcspi4_clkctrl = 0x4a009108, + .cm_l4per_gpio7_clkctrl = 0x4a009110, + .cm_l4per_gpio8_clkctrl = 0x4a009118, + .cm_l4per_mmcsd3_clkctrl = 0x4a009120, + .cm_l4per_mmcsd4_clkctrl = 0x4a009128, + .cm_l4per_msprohg_clkctrl = 0x4a009130, + .cm_l4per_slimbus2_clkctrl = 0x4a009138, + .cm_l4per_uart1_clkctrl = 0x4a009140, + .cm_l4per_uart2_clkctrl = 0x4a009148, + .cm_l4per_uart3_clkctrl = 0x4a009150, + .cm_l4per_uart4_clkctrl = 0x4a009158, + .cm_l4per_mmcsd5_clkctrl = 0x4a009160, + .cm_l4per_i2c5_clkctrl = 0x4a009168, + .cm_l4per_uart5_clkctrl = 0x4a009170, + .cm_l4per_uart6_clkctrl = 0x4a009178, + .cm_l4sec_clkstctrl = 0x4a009180, + .cm_l4sec_staticdep = 0x4a009184, + .cm_l4sec_dynamicdep = 0x4a009188, + .cm_l4sec_aes1_clkctrl = 0x4a0091a0, + .cm_l4sec_aes2_clkctrl = 0x4a0091a8, + .cm_l4sec_des3des_clkctrl = 0x4a0091b0, + .cm_l4sec_pkaeip29_clkctrl = 0x4a0091b8, + .cm_l4sec_rng_clkctrl = 0x4a0091c0, + .cm_l4sec_sha2md51_clkctrl = 0x4a0091c8, + .cm_l4sec_cryptodma_clkctrl = 0x4a0091d8, + + /* cm2.ivahd */ + .cm_ivahd_clkstctrl = 0x4a009200, + .cm_ivahd_ivahd_clkctrl = 0x4a009220, + .cm_ivahd_sl2_clkctrl = 0x4a009228, + + /* cm2.cam */ + .cm_cam_clkstctrl = 0x4a009300, + .cm_cam_iss_clkctrl = 0x4a009320, + .cm_cam_fdif_clkctrl = 0x4a009328, + + /* cm2.dss */ + .cm_dss_clkstctrl = 0x4a009400, + .cm_dss_dss_clkctrl = 0x4a009420, + + /* cm2.sgx */ + .cm_sgx_clkstctrl = 0x4a009500, + .cm_sgx_sgx_clkctrl = 0x4a009520, + + /* cm2.l3init */ + .cm_l3init_clkstctrl = 0x4a009600, + + /* cm2.l3init */ + .cm_l3init_hsmmc1_clkctrl = 0x4a009628, + .cm_l3init_hsmmc2_clkctrl = 0x4a009630, + .cm_l3init_hsi_clkctrl = 0x4a009638, + .cm_l3init_hsusbhost_clkctrl = 0x4a009658, + .cm_l3init_hsusbotg_clkctrl = 0x4a009660, + .cm_l3init_hsusbtll_clkctrl = 0x4a009668, + .cm_l3init_p1500_clkctrl = 0x4a009678, + .cm_l3init_sata_clkctrl = 0x4a009688, + .cm_l3init_fsusb_clkctrl = 0x4a0096d0, + .cm_l3init_ocp2scp1_clkctrl = 0x4a0096e0, + .cm_l3init_ocp2scp3_clkctrl = 0x4a0096e8, + .cm_l3init_usb_otg_ss_clkctrl = 0x4a0096f0, + + /* prm irqstatus regs */ + .prm_irqstatus_mpu_2 = 0x4ae06014, + + /* l4 wkup regs */ + .cm_abe_pll_ref_clksel = 0x4ae0610c, + .cm_sys_clksel = 0x4ae06110, + .cm_wkup_clkstctrl = 0x4ae07900, + .cm_wkup_l4wkup_clkctrl = 0x4ae07920, + .cm_wkup_wdtimer1_clkctrl = 0x4ae07928, + .cm_wkup_wdtimer2_clkctrl = 0x4ae07930, + .cm_wkup_gpio1_clkctrl = 0x4ae07938, + .cm_wkup_gptimer1_clkctrl = 0x4ae07940, + .cm_wkup_gptimer12_clkctrl = 0x4ae07948, + .cm_wkup_synctimer_clkctrl = 0x4ae07950, + .cm_wkup_usim_clkctrl = 0x4ae07958, + .cm_wkup_sarram_clkctrl = 0x4ae07960, + .cm_wkup_keyboard_clkctrl = 0x4ae07978, + .cm_wkup_rtc_clkctrl = 0x4ae07980, + .cm_wkup_bandgap_clkctrl = 0x4ae07988, + .cm_wkupaon_scrm_clkctrl = 0x4ae07990, + .cm_wkupaon_io_srcomp_clkctrl = 0x4ae07998, + .prm_rstctrl = 0x4ae07c00, + .prm_rstst = 0x4ae07c04, + .prm_rsttime = 0x4ae07c08, + .prm_vc_val_bypass = 0x4ae07ca0, + .prm_vc_cfg_i2c_mode = 0x4ae07cb4, + .prm_vc_cfg_i2c_clk = 0x4ae07cb8, + + .prm_abbldo_mpu_setup = 0x4ae07cdc, + .prm_abbldo_mpu_ctrl = 0x4ae07ce0, + + /* SCRM stuff, used by some boards */ + .scrm_auxclk0 = 0x4ae0a310, + .scrm_auxclk1 = 0x4ae0a314, +}; + +struct prcm_regs const dra7xx_prcm = { + /* cm1.ckgen */ + .cm_clksel_core = 0x4a005100, + .cm_clksel_abe = 0x4a005108, + .cm_dll_ctrl = 0x4a005110, + .cm_clkmode_dpll_core = 0x4a005120, + .cm_idlest_dpll_core = 0x4a005124, + .cm_autoidle_dpll_core = 0x4a005128, + .cm_clksel_dpll_core = 0x4a00512c, + .cm_div_m2_dpll_core = 0x4a005130, + .cm_div_m3_dpll_core = 0x4a005134, + .cm_div_h11_dpll_core = 0x4a005138, + .cm_div_h12_dpll_core = 0x4a00513c, + .cm_div_h13_dpll_core = 0x4a005140, + .cm_div_h14_dpll_core = 0x4a005144, + .cm_ssc_deltamstep_dpll_core = 0x4a005148, + .cm_ssc_modfreqdiv_dpll_core = 0x4a00514c, + .cm_div_h21_dpll_core = 0x4a005150, + .cm_div_h22_dpllcore = 0x4a005154, + .cm_div_h23_dpll_core = 0x4a005158, + .cm_div_h24_dpll_core = 0x4a00515c, + .cm_clkmode_dpll_mpu = 0x4a005160, + .cm_idlest_dpll_mpu = 0x4a005164, + .cm_autoidle_dpll_mpu = 0x4a005168, + .cm_clksel_dpll_mpu = 0x4a00516c, + .cm_div_m2_dpll_mpu = 0x4a005170, + .cm_ssc_deltamstep_dpll_mpu = 0x4a005188, + .cm_ssc_modfreqdiv_dpll_mpu = 0x4a00518c, + .cm_bypclk_dpll_mpu = 0x4a00519c, + .cm_clkmode_dpll_iva = 0x4a0051a0, + .cm_idlest_dpll_iva = 0x4a0051a4, + .cm_autoidle_dpll_iva = 0x4a0051a8, + .cm_clksel_dpll_iva = 0x4a0051ac, + .cm_ssc_deltamstep_dpll_iva = 0x4a0051c8, + .cm_ssc_modfreqdiv_dpll_iva = 0x4a0051cc, + .cm_bypclk_dpll_iva = 0x4a0051dc, + .cm_clkmode_dpll_abe = 0x4a0051e0, + .cm_idlest_dpll_abe = 0x4a0051e4, + .cm_autoidle_dpll_abe = 0x4a0051e8, + .cm_clksel_dpll_abe = 0x4a0051ec, + .cm_div_m2_dpll_abe = 0x4a0051f0, + .cm_div_m3_dpll_abe = 0x4a0051f4, + .cm_ssc_deltamstep_dpll_abe = 0x4a005208, + .cm_ssc_modfreqdiv_dpll_abe = 0x4a00520c, + .cm_clkmode_dpll_ddrphy = 0x4a005210, + .cm_idlest_dpll_ddrphy = 0x4a005214, + .cm_autoidle_dpll_ddrphy = 0x4a005218, + .cm_clksel_dpll_ddrphy = 0x4a00521c, + .cm_div_m2_dpll_ddrphy = 0x4a005220, + .cm_div_h11_dpll_ddrphy = 0x4a005228, + .cm_ssc_deltamstep_dpll_ddrphy = 0x4a00522c, + .cm_clkmode_dpll_dsp = 0x4a005234, + .cm_shadow_freq_config1 = 0x4a005260, + .cm_clkmode_dpll_gmac = 0x4a0052a8, + .cm_coreaon_usb_phy_core_clkctrl = 0x4a008640, + .cm_coreaon_usb_phy2_core_clkctrl = 0x4a008688, + + /* cm1.mpu */ + .cm_mpu_mpu_clkctrl = 0x4a005320, + + /* cm1.dsp */ + .cm_dsp_clkstctrl = 0x4a005400, + .cm_dsp_dsp_clkctrl = 0x4a005420, + + /* prm irqstatus regs */ + .prm_irqstatus_mpu_2 = 0x4ae06014, + + /* cm2.ckgen */ + .cm_clksel_usb_60mhz = 0x4a008104, + .cm_clkmode_dpll_per = 0x4a008140, + .cm_idlest_dpll_per = 0x4a008144, + .cm_autoidle_dpll_per = 0x4a008148, + .cm_clksel_dpll_per = 0x4a00814c, + .cm_div_m2_dpll_per = 0x4a008150, + .cm_div_m3_dpll_per = 0x4a008154, + .cm_div_h11_dpll_per = 0x4a008158, + .cm_div_h12_dpll_per = 0x4a00815c, + .cm_div_h13_dpll_per = 0x4a008160, + .cm_div_h14_dpll_per = 0x4a008164, + .cm_ssc_deltamstep_dpll_per = 0x4a008168, + .cm_ssc_modfreqdiv_dpll_per = 0x4a00816c, + .cm_clkmode_dpll_usb = 0x4a008180, + .cm_idlest_dpll_usb = 0x4a008184, + .cm_autoidle_dpll_usb = 0x4a008188, + .cm_clksel_dpll_usb = 0x4a00818c, + .cm_div_m2_dpll_usb = 0x4a008190, + .cm_ssc_deltamstep_dpll_usb = 0x4a0081a8, + .cm_ssc_modfreqdiv_dpll_usb = 0x4a0081ac, + .cm_clkdcoldo_dpll_usb = 0x4a0081b4, + .cm_clkmode_dpll_pcie_ref = 0x4a008200, + .cm_clkmode_apll_pcie = 0x4a00821c, + .cm_idlest_apll_pcie = 0x4a008220, + .cm_div_m2_apll_pcie = 0x4a008224, + .cm_clkvcoldo_apll_pcie = 0x4a008228, + + /* cm2.core */ + .cm_l3_1_clkstctrl = 0x4a008700, + .cm_l3_1_dynamicdep = 0x4a008708, + .cm_l3_1_l3_1_clkctrl = 0x4a008720, + .cm_l3_gpmc_clkctrl = 0x4a008728, + .cm_mpu_m3_clkstctrl = 0x4a008900, + .cm_mpu_m3_staticdep = 0x4a008904, + .cm_mpu_m3_dynamicdep = 0x4a008908, + .cm_mpu_m3_mpu_m3_clkctrl = 0x4a008920, + .cm_sdma_clkstctrl = 0x4a008a00, + .cm_sdma_staticdep = 0x4a008a04, + .cm_sdma_dynamicdep = 0x4a008a08, + .cm_sdma_sdma_clkctrl = 0x4a008a20, + .cm_memif_clkstctrl = 0x4a008b00, + .cm_memif_dmm_clkctrl = 0x4a008b20, + .cm_memif_emif_fw_clkctrl = 0x4a008b28, + .cm_memif_emif_1_clkctrl = 0x4a008b30, + .cm_memif_emif_2_clkctrl = 0x4a008b38, + .cm_memif_dll_clkctrl = 0x4a008b40, + .cm_l4cfg_clkstctrl = 0x4a008d00, + .cm_l4cfg_dynamicdep = 0x4a008d08, + .cm_l4cfg_l4_cfg_clkctrl = 0x4a008d20, + .cm_l4cfg_hw_sem_clkctrl = 0x4a008d28, + .cm_l4cfg_mailbox_clkctrl = 0x4a008d30, + .cm_l4cfg_sar_rom_clkctrl = 0x4a008d38, + .cm_l3instr_clkstctrl = 0x4a008e00, + .cm_l3instr_l3_3_clkctrl = 0x4a008e20, + .cm_l3instr_l3_instr_clkctrl = 0x4a008e28, + .cm_l3instr_intrconn_wp1_clkctrl = 0x4a008e40, + + /* cm2.ivahd */ + .cm_ivahd_clkstctrl = 0x4a008f00, + .cm_ivahd_ivahd_clkctrl = 0x4a008f20, + .cm_ivahd_sl2_clkctrl = 0x4a008f28, + + /* cm2.cam */ + .cm_cam_clkstctrl = 0x4a009000, + .cm_cam_vip1_clkctrl = 0x4a009020, + .cm_cam_vip2_clkctrl = 0x4a009028, + .cm_cam_vip3_clkctrl = 0x4a009030, + .cm_cam_lvdsrx_clkctrl = 0x4a009038, + .cm_cam_csi1_clkctrl = 0x4a009040, + .cm_cam_csi2_clkctrl = 0x4a009048, + + /* cm2.dss */ + .cm_dss_clkstctrl = 0x4a009100, + .cm_dss_dss_clkctrl = 0x4a009120, + + /* cm2.sgx */ + .cm_sgx_clkstctrl = 0x4a009200, + .cm_sgx_sgx_clkctrl = 0x4a009220, + + /* cm2.l3init */ + .cm_l3init_clkstctrl = 0x4a009300, + + /* cm2.l3init */ + .cm_l3init_hsmmc1_clkctrl = 0x4a009328, + .cm_l3init_hsmmc2_clkctrl = 0x4a009330, + .cm_l3init_hsusbhost_clkctrl = 0x4a009340, + .cm_l3init_hsusbotg_clkctrl = 0x4a009348, + .cm_l3init_hsusbtll_clkctrl = 0x4a009350, + .cm_l3init_sata_clkctrl = 0x4a009388, + .cm_gmac_clkstctrl = 0x4a0093c0, + .cm_gmac_gmac_clkctrl = 0x4a0093d0, + .cm_l3init_ocp2scp1_clkctrl = 0x4a0093e0, + .cm_l3init_ocp2scp3_clkctrl = 0x4a0093e8, + .cm_l3init_usb_otg_ss_clkctrl = 0x4a0093f0, + + /* cm2.l4per */ + .cm_l4per_clkstctrl = 0x4a009700, + .cm_l4per_dynamicdep = 0x4a009708, + .cm_l4per_gptimer10_clkctrl = 0x4a009728, + .cm_l4per_gptimer11_clkctrl = 0x4a009730, + .cm_l4per_gptimer2_clkctrl = 0x4a009738, + .cm_l4per_gptimer3_clkctrl = 0x4a009740, + .cm_l4per_gptimer4_clkctrl = 0x4a009748, + .cm_l4per_gptimer9_clkctrl = 0x4a009750, + .cm_l4per_elm_clkctrl = 0x4a009758, + .cm_l4per_gpio2_clkctrl = 0x4a009760, + .cm_l4per_gpio3_clkctrl = 0x4a009768, + .cm_l4per_gpio4_clkctrl = 0x4a009770, + .cm_l4per_gpio5_clkctrl = 0x4a009778, + .cm_l4per_gpio6_clkctrl = 0x4a009780, + .cm_l4per_hdq1w_clkctrl = 0x4a009788, + .cm_l4per_i2c1_clkctrl = 0x4a0097a0, + .cm_l4per_i2c2_clkctrl = 0x4a0097a8, + .cm_l4per_i2c3_clkctrl = 0x4a0097b0, + .cm_l4per_i2c4_clkctrl = 0x4a0097b8, + .cm_l4per_l4per_clkctrl = 0x4a0097c0, + .cm_l4per_mcspi1_clkctrl = 0x4a0097f0, + .cm_l4per_mcspi2_clkctrl = 0x4a0097f8, + .cm_l4per_mcspi3_clkctrl = 0x4a009800, + .cm_l4per_mcspi4_clkctrl = 0x4a009808, + .cm_l4per_gpio7_clkctrl = 0x4a009810, + .cm_l4per_gpio8_clkctrl = 0x4a009818, + .cm_l4per_mmcsd3_clkctrl = 0x4a009820, + .cm_l4per_mmcsd4_clkctrl = 0x4a009828, + .cm_l4per_qspi_clkctrl = 0x4a009838, + .cm_l4per_uart1_clkctrl = 0x4a009840, + .cm_l4per_uart2_clkctrl = 0x4a009848, + .cm_l4per_uart3_clkctrl = 0x4a009850, + .cm_l4per_uart4_clkctrl = 0x4a009858, + .cm_l4per_uart5_clkctrl = 0x4a009870, + .cm_l4sec_clkstctrl = 0x4a009880, + .cm_l4sec_staticdep = 0x4a009884, + .cm_l4sec_dynamicdep = 0x4a009888, + .cm_l4sec_aes1_clkctrl = 0x4a0098a0, + .cm_l4sec_aes2_clkctrl = 0x4a0098a8, + .cm_l4sec_des3des_clkctrl = 0x4a0098b0, + .cm_l4sec_rng_clkctrl = 0x4a0098c0, + .cm_l4sec_sha2md51_clkctrl = 0x4a0098c8, + .cm_l4sec_cryptodma_clkctrl = 0x4a0098d8, + + /* l4 wkup regs */ + .cm_abe_pll_ref_clksel = 0x4ae0610c, + .cm_sys_clksel = 0x4ae06110, + .cm_abe_pll_sys_clksel = 0x4ae06118, + .cm_wkup_clkstctrl = 0x4ae07800, + .cm_wkup_l4wkup_clkctrl = 0x4ae07820, + .cm_wkup_wdtimer1_clkctrl = 0x4ae07828, + .cm_wkup_wdtimer2_clkctrl = 0x4ae07830, + .cm_wkup_gpio1_clkctrl = 0x4ae07838, + .cm_wkup_gptimer1_clkctrl = 0x4ae07840, + .cm_wkup_gptimer12_clkctrl = 0x4ae07848, + .cm_wkup_sarram_clkctrl = 0x4ae07860, + .cm_wkup_keyboard_clkctrl = 0x4ae07878, + .cm_wkupaon_scrm_clkctrl = 0x4ae07890, + .prm_rstctrl = 0x4ae07d00, + .prm_rstst = 0x4ae07d04, + .prm_rsttime = 0x4ae07d08, + .prm_vc_val_bypass = 0x4ae07da0, + .prm_vc_cfg_i2c_mode = 0x4ae07db4, + .prm_vc_cfg_i2c_clk = 0x4ae07db8, + + .prm_abbldo_mpu_setup = 0x4AE07DDC, + .prm_abbldo_mpu_ctrl = 0x4AE07DE0, +};
diff --git a/u-boot-imx/arch/arm/cpu/armv7/omap5/sdram.c b/u-boot-imx/arch/arm/cpu/armv7/omap5/sdram.c new file mode 100644 index 0000000..5f8daa1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/omap5/sdram.c
@@ -0,0 +1,736 @@ +/* + * Timing and Organization details of the ddr device parts used in OMAP5 + * EVM + * + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * Sricharan R <r.sricharan@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/emif.h> +#include <asm/arch/sys_proto.h> + +/* + * This file provides details of the LPDDR2 SDRAM parts used on OMAP5 + * EVM. Since the parts used and geometry are identical for + * evm for a given OMAP5 revision, this information is kept + * here instead of being in board directory. However the key functions + * exported are weakly linked so that they can be over-ridden in the board + * directory if there is a OMAP5 board in the future that uses a different + * memory device or geometry. + * + * For any new board with different memory devices over-ride one or more + * of the following functions as per the CONFIG flags you intend to enable: + * - emif_get_reg_dump() + * - emif_get_dmm_regs() + * - emif_get_device_details() + * - emif_get_device_timings() + */ + +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS +const struct emif_regs emif_regs_532_mhz_2cs = { + .sdram_config_init = 0x80800EBA, + .sdram_config = 0x808022BA, + .ref_ctrl = 0x0000081A, + .sdram_tim1 = 0x772F6873, + .sdram_tim2 = 0x304a129a, + .sdram_tim3 = 0x02f7e45f, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x000b3215, + .temp_alert_config = 0x08000a05, + .emif_ddr_phy_ctlr_1_init = 0x0E28420d, + .emif_ddr_phy_ctlr_1 = 0x0E28420d, + .emif_ddr_ext_phy_ctrl_1 = 0x04020080, + .emif_ddr_ext_phy_ctrl_2 = 0x28C518A3, + .emif_ddr_ext_phy_ctrl_3 = 0x518A3146, + .emif_ddr_ext_phy_ctrl_4 = 0x0014628C, + .emif_ddr_ext_phy_ctrl_5 = 0x04010040 +}; + +const struct emif_regs emif_regs_532_mhz_2cs_es2 = { + .sdram_config_init = 0x80800EBA, + .sdram_config = 0x808022BA, + .ref_ctrl = 0x0000081A, + .sdram_tim1 = 0x772F6873, + .sdram_tim2 = 0x304a129a, + .sdram_tim3 = 0x02f7e45f, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x100b3215, + .temp_alert_config = 0x08000a05, + .emif_ddr_phy_ctlr_1_init = 0x0E30400d, + .emif_ddr_phy_ctlr_1 = 0x0E30400d, + .emif_ddr_ext_phy_ctrl_1 = 0x04020080, + .emif_ddr_ext_phy_ctrl_2 = 0x28C518A3, + .emif_ddr_ext_phy_ctrl_3 = 0x518A3146, + .emif_ddr_ext_phy_ctrl_4 = 0x0014628C, + .emif_ddr_ext_phy_ctrl_5 = 0xC330CC33, +}; + +const struct emif_regs emif_regs_266_mhz_2cs = { + .sdram_config_init = 0x80800EBA, + .sdram_config = 0x808022BA, + .ref_ctrl = 0x0000040D, + .sdram_tim1 = 0x2A86B419, + .sdram_tim2 = 0x1025094A, + .sdram_tim3 = 0x026BA22F, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x000b3215, + .temp_alert_config = 0x08000a05, + .emif_ddr_phy_ctlr_1_init = 0x0E28420d, + .emif_ddr_phy_ctlr_1 = 0x0E28420d, + .emif_ddr_ext_phy_ctrl_1 = 0x04020080, + .emif_ddr_ext_phy_ctrl_2 = 0x0A414829, + .emif_ddr_ext_phy_ctrl_3 = 0x14829052, + .emif_ddr_ext_phy_ctrl_4 = 0x000520A4, + .emif_ddr_ext_phy_ctrl_5 = 0x04010040 +}; + +const struct emif_regs emif_regs_ddr3_532_mhz_1cs = { + .sdram_config_init = 0x61851B32, + .sdram_config = 0x61851B32, + .sdram_config2 = 0x0, + .ref_ctrl = 0x00001035, + .sdram_tim1 = 0xCCCF36B3, + .sdram_tim2 = 0x308F7FDA, + .sdram_tim3 = 0x027F88A8, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x0007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0020420A, + .emif_ddr_phy_ctlr_1 = 0x0024420A, + .emif_ddr_ext_phy_ctrl_1 = 0x04040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00000000, + .emif_ddr_ext_phy_ctrl_3 = 0x00000000, + .emif_ddr_ext_phy_ctrl_4 = 0x00000000, + .emif_ddr_ext_phy_ctrl_5 = 0x04010040, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x80000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x00000305 +}; + +const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = { + .sdram_config_init = 0x61851B32, + .sdram_config = 0x61851B32, + .sdram_config2 = 0x0, + .ref_ctrl = 0x00001035, + .sdram_tim1 = 0xCCCF36B3, + .sdram_tim2 = 0x308F7FDA, + .sdram_tim3 = 0x027F88A8, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x1007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0030400A, + .emif_ddr_phy_ctlr_1 = 0x0034400A, + .emif_ddr_ext_phy_ctrl_1 = 0x04040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00000000, + .emif_ddr_ext_phy_ctrl_3 = 0x00000000, + .emif_ddr_ext_phy_ctrl_4 = 0x00000000, + .emif_ddr_ext_phy_ctrl_5 = 0x4350D435, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x80000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x40000305 +}; + +const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = { + .sdram_config_init = 0x61851ab2, + .sdram_config = 0x61851ab2, + .sdram_config2 = 0x08000000, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, + .sdram_tim1 = 0xCCCF36B3, + .sdram_tim2 = 0x308F7FDA, + .sdram_tim3 = 0x027F88A8, + .read_idle_ctrl = 0x00050001, + .zq_config = 0x0007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0E24400A, + .emif_ddr_phy_ctlr_1 = 0x0E24400A, + .emif_ddr_ext_phy_ctrl_1 = 0x10040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00910091, + .emif_ddr_ext_phy_ctrl_3 = 0x00950095, + .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, + .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x00000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x00000305 +}; + +const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = { + .sdram_config_init = 0x61851B32, + .sdram_config = 0x61851B32, + .sdram_config2 = 0x08000000, + .ref_ctrl = 0x000040F1, + .ref_ctrl_final = 0x00001035, + .sdram_tim1 = 0xCCCF36B3, + .sdram_tim2 = 0x308F7FDA, + .sdram_tim3 = 0x027F88A8, + .read_idle_ctrl = 0x00050001, + .zq_config = 0x0007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0E24400A, + .emif_ddr_phy_ctlr_1 = 0x0E24400A, + .emif_ddr_ext_phy_ctrl_1 = 0x10040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00910091, + .emif_ddr_ext_phy_ctrl_3 = 0x00950095, + .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, + .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x00000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x00000305 +}; + +const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = { + .sdram_config_init = 0x61862B32, + .sdram_config = 0x61862B32, + .sdram_config2 = 0x08000000, + .ref_ctrl = 0x0000493E, + .ref_ctrl_final = 0x0000144A, + .sdram_tim1 = 0xD113781C, + .sdram_tim2 = 0x308F7FE3, + .sdram_tim3 = 0x009F86A8, + .read_idle_ctrl = 0x00050000, + .zq_config = 0x0007190B, + .temp_alert_config = 0x00000000, + .emif_ddr_phy_ctlr_1_init = 0x0E24400D, + .emif_ddr_phy_ctlr_1 = 0x0E24400D, + .emif_ddr_ext_phy_ctrl_1 = 0x10040100, + .emif_ddr_ext_phy_ctrl_2 = 0x00A400A4, + .emif_ddr_ext_phy_ctrl_3 = 0x00A900A9, + .emif_ddr_ext_phy_ctrl_4 = 0x00B000B0, + .emif_ddr_ext_phy_ctrl_5 = 0x00B000B0, + .emif_rd_wr_lvl_rmp_win = 0x00000000, + .emif_rd_wr_lvl_rmp_ctl = 0x00000000, + .emif_rd_wr_lvl_ctl = 0x00000000, + .emif_rd_wr_exec_thresh = 0x00000305 +}; + +const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80740300, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1 +}; + +/* + * DRA752 EVM board has 1.5 GB of memory + * EMIF1 --> 2Gb * 2 = 512MB + * EMIF2 --> 2Gb * 4 = 1GB + * so mapping 1GB interleaved and 512MB non-interleaved + */ +const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2_2G_x_1_x_2 = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x80640300, + .dmm_lisa_map_2 = 0xC0500220, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1 +}; + +/* + * DRA752 EVM EMIF1 ONLY CONFIGURATION + */ +const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80500100, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1 +}; + +/* + * DRA752 EVM EMIF2 ONLY CONFIGURATION + */ +const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80600200, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1 +}; + +/* + * DRA722 EVM EMIF1 CONFIGURATION + */ +const struct dmm_lisa_map_regs lisa_map_2G_x_2 = { + .dmm_lisa_map_0 = 0x0, + .dmm_lisa_map_1 = 0x0, + .dmm_lisa_map_2 = 0x80600100, + .dmm_lisa_map_3 = 0xFF020100, + .is_ma_present = 0x1 +}; + +static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) +{ + switch (omap_revision()) { + case OMAP5430_ES1_0: + *regs = &emif_regs_532_mhz_2cs; + break; + case OMAP5432_ES1_0: + *regs = &emif_regs_ddr3_532_mhz_1cs; + break; + case OMAP5430_ES2_0: + *regs = &emif_regs_532_mhz_2cs_es2; + break; + case OMAP5432_ES2_0: + *regs = &emif_regs_ddr3_532_mhz_1cs_es2; + break; + case DRA752_ES1_0: + case DRA752_ES1_1: + switch (emif_nr) { + case 1: + *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1; + break; + case 2: + *regs = &emif_2_regs_ddr3_532_mhz_1cs_dra_es1; + break; + } + break; + case DRA722_ES1_0: + *regs = &emif_1_regs_ddr3_666_mhz_1cs_dra_es1; + break; + default: + *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1; + } +} + +void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs) + __attribute__((weak, alias("emif_get_reg_dump_sdp"))); + +static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs + **dmm_lisa_regs) +{ + switch (omap_revision()) { + case OMAP5430_ES1_0: + case OMAP5430_ES2_0: + case OMAP5432_ES1_0: + case OMAP5432_ES2_0: + *dmm_lisa_regs = &lisa_map_4G_x_2_x_2; + break; + case DRA752_ES1_0: + case DRA752_ES1_1: + *dmm_lisa_regs = &lisa_map_2G_x_2_x_2_2G_x_1_x_2; + break; + case DRA722_ES1_0: + default: + *dmm_lisa_regs = &lisa_map_2G_x_2; + } + +} + +void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) + __attribute__((weak, alias("emif_get_dmm_regs_sdp"))); +#else + +static const struct lpddr2_device_details dev_4G_S4_details = { + .type = LPDDR2_TYPE_S4, + .density = LPDDR2_DENSITY_4Gb, + .io_width = LPDDR2_IO_WIDTH_32, + .manufacturer = LPDDR2_MANUFACTURER_SAMSUNG +}; + +static void emif_get_device_details_sdp(u32 emif_nr, + struct lpddr2_device_details *cs0_device_details, + struct lpddr2_device_details *cs1_device_details) +{ + /* EMIF1 & EMIF2 have identical configuration */ + *cs0_device_details = dev_4G_S4_details; + *cs1_device_details = dev_4G_S4_details; +} + +void emif_get_device_details(u32 emif_nr, + struct lpddr2_device_details *cs0_device_details, + struct lpddr2_device_details *cs1_device_details) + __attribute__((weak, alias("emif_get_device_details_sdp"))); + +#endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ + +const u32 ext_phy_ctrl_const_base[] = { + 0x01004010, + 0x00001004, + 0x04010040, + 0x01004010, + 0x00001004, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80080080, + 0x00800800, + 0x08102040, + 0x00000001, + 0x540A8150, + 0xA81502a0, + 0x002A0540, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000077, + 0x0 +}; + +const u32 ddr3_ext_phy_ctrl_const_base_es1[] = { + 0x01004010, + 0x00001004, + 0x04010040, + 0x01004010, + 0x00001004, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80080080, + 0x00800800, + 0x08102040, + 0x00000002, + 0x0, + 0x0, + 0x0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000057, + 0x0 +}; + +const u32 ddr3_ext_phy_ctrl_const_base_es2[] = { + 0x50D4350D, + 0x00000D43, + 0x04010040, + 0x01004010, + 0x00001004, + 0x00000000, + 0x00000000, + 0x00000000, + 0x80080080, + 0x00800800, + 0x08102040, + 0x00000002, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000057, + 0x0 +}; + +const u32 +dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = { + 0x00980098, + 0x00340034, + 0x00350035, + 0x00340034, + 0x00310031, + 0x00340034, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x00480048, + 0x004A004A, + 0x00520052, + 0x00550055, + 0x00500050, + 0x00000000, + 0x00600020, + 0x40010080, + 0x08102040, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0 +}; + +const u32 +dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = { + 0x00980098, + 0x00330033, + 0x00330033, + 0x002F002F, + 0x00320032, + 0x00310031, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x007F007F, + 0x00520052, + 0x00520052, + 0x00470047, + 0x00490049, + 0x00500050, + 0x00000000, + 0x00600020, + 0x40010080, + 0x08102040, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0 +}; + +const u32 +dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = { + 0x00A400A4, + 0x00390039, + 0x00320032, + 0x00320032, + 0x00320032, + 0x00440044, + 0x00550055, + 0x00550055, + 0x00550055, + 0x00550055, + 0x007F007F, + 0x004D004D, + 0x00430043, + 0x00560056, + 0x00540054, + 0x00600060, + 0x0, + 0x00600020, + 0x40010080, + 0x08102040, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0 +}; + +const struct lpddr2_mr_regs mr_regs = { + .mr1 = MR1_BL_8_BT_SEQ_WRAP_EN_NWR_8, + .mr2 = 0x6, + .mr3 = 0x1, + .mr10 = MR10_ZQ_ZQINIT, + .mr16 = MR16_REF_FULL_ARRAY +}; + +void __weak emif_get_ext_phy_ctrl_const_regs(u32 emif_nr, + const u32 **regs, + u32 *size) +{ + switch (omap_revision()) { + case OMAP5430_ES1_0: + case OMAP5430_ES2_0: + *regs = ext_phy_ctrl_const_base; + *size = ARRAY_SIZE(ext_phy_ctrl_const_base); + break; + case OMAP5432_ES1_0: + *regs = ddr3_ext_phy_ctrl_const_base_es1; + *size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es1); + break; + case OMAP5432_ES2_0: + *regs = ddr3_ext_phy_ctrl_const_base_es2; + *size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2); + break; + case DRA752_ES1_0: + case DRA752_ES1_1: + if (emif_nr == 1) { + *regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif1; + *size = + ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif1); + } else { + *regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif2; + *size = + ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif2); + } + break; + case DRA722_ES1_0: + *regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz; + *size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz); + break; + default: + *regs = ddr3_ext_phy_ctrl_const_base_es2; + *size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2); + + } +} + +void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs) +{ + *regs = &mr_regs; +} + +void do_ext_phy_settings(u32 base, const struct emif_regs *regs) +{ + u32 *ext_phy_ctrl_base = 0; + u32 *emif_ext_phy_ctrl_base = 0; + u32 emif_nr; + const u32 *ext_phy_ctrl_const_regs; + u32 i = 0; + u32 size; + + emif_nr = (base == EMIF1_BASE) ? 1 : 2; + + struct emif_reg_struct *emif = (struct emif_reg_struct *)base; + + ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1); + emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1); + + /* Configure external phy control timing registers */ + for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) { + writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++); + } + + /* + * external phy 6-24 registers do not change with + * ddr frequency + */ + emif_get_ext_phy_ctrl_const_regs(emif_nr, + &ext_phy_ctrl_const_regs, &size); + + for (i = 0; i < size; i++) { + writel(ext_phy_ctrl_const_regs[i], + emif_ext_phy_ctrl_base++); + /* Update shadow registers */ + writel(ext_phy_ctrl_const_regs[i], + emif_ext_phy_ctrl_base++); + } +} + +#ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +static const struct lpddr2_ac_timings timings_jedec_532_mhz = { + .max_freq = 532000000, + .RL = 8, + .tRPab = 21, + .tRCD = 18, + .tWR = 15, + .tRASmin = 42, + .tRRD = 10, + .tWTRx2 = 15, + .tXSR = 140, + .tXPx2 = 15, + .tRFCab = 130, + .tRTPx2 = 15, + .tCKE = 3, + .tCKESR = 15, + .tZQCS = 90, + .tZQCL = 360, + .tZQINIT = 1000, + .tDQSCKMAXx2 = 11, + .tRASmax = 70, + .tFAW = 50 +}; + +static const struct lpddr2_min_tck min_tck = { + .tRL = 3, + .tRP_AB = 3, + .tRCD = 3, + .tWR = 3, + .tRAS_MIN = 3, + .tRRD = 2, + .tWTR = 2, + .tXP = 2, + .tRTP = 2, + .tCKE = 3, + .tCKESR = 3, + .tFAW = 8 +}; + +static const struct lpddr2_ac_timings *ac_timings[MAX_NUM_SPEEDBINS] = { + &timings_jedec_532_mhz +}; + +static const struct lpddr2_device_timings dev_4G_S4_timings = { + .ac_timings = ac_timings, + .min_tck = &min_tck, +}; + +/* + * List of status registers to be controlled back to control registers + * after initial leveling + * readreg, writereg + */ +const struct read_write_regs omap5_bug_00339_regs[] = { + { 8, 5 }, + { 9, 6 }, + { 10, 7 }, + { 14, 8 }, + { 15, 9 }, + { 16, 10 }, + { 11, 2 }, + { 12, 3 }, + { 13, 4 }, + { 17, 11 }, + { 18, 12 }, + { 19, 13 }, +}; + +const struct read_write_regs dra_bug_00339_regs[] = { + { 7, 7 }, + { 8, 8 }, + { 9, 9 }, + { 10, 10 }, + { 11, 11 }, + { 12, 2 }, + { 13, 3 }, + { 14, 4 }, + { 15, 5 }, + { 16, 6 }, + { 17, 12 }, + { 18, 13 }, + { 19, 14 }, + { 20, 15 }, + { 21, 16 }, + { 22, 17 }, + { 23, 18 }, + { 24, 19 }, + { 25, 20 }, + { 26, 21} +}; + +const struct read_write_regs *get_bug_regs(u32 *iterations) +{ + const struct read_write_regs *bug_00339_regs_ptr = NULL; + + switch (omap_revision()) { + case OMAP5430_ES1_0: + case OMAP5430_ES2_0: + case OMAP5432_ES1_0: + case OMAP5432_ES2_0: + bug_00339_regs_ptr = omap5_bug_00339_regs; + *iterations = sizeof(omap5_bug_00339_regs)/ + sizeof(omap5_bug_00339_regs[0]); + break; + case DRA752_ES1_0: + case DRA752_ES1_1: + case DRA722_ES1_0: + bug_00339_regs_ptr = dra_bug_00339_regs; + *iterations = sizeof(dra_bug_00339_regs)/ + sizeof(dra_bug_00339_regs[0]); + break; + default: + printf("\n Error: UnKnown SOC"); + } + + return bug_00339_regs_ptr; +} + +void emif_get_device_timings_sdp(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) +{ + /* Identical devices on EMIF1 & EMIF2 */ + *cs0_device_timings = &dev_4G_S4_timings; + *cs1_device_timings = &dev_4G_S4_timings; +} + +void emif_get_device_timings(u32 emif_nr, + const struct lpddr2_device_timings **cs0_device_timings, + const struct lpddr2_device_timings **cs1_device_timings) + __attribute__((weak, alias("emif_get_device_timings_sdp"))); + +#endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/psci.S b/u-boot-imx/arch/arm/cpu/armv7/psci.S new file mode 100644 index 0000000..bf11a34 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/psci.S
@@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013,2014 - ARM Ltd + * Author: Marc Zyngier <marc.zyngier@arm.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 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, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <linux/linkage.h> +#include <asm/psci.h> + + .pushsection ._secure.text, "ax" + + .arch_extension sec + + .align 5 + .globl _psci_vectors +_psci_vectors: + b default_psci_vector @ reset + b default_psci_vector @ undef + b _smc_psci @ smc + b default_psci_vector @ pabort + b default_psci_vector @ dabort + b default_psci_vector @ hyp + b default_psci_vector @ irq + b psci_fiq_enter @ fiq + +ENTRY(psci_fiq_enter) + movs pc, lr +ENDPROC(psci_fiq_enter) +.weak psci_fiq_enter + +ENTRY(default_psci_vector) + movs pc, lr +ENDPROC(default_psci_vector) +.weak default_psci_vector + +ENTRY(psci_cpu_suspend) +ENTRY(psci_cpu_off) +ENTRY(psci_cpu_on) +ENTRY(psci_migrate) + mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) + mov pc, lr +ENDPROC(psci_migrate) +ENDPROC(psci_cpu_on) +ENDPROC(psci_cpu_off) +ENDPROC(psci_cpu_suspend) +.weak psci_cpu_suspend +.weak psci_cpu_off +.weak psci_cpu_on +.weak psci_migrate + +_psci_table: + .word ARM_PSCI_FN_CPU_SUSPEND + .word psci_cpu_suspend + .word ARM_PSCI_FN_CPU_OFF + .word psci_cpu_off + .word ARM_PSCI_FN_CPU_ON + .word psci_cpu_on + .word ARM_PSCI_FN_MIGRATE + .word psci_migrate + .word 0 + .word 0 + +_smc_psci: + push {r4-r7,lr} + + @ Switch to secure + mrc p15, 0, r7, c1, c1, 0 + bic r4, r7, #1 + mcr p15, 0, r4, c1, c1, 0 + isb + + adr r4, _psci_table +1: ldr r5, [r4] @ Load PSCI function ID + ldr r6, [r4, #4] @ Load target PC + cmp r5, #0 @ If reach the end, bail out + moveq r0, #ARM_PSCI_RET_INVAL @ Return -2 (Invalid) + beq 2f + cmp r0, r5 @ If not matching, try next entry + addne r4, r4, #8 + bne 1b + + blx r6 @ Execute PSCI function + + @ Switch back to non-secure +2: mcr p15, 0, r7, c1, c1, 0 + + pop {r4-r7, lr} + movs pc, lr @ Return to the kernel + + .popsection
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/rmobile/Kconfig new file mode 100644 index 0000000..2b333a3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/Kconfig
@@ -0,0 +1,49 @@ +if RMOBILE + +choice + prompt "Renesus ARM SoCs board select" + +config TARGET_ARMADILLO_800EVA + bool "armadillo 800 eva board" + +config TARGET_GOSE + bool "Gose board" + +config TARGET_KOELSCH + bool "Koelsch board" + +config TARGET_LAGER + bool "Lager board" + +config TARGET_KZM9G + bool "KZM9D board" + +config TARGET_ALT + bool "Alt board" + +config TARGET_SILK + bool "Silk board" + +config TARGET_PORTER + bool "Porter board" + +endchoice + +config SYS_SOC + default "rmobile" + +config RMOBILE_EXTRAM_BOOT + bool "Enable boot from RAM" + depends on TARGET_ALT || TARGET_KOELSCH || TARGET_LAGER || TARGET_PORTER || TARGET_SILK + default n + +source "board/atmark-techno/armadillo-800eva/Kconfig" +source "board/renesas/gose/Kconfig" +source "board/renesas/koelsch/Kconfig" +source "board/renesas/lager/Kconfig" +source "board/kmc/kzm9g/Kconfig" +source "board/renesas/alt/Kconfig" +source "board/renesas/silk/Kconfig" +source "board/renesas/porter/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/Makefile b/u-boot-imx/arch/arm/cpu/armv7/rmobile/Makefile new file mode 100644 index 0000000..647e426 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/Makefile
@@ -0,0 +1,19 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu_info.o +obj-y += emac.o + +obj-$(CONFIG_DISPLAY_BOARDINFO) += board.o +obj-$(CONFIG_GLOBAL_TIMER) += timer.o +obj-$(CONFIG_R8A7740) += lowlevel_init.o cpu_info-r8a7740.o pfc-r8a7740.o +obj-$(CONFIG_R8A7790) += lowlevel_init_ca15.o cpu_info-rcar.o pfc-r8a7790.o +obj-$(CONFIG_R8A7791) += lowlevel_init_ca15.o cpu_info-rcar.o pfc-r8a7791.o +obj-$(CONFIG_R8A7793) += lowlevel_init_ca15.o cpu_info-rcar.o pfc-r8a7793.o +obj-$(CONFIG_R8A7794) += lowlevel_init_ca15.o cpu_info-rcar.o pfc-r8a7794.o +obj-$(CONFIG_SH73A0) += lowlevel_init.o cpu_info-sh73a0.o pfc-sh73a0.o +obj-$(CONFIG_TMU_TIMER) += ../../../../sh/lib/time.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/board.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/board.c new file mode 100644 index 0000000..d91bc26 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/board.c
@@ -0,0 +1,15 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> + +int checkboard(void) +{ + printf("Board: %s\n", sysinfo.board_string); + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-r8a7740.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-r8a7740.c new file mode 100644 index 0000000..dfe8950 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-r8a7740.c
@@ -0,0 +1,32 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> + +u32 rmobile_get_cpu_type(void) +{ + u32 id; + u32 type; + struct r8a7740_hpb *hpb = (struct r8a7740_hpb *)HPB_BASE; + + id = readl(hpb->cccr); + type = (id >> 8) & 0xFF; + + return type; +} + +u32 rmobile_get_cpu_rev(void) +{ + u32 id; + u32 rev; + struct r8a7740_hpb *hpb = (struct r8a7740_hpb *)HPB_BASE; + + id = readl(hpb->cccr); + rev = (id >> 4) & 0xF; + + return rev; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-rcar.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-rcar.c new file mode 100644 index 0000000..42ee30f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-rcar.c
@@ -0,0 +1,26 @@ +/* + * arch/arm/cpu/armv7/rmobile/cpu_info-rcar.c + * + * Copyright (C) 2013,2014 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ +#include <common.h> +#include <asm/io.h> + +#define PRR 0xFF000044 + +u32 rmobile_get_cpu_type(void) +{ + return (readl(PRR) & 0x00007F00) >> 8; +} + +u32 rmobile_get_cpu_rev_integer(void) +{ + return ((readl(PRR) & 0x000000F0) >> 4) + 1; +} + +u32 rmobile_get_cpu_rev_fraction(void) +{ + return readl(PRR) & 0x0000000F; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-sh73a0.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-sh73a0.c new file mode 100644 index 0000000..186b4b5 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info-sh73a0.c
@@ -0,0 +1,44 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> + +u32 rmobile_get_cpu_type(void) +{ + u32 id; + u32 type; + struct sh73a0_hpb *hpb = (struct sh73a0_hpb *)HPB_BASE; + + id = readl(&hpb->cccr); + type = (id >> 8) & 0xFF; + + return type; +} + +u32 rmobile_get_cpu_rev_integer(void) +{ + u32 id; + u32 rev; + struct sh73a0_hpb *hpb = (struct sh73a0_hpb *)HPB_BASE; + + id = readl(&hpb->cccr); + rev = ((id >> 4) & 0xF) + 1; + + return rev; +} + +u32 rmobile_get_cpu_rev_fraction(void) +{ + u32 id; + u32 rev; + struct sh73a0_hpb *hpb = (struct sh73a0_hpb *)HPB_BASE; + + id = readl(&hpb->cccr); + rev = id & 0xF; + + return rev; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info.c new file mode 100644 index 0000000..d47c47c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/cpu_info.c
@@ -0,0 +1,76 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + icache_enable(); + return 0; +} +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + dcache_enable(); +} +#endif + +#ifdef CONFIG_DISPLAY_CPUINFO +static u32 __rmobile_get_cpu_type(void) +{ + return 0x0; +} +u32 rmobile_get_cpu_type(void) + __attribute__((weak, alias("__rmobile_get_cpu_type"))); + +static u32 __rmobile_get_cpu_rev_integer(void) +{ + return 0; +} +u32 rmobile_get_cpu_rev_integer(void) + __attribute__((weak, alias("__rmobile_get_cpu_rev_integer"))); + +static u32 __rmobile_get_cpu_rev_fraction(void) +{ + return 0; +} +u32 rmobile_get_cpu_rev_fraction(void) + __attribute__((weak, alias("__rmobile_get_cpu_rev_fraction"))); + +/* CPU infomation table */ +static const struct { + u16 cpu_type; + u8 cpu_name[10]; +} rmobile_cpuinfo[] = { + { 0x37, "SH73A0" }, + { 0x40, "R8A7740" }, + { 0x45, "R8A7790" }, + { 0x47, "R8A7791" }, + { 0x4B, "R8A7793" }, + { 0x4C, "R8A7794" }, + { 0x0, "CPU" }, +}; + +int print_cpuinfo(void) +{ + int i = 0; + u32 cpu_type = rmobile_get_cpu_type(); + for (; i < ARRAY_SIZE(rmobile_cpuinfo); i++) { + if (rmobile_cpuinfo[i].cpu_type == cpu_type) { + printf("CPU: Renesas Electronics %s rev %d.%d\n", + rmobile_cpuinfo[i].cpu_name, + rmobile_get_cpu_rev_integer(), + rmobile_get_cpu_rev_fraction()); + break; + } + } + return 0; +} +#endif /* CONFIG_DISPLAY_CPUINFO */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/emac.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/emac.c new file mode 100644 index 0000000..0710cfd --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/emac.c
@@ -0,0 +1,21 @@ +/* + * RMOBILE EtherMAC initialization. + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <netdev.h> + +int cpu_eth_init(bd_t *bis) +{ + int ret = -ENODEV; +#ifdef CONFIG_SH_ETHER + ret = sh_eth_initialize(bis); +#endif + return ret; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init.S new file mode 100644 index 0000000..0d65440 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init.S
@@ -0,0 +1,72 @@ +/* + * Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.Iwamatsu.yj@renesas.com> + * Copyright (C) 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + ldr r0, =MERAM_BASE + mov r1, #0x0 + str r1, [r0] + + mrc p15, 0, r0, c0, c0, 5 + ands r0, r0, #0xF + beq lowlevel_init__ + b wait_interrupt + + .pool + .align 4 + +wait_interrupt: +#ifdef ICCICR + ldr r1, =ICCICR + mov r2, #0x0 + str r2, [r1] + mov r2, #0xF0 + adds r1, r1, #4 /* ICCPMR */ + str r2, [r1] + ldr r1, =ICCICR + mov r2, #0x1 + str r2, [r1] +#endif + +wait_loop: + .long 0xE320F003 /* wfi */ + + ldr r2, [r1, #0xC] + str r2, [r1, #0x10] + + ldr r0, =MERAM_BASE + ldr r2, [r0] + cmp r2, #0 + movne pc, r2 + + b wait_loop + +wait_loop_end: + .pool + .align 4 + +lowlevel_init__: + + mov r0, #0x200000 + +loop0: + subs r0, r0, #1 + bne loop0 + + ldr sp, MERAM_STACK + b s_init + + .pool + .align 4 + +ENDPROC(lowlevel_init) + .ltorg + +MERAM_STACK: + .word LOW_LEVEL_MERAM_STACK
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S b/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S new file mode 100644 index 0000000..a5dbbea --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S
@@ -0,0 +1,89 @@ +/* + * arch/arm/cpu/armv7/rmobile/lowlevel_init_ca15.S + * This file is lager low level initialize. + * + * Copyright (C) 2013, 2014 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + mrc p15, 0, r4, c0, c0, 5 /* mpidr */ + orr r4, r4, r4, lsr #6 + and r4, r4, #7 /* id 0-3 = ca15.0,1,2,3 */ + + b do_lowlevel_init + + .pool + +/* + * CPU ID #1-#3 come here + */ + .align 4 +do_cpu_waiting: + ldr r1, =0xe6180000 /* sysc */ +1: ldr r0, [r1, #0x20] /* sbar */ + tst r0, r0 + beq 1b + bx r0 + +/* + * Only CPU ID #0 comes here + */ + .align 4 +do_lowlevel_init: + ldr r2, =0xFF000044 /* PRR */ + ldr r1, [r2] + and r1, r1, #0x7F00 + lsrs r1, r1, #8 + cmp r1, #0x4C /* 0x4C is ID of r8a7794 */ + beq _enable_actlr_smp + + /* surpress wfe if ca15 */ + tst r4, #4 + mrceq p15, 0, r0, c1, c0, 1 /* actlr */ + orreq r0, r0, #(1<<7) + mcreq p15, 0, r0, c1, c0, 1 + + /* and set l2 latency */ + mrc p15, 0, r0, c0, c0, 5 /* r0 = MPIDR */ + and r0, r0, #0xf00 + lsr r0, r0, #8 + tst r0, #1 /* only need for cluster 0 */ + bne _exit_init_l2_a15 + + mrc p15, 1, r0, c9, c0, 2 /* r0 = L2CTLR */ + and r1, r0, #7 + cmp r1, #3 /* has already been set up */ + bicne r0, r0, #0xe7 + orrne r0, r0, #0x83 /* L2CTLR[7:6] + L2CTLR[2:0] */ +#if defined(CONFIG_R8A7790) + orrne r0, r0, #0x20 /* L2CTLR[5] */ +#endif + mcrne p15, 1, r0, c9, c0, 2 + + b _exit_init_l2_a15 + +_enable_actlr_smp: /* R8A7794 only (CA7) */ +#ifndef CONFIG_DCACHE_OFF + mrc p15, 0, r0, c1, c0, 1 + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 +#endif + +_exit_init_l2_a15: + ldr r3, =(CONFIG_SYS_INIT_SP_ADDR) + sub sp, r3, #4 + str lr, [sp] + + /* initialize system */ + bl s_init + + ldr lr, [sp] + mov pc, lr + nop +ENDPROC(lowlevel_init) + .ltorg
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7740.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7740.c new file mode 100644 index 0000000..5d42a68 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7740.c
@@ -0,0 +1,2612 @@ +/* + * R8A7740 processor support + * + * Copyright (C) 2011 Renesas Solutions Corp. + * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <common.h> +#include <sh_pfc.h> +#include <asm/gpio.h> +#include <asm/arch/irqs.h> + +#define CPU_ALL_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \ + PORT_10(fn, pfx##10, sfx), PORT_90(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##20, sfx), \ + PORT_1(fn, pfx##210, sfx), PORT_1(fn, pfx##211, sfx) + +enum { + PINMUX_RESERVED = 0, + + /* PORT0_DATA -> PORT211_DATA */ + PINMUX_DATA_BEGIN, + PORT_ALL(DATA), + PINMUX_DATA_END, + + /* PORT0_IN -> PORT211_IN */ + PINMUX_INPUT_BEGIN, + PORT_ALL(IN), + PINMUX_INPUT_END, + + /* PORT0_IN_PU -> PORT211_IN_PU */ + PINMUX_INPUT_PULLUP_BEGIN, + PORT_ALL(IN_PU), + PINMUX_INPUT_PULLUP_END, + + /* PORT0_IN_PD -> PORT211_IN_PD */ + PINMUX_INPUT_PULLDOWN_BEGIN, + PORT_ALL(IN_PD), + PINMUX_INPUT_PULLDOWN_END, + + /* PORT0_OUT -> PORT211_OUT */ + PINMUX_OUTPUT_BEGIN, + PORT_ALL(OUT), + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT211_FN_IN */ + PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT211_FN_OUT */ + PORT_ALL(FN0), /* PORT0_FN0 -> PORT211_FN0 */ + PORT_ALL(FN1), /* PORT0_FN1 -> PORT211_FN1 */ + PORT_ALL(FN2), /* PORT0_FN2 -> PORT211_FN2 */ + PORT_ALL(FN3), /* PORT0_FN3 -> PORT211_FN3 */ + PORT_ALL(FN4), /* PORT0_FN4 -> PORT211_FN4 */ + PORT_ALL(FN5), /* PORT0_FN5 -> PORT211_FN5 */ + PORT_ALL(FN6), /* PORT0_FN6 -> PORT211_FN6 */ + PORT_ALL(FN7), /* PORT0_FN7 -> PORT211_FN7 */ + + MSEL1CR_31_0, MSEL1CR_31_1, + MSEL1CR_30_0, MSEL1CR_30_1, + MSEL1CR_29_0, MSEL1CR_29_1, + MSEL1CR_28_0, MSEL1CR_28_1, + MSEL1CR_27_0, MSEL1CR_27_1, + MSEL1CR_26_0, MSEL1CR_26_1, + MSEL1CR_16_0, MSEL1CR_16_1, + MSEL1CR_15_0, MSEL1CR_15_1, + MSEL1CR_14_0, MSEL1CR_14_1, + MSEL1CR_13_0, MSEL1CR_13_1, + MSEL1CR_12_0, MSEL1CR_12_1, + MSEL1CR_9_0, MSEL1CR_9_1, + MSEL1CR_7_0, MSEL1CR_7_1, + MSEL1CR_6_0, MSEL1CR_6_1, + MSEL1CR_5_0, MSEL1CR_5_1, + MSEL1CR_4_0, MSEL1CR_4_1, + MSEL1CR_3_0, MSEL1CR_3_1, + MSEL1CR_2_0, MSEL1CR_2_1, + MSEL1CR_0_0, MSEL1CR_0_1, + + MSEL3CR_15_0, MSEL3CR_15_1, /* Trace / Debug ? */ + MSEL3CR_6_0, MSEL3CR_6_1, + + MSEL4CR_19_0, MSEL4CR_19_1, + MSEL4CR_18_0, MSEL4CR_18_1, + MSEL4CR_15_0, MSEL4CR_15_1, + MSEL4CR_10_0, MSEL4CR_10_1, + MSEL4CR_6_0, MSEL4CR_6_1, + MSEL4CR_4_0, MSEL4CR_4_1, + MSEL4CR_1_0, MSEL4CR_1_1, + + MSEL5CR_31_0, MSEL5CR_31_1, /* irq/fiq output */ + MSEL5CR_30_0, MSEL5CR_30_1, + MSEL5CR_29_0, MSEL5CR_29_1, + MSEL5CR_27_0, MSEL5CR_27_1, + MSEL5CR_25_0, MSEL5CR_25_1, + MSEL5CR_23_0, MSEL5CR_23_1, + MSEL5CR_21_0, MSEL5CR_21_1, + MSEL5CR_19_0, MSEL5CR_19_1, + MSEL5CR_17_0, MSEL5CR_17_1, + MSEL5CR_15_0, MSEL5CR_15_1, + MSEL5CR_14_0, MSEL5CR_14_1, + MSEL5CR_13_0, MSEL5CR_13_1, + MSEL5CR_12_0, MSEL5CR_12_1, + MSEL5CR_11_0, MSEL5CR_11_1, + MSEL5CR_10_0, MSEL5CR_10_1, + MSEL5CR_8_0, MSEL5CR_8_1, + MSEL5CR_7_0, MSEL5CR_7_1, + MSEL5CR_6_0, MSEL5CR_6_1, + MSEL5CR_5_0, MSEL5CR_5_1, + MSEL5CR_4_0, MSEL5CR_4_1, + MSEL5CR_3_0, MSEL5CR_3_1, + MSEL5CR_2_0, MSEL5CR_2_1, + MSEL5CR_0_0, MSEL5CR_0_1, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + + /* IRQ */ + IRQ0_PORT2_MARK, IRQ0_PORT13_MARK, + IRQ1_MARK, + IRQ2_PORT11_MARK, IRQ2_PORT12_MARK, + IRQ3_PORT10_MARK, IRQ3_PORT14_MARK, + IRQ4_PORT15_MARK, IRQ4_PORT172_MARK, + IRQ5_PORT0_MARK, IRQ5_PORT1_MARK, + IRQ6_PORT121_MARK, IRQ6_PORT173_MARK, + IRQ7_PORT120_MARK, IRQ7_PORT209_MARK, + IRQ8_MARK, + IRQ9_PORT118_MARK, IRQ9_PORT210_MARK, + IRQ10_MARK, + IRQ11_MARK, + IRQ12_PORT42_MARK, IRQ12_PORT97_MARK, + IRQ13_PORT64_MARK, IRQ13_PORT98_MARK, + IRQ14_PORT63_MARK, IRQ14_PORT99_MARK, + IRQ15_PORT62_MARK, IRQ15_PORT100_MARK, + IRQ16_PORT68_MARK, IRQ16_PORT211_MARK, + IRQ17_MARK, + IRQ18_MARK, + IRQ19_MARK, + IRQ20_MARK, + IRQ21_MARK, + IRQ22_MARK, + IRQ23_MARK, + IRQ24_MARK, + IRQ25_MARK, + IRQ26_PORT58_MARK, IRQ26_PORT81_MARK, + IRQ27_PORT57_MARK, IRQ27_PORT168_MARK, + IRQ28_PORT56_MARK, IRQ28_PORT169_MARK, + IRQ29_PORT50_MARK, IRQ29_PORT170_MARK, + IRQ30_PORT49_MARK, IRQ30_PORT171_MARK, + IRQ31_PORT41_MARK, IRQ31_PORT167_MARK, + + /* Function */ + + /* DBGT */ + DBGMDT2_MARK, DBGMDT1_MARK, DBGMDT0_MARK, + DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK, + DBGMD21_MARK, + + /* FSI */ + FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */ + FSIAISLD_PORT5_MARK, + FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */ + FSIASPDIF_PORT18_MARK, + FSIAOSLD1_MARK, FSIAOSLD2_MARK, FSIAOLR_MARK, + FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK, + FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK, + + /* FMSI */ + FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */ + FMSISLD_PORT6_MARK, + FMSIILR_MARK, FMSIIBT_MARK, FMSIOLR_MARK, FMSIOBT_MARK, + FMSICK_MARK, FMSOILR_MARK, FMSOIBT_MARK, FMSOOLR_MARK, + FMSOOBT_MARK, FMSOSLD_MARK, FMSOCK_MARK, + + /* SCIFA0 */ + SCIFA0_SCK_MARK, SCIFA0_CTS_MARK, SCIFA0_RTS_MARK, + SCIFA0_RXD_MARK, SCIFA0_TXD_MARK, + + /* SCIFA1 */ + SCIFA1_CTS_MARK, SCIFA1_SCK_MARK, SCIFA1_RXD_MARK, + SCIFA1_TXD_MARK, SCIFA1_RTS_MARK, + + /* SCIFA2 */ + SCIFA2_SCK_PORT22_MARK, /* SCIFA2_SCK Port 22/199 */ + SCIFA2_SCK_PORT199_MARK, + SCIFA2_RXD_MARK, SCIFA2_TXD_MARK, + SCIFA2_CTS_MARK, SCIFA2_RTS_MARK, + + /* SCIFA3 */ + SCIFA3_RTS_PORT105_MARK, /* MSEL5CR_8_0 */ + SCIFA3_SCK_PORT116_MARK, + SCIFA3_CTS_PORT117_MARK, + SCIFA3_RXD_PORT174_MARK, + SCIFA3_TXD_PORT175_MARK, + + SCIFA3_RTS_PORT161_MARK, /* MSEL5CR_8_1 */ + SCIFA3_SCK_PORT158_MARK, + SCIFA3_CTS_PORT162_MARK, + SCIFA3_RXD_PORT159_MARK, + SCIFA3_TXD_PORT160_MARK, + + /* SCIFA4 */ + SCIFA4_RXD_PORT12_MARK, /* MSEL5CR[12:11] = 00 */ + SCIFA4_TXD_PORT13_MARK, + + SCIFA4_RXD_PORT204_MARK, /* MSEL5CR[12:11] = 01 */ + SCIFA4_TXD_PORT203_MARK, + + SCIFA4_RXD_PORT94_MARK, /* MSEL5CR[12:11] = 10 */ + SCIFA4_TXD_PORT93_MARK, + + SCIFA4_SCK_PORT21_MARK, /* SCIFA4_SCK Port 21/205 */ + SCIFA4_SCK_PORT205_MARK, + + /* SCIFA5 */ + SCIFA5_TXD_PORT20_MARK, /* MSEL5CR[15:14] = 00 */ + SCIFA5_RXD_PORT10_MARK, + + SCIFA5_RXD_PORT207_MARK, /* MSEL5CR[15:14] = 01 */ + SCIFA5_TXD_PORT208_MARK, + + SCIFA5_TXD_PORT91_MARK, /* MSEL5CR[15:14] = 10 */ + SCIFA5_RXD_PORT92_MARK, + + SCIFA5_SCK_PORT23_MARK, /* SCIFA5_SCK Port 23/206 */ + SCIFA5_SCK_PORT206_MARK, + + /* SCIFA6 */ + SCIFA6_SCK_MARK, SCIFA6_RXD_MARK, SCIFA6_TXD_MARK, + + /* SCIFA7 */ + SCIFA7_TXD_MARK, SCIFA7_RXD_MARK, + + /* SCIFAB */ + SCIFB_SCK_PORT190_MARK, /* MSEL5CR_17_0 */ + SCIFB_RXD_PORT191_MARK, + SCIFB_TXD_PORT192_MARK, + SCIFB_RTS_PORT186_MARK, + SCIFB_CTS_PORT187_MARK, + + SCIFB_SCK_PORT2_MARK, /* MSEL5CR_17_1 */ + SCIFB_RXD_PORT3_MARK, + SCIFB_TXD_PORT4_MARK, + SCIFB_RTS_PORT172_MARK, + SCIFB_CTS_PORT173_MARK, + + /* LCD0 */ + LCDC0_SELECT_MARK, + + LCD0_D0_MARK, LCD0_D1_MARK, LCD0_D2_MARK, LCD0_D3_MARK, + LCD0_D4_MARK, LCD0_D5_MARK, LCD0_D6_MARK, LCD0_D7_MARK, + LCD0_D8_MARK, LCD0_D9_MARK, LCD0_D10_MARK, LCD0_D11_MARK, + LCD0_D12_MARK, LCD0_D13_MARK, LCD0_D14_MARK, LCD0_D15_MARK, + LCD0_D16_MARK, LCD0_D17_MARK, + LCD0_DON_MARK, LCD0_VCPWC_MARK, LCD0_VEPWC_MARK, + LCD0_DCK_MARK, LCD0_VSYN_MARK, /* for RGB */ + LCD0_HSYN_MARK, LCD0_DISP_MARK, /* for RGB */ + LCD0_WR_MARK, LCD0_RD_MARK, /* for SYS */ + LCD0_CS_MARK, LCD0_RS_MARK, /* for SYS */ + + LCD0_D21_PORT158_MARK, LCD0_D23_PORT159_MARK, /* MSEL5CR_6_1 */ + LCD0_D22_PORT160_MARK, LCD0_D20_PORT161_MARK, + LCD0_D19_PORT162_MARK, LCD0_D18_PORT163_MARK, + LCD0_LCLK_PORT165_MARK, + + LCD0_D18_PORT40_MARK, LCD0_D22_PORT0_MARK, /* MSEL5CR_6_0 */ + LCD0_D23_PORT1_MARK, LCD0_D21_PORT2_MARK, + LCD0_D20_PORT3_MARK, LCD0_D19_PORT4_MARK, + LCD0_LCLK_PORT102_MARK, + + /* LCD1 */ + LCDC1_SELECT_MARK, + + LCD1_D0_MARK, LCD1_D1_MARK, LCD1_D2_MARK, LCD1_D3_MARK, + LCD1_D4_MARK, LCD1_D5_MARK, LCD1_D6_MARK, LCD1_D7_MARK, + LCD1_D8_MARK, LCD1_D9_MARK, LCD1_D10_MARK, LCD1_D11_MARK, + LCD1_D12_MARK, LCD1_D13_MARK, LCD1_D14_MARK, LCD1_D15_MARK, + LCD1_D16_MARK, LCD1_D17_MARK, LCD1_D18_MARK, LCD1_D19_MARK, + LCD1_D20_MARK, LCD1_D21_MARK, LCD1_D22_MARK, LCD1_D23_MARK, + LCD1_DON_MARK, LCD1_VCPWC_MARK, + LCD1_LCLK_MARK, LCD1_VEPWC_MARK, + + LCD1_DCK_MARK, LCD1_VSYN_MARK, /* for RGB */ + LCD1_HSYN_MARK, LCD1_DISP_MARK, /* for RGB */ + LCD1_RS_MARK, LCD1_CS_MARK, /* for SYS */ + LCD1_RD_MARK, LCD1_WR_MARK, /* for SYS */ + + /* RSPI */ + RSPI_SSL0_A_MARK, RSPI_SSL1_A_MARK, RSPI_SSL2_A_MARK, + RSPI_SSL3_A_MARK, RSPI_CK_A_MARK, RSPI_MOSI_A_MARK, + RSPI_MISO_A_MARK, + + /* VIO CKO */ + VIO_CKO1_MARK, /* needs fixup */ + VIO_CKO2_MARK, + VIO_CKO_1_MARK, + VIO_CKO_MARK, + + /* VIO0 */ + VIO0_D0_MARK, VIO0_D1_MARK, VIO0_D2_MARK, VIO0_D3_MARK, + VIO0_D4_MARK, VIO0_D5_MARK, VIO0_D6_MARK, VIO0_D7_MARK, + VIO0_D8_MARK, VIO0_D9_MARK, VIO0_D10_MARK, VIO0_D11_MARK, + VIO0_D12_MARK, VIO0_VD_MARK, VIO0_HD_MARK, VIO0_CLK_MARK, + VIO0_FIELD_MARK, + + VIO0_D13_PORT26_MARK, /* MSEL5CR_27_0 */ + VIO0_D14_PORT25_MARK, + VIO0_D15_PORT24_MARK, + + VIO0_D13_PORT22_MARK, /* MSEL5CR_27_1 */ + VIO0_D14_PORT95_MARK, + VIO0_D15_PORT96_MARK, + + /* VIO1 */ + VIO1_D0_MARK, VIO1_D1_MARK, VIO1_D2_MARK, VIO1_D3_MARK, + VIO1_D4_MARK, VIO1_D5_MARK, VIO1_D6_MARK, VIO1_D7_MARK, + VIO1_VD_MARK, VIO1_HD_MARK, VIO1_CLK_MARK, VIO1_FIELD_MARK, + + /* TPU0 */ + TPU0TO0_MARK, TPU0TO1_MARK, TPU0TO3_MARK, + TPU0TO2_PORT66_MARK, /* TPU0TO2 Port 66/202 */ + TPU0TO2_PORT202_MARK, + + /* SSP1 0 */ + STP0_IPD0_MARK, STP0_IPD1_MARK, STP0_IPD2_MARK, STP0_IPD3_MARK, + STP0_IPD4_MARK, STP0_IPD5_MARK, STP0_IPD6_MARK, STP0_IPD7_MARK, + STP0_IPEN_MARK, STP0_IPCLK_MARK, STP0_IPSYNC_MARK, + + /* SSP1 1 */ + STP1_IPD1_MARK, STP1_IPD2_MARK, STP1_IPD3_MARK, STP1_IPD4_MARK, + STP1_IPD5_MARK, STP1_IPD6_MARK, STP1_IPD7_MARK, STP1_IPCLK_MARK, + STP1_IPSYNC_MARK, + + STP1_IPD0_PORT186_MARK, /* MSEL5CR_23_0 */ + STP1_IPEN_PORT187_MARK, + + STP1_IPD0_PORT194_MARK, /* MSEL5CR_23_1 */ + STP1_IPEN_PORT193_MARK, + + /* SIM */ + SIM_RST_MARK, SIM_CLK_MARK, + SIM_D_PORT22_MARK, /* SIM_D Port 22/199 */ + SIM_D_PORT199_MARK, + + /* SDHI0 */ + SDHI0_D0_MARK, SDHI0_D1_MARK, SDHI0_D2_MARK, SDHI0_D3_MARK, + SDHI0_CD_MARK, SDHI0_WP_MARK, SDHI0_CMD_MARK, SDHI0_CLK_MARK, + + /* SDHI1 */ + SDHI1_D0_MARK, SDHI1_D1_MARK, SDHI1_D2_MARK, SDHI1_D3_MARK, + SDHI1_CD_MARK, SDHI1_WP_MARK, SDHI1_CMD_MARK, SDHI1_CLK_MARK, + + /* SDHI2 */ + SDHI2_D0_MARK, SDHI2_D1_MARK, SDHI2_D2_MARK, SDHI2_D3_MARK, + SDHI2_CLK_MARK, SDHI2_CMD_MARK, + + SDHI2_CD_PORT24_MARK, /* MSEL5CR_19_0 */ + SDHI2_WP_PORT25_MARK, + + SDHI2_WP_PORT177_MARK, /* MSEL5CR_19_1 */ + SDHI2_CD_PORT202_MARK, + + /* MSIOF2 */ + MSIOF2_TXD_MARK, MSIOF2_RXD_MARK, MSIOF2_TSCK_MARK, + MSIOF2_SS2_MARK, MSIOF2_TSYNC_MARK, MSIOF2_SS1_MARK, + MSIOF2_MCK1_MARK, MSIOF2_MCK0_MARK, MSIOF2_RSYNC_MARK, + MSIOF2_RSCK_MARK, + + /* KEYSC */ + KEYIN4_MARK, KEYIN5_MARK, KEYIN6_MARK, KEYIN7_MARK, + KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK, + KEYOUT4_MARK, KEYOUT5_MARK, KEYOUT6_MARK, KEYOUT7_MARK, + + KEYIN0_PORT43_MARK, /* MSEL4CR_18_0 */ + KEYIN1_PORT44_MARK, + KEYIN2_PORT45_MARK, + KEYIN3_PORT46_MARK, + + KEYIN0_PORT58_MARK, /* MSEL4CR_18_1 */ + KEYIN1_PORT57_MARK, + KEYIN2_PORT56_MARK, + KEYIN3_PORT55_MARK, + + /* VOU */ + DV_D0_MARK, DV_D1_MARK, DV_D2_MARK, DV_D3_MARK, + DV_D4_MARK, DV_D5_MARK, DV_D6_MARK, DV_D7_MARK, + DV_D8_MARK, DV_D9_MARK, DV_D10_MARK, DV_D11_MARK, + DV_D12_MARK, DV_D13_MARK, DV_D14_MARK, DV_D15_MARK, + DV_CLK_MARK, DV_VSYNC_MARK, DV_HSYNC_MARK, + + /* MEMC */ + MEMC_AD0_MARK, MEMC_AD1_MARK, MEMC_AD2_MARK, MEMC_AD3_MARK, + MEMC_AD4_MARK, MEMC_AD5_MARK, MEMC_AD6_MARK, MEMC_AD7_MARK, + MEMC_AD8_MARK, MEMC_AD9_MARK, MEMC_AD10_MARK, MEMC_AD11_MARK, + MEMC_AD12_MARK, MEMC_AD13_MARK, MEMC_AD14_MARK, MEMC_AD15_MARK, + MEMC_CS0_MARK, MEMC_INT_MARK, MEMC_NWE_MARK, MEMC_NOE_MARK, + + MEMC_CS1_MARK, /* MSEL4CR_6_0 */ + MEMC_ADV_MARK, + MEMC_WAIT_MARK, + MEMC_BUSCLK_MARK, + + MEMC_A1_MARK, /* MSEL4CR_6_1 */ + MEMC_DREQ0_MARK, + MEMC_DREQ1_MARK, + MEMC_A0_MARK, + + /* MMC */ + MMC0_D0_PORT68_MARK, MMC0_D1_PORT69_MARK, MMC0_D2_PORT70_MARK, + MMC0_D3_PORT71_MARK, MMC0_D4_PORT72_MARK, MMC0_D5_PORT73_MARK, + MMC0_D6_PORT74_MARK, MMC0_D7_PORT75_MARK, MMC0_CLK_PORT66_MARK, + MMC0_CMD_PORT67_MARK, /* MSEL4CR_15_0 */ + + MMC1_D0_PORT149_MARK, MMC1_D1_PORT148_MARK, MMC1_D2_PORT147_MARK, + MMC1_D3_PORT146_MARK, MMC1_D4_PORT145_MARK, MMC1_D5_PORT144_MARK, + MMC1_D6_PORT143_MARK, MMC1_D7_PORT142_MARK, MMC1_CLK_PORT103_MARK, + MMC1_CMD_PORT104_MARK, /* MSEL4CR_15_1 */ + + /* MSIOF0 */ + MSIOF0_SS1_MARK, MSIOF0_SS2_MARK, MSIOF0_RXD_MARK, + MSIOF0_TXD_MARK, MSIOF0_MCK0_MARK, MSIOF0_MCK1_MARK, + MSIOF0_RSYNC_MARK, MSIOF0_RSCK_MARK, MSIOF0_TSCK_MARK, + MSIOF0_TSYNC_MARK, + + /* MSIOF1 */ + MSIOF1_RSCK_MARK, MSIOF1_RSYNC_MARK, + MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK, + + MSIOF1_SS2_PORT116_MARK, MSIOF1_SS1_PORT117_MARK, + MSIOF1_RXD_PORT118_MARK, MSIOF1_TXD_PORT119_MARK, + MSIOF1_TSYNC_PORT120_MARK, + MSIOF1_TSCK_PORT121_MARK, /* MSEL4CR_10_0 */ + + MSIOF1_SS1_PORT67_MARK, MSIOF1_TSCK_PORT72_MARK, + MSIOF1_TSYNC_PORT73_MARK, MSIOF1_TXD_PORT74_MARK, + MSIOF1_RXD_PORT75_MARK, + MSIOF1_SS2_PORT202_MARK, /* MSEL4CR_10_1 */ + + /* GPIO */ + GPO0_MARK, GPI0_MARK, GPO1_MARK, GPI1_MARK, + + /* USB0 */ + USB0_OCI_MARK, USB0_PPON_MARK, VBUS_MARK, + + /* USB1 */ + USB1_OCI_MARK, USB1_PPON_MARK, + + /* BBIF1 */ + BBIF1_RXD_MARK, BBIF1_TXD_MARK, BBIF1_TSYNC_MARK, + BBIF1_TSCK_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK, + BBIF1_FLOW_MARK, BBIF1_RX_FLOW_N_MARK, + + /* BBIF2 */ + BBIF2_TXD2_PORT5_MARK, /* MSEL5CR_0_0 */ + BBIF2_RXD2_PORT60_MARK, + BBIF2_TSYNC2_PORT6_MARK, + BBIF2_TSCK2_PORT59_MARK, + + BBIF2_RXD2_PORT90_MARK, /* MSEL5CR_0_1 */ + BBIF2_TXD2_PORT183_MARK, + BBIF2_TSCK2_PORT89_MARK, + BBIF2_TSYNC2_PORT184_MARK, + + /* BSC / FLCTL / PCMCIA */ + CS0_MARK, CS2_MARK, CS4_MARK, + CS5B_MARK, CS6A_MARK, + CS5A_PORT105_MARK, /* CS5A PORT 19/105 */ + CS5A_PORT19_MARK, + IOIS16_MARK, /* ? */ + + A0_MARK, A1_MARK, A2_MARK, A3_MARK, + A4_FOE_MARK, /* share with FLCTL */ + A5_FCDE_MARK, /* share with FLCTL */ + A6_MARK, A7_MARK, A8_MARK, A9_MARK, + A10_MARK, A11_MARK, A12_MARK, A13_MARK, + A14_MARK, A15_MARK, A16_MARK, A17_MARK, + A18_MARK, A19_MARK, A20_MARK, A21_MARK, + A22_MARK, A23_MARK, A24_MARK, A25_MARK, + A26_MARK, + + D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, /* share with FLCTL */ + D3_NAF3_MARK, D4_NAF4_MARK, D5_NAF5_MARK, /* share with FLCTL */ + D6_NAF6_MARK, D7_NAF7_MARK, D8_NAF8_MARK, /* share with FLCTL */ + D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK, /* share with FLCTL */ + D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, /* share with FLCTL */ + D15_NAF15_MARK, /* share with FLCTL */ + D16_MARK, D17_MARK, D18_MARK, D19_MARK, + D20_MARK, D21_MARK, D22_MARK, D23_MARK, + D24_MARK, D25_MARK, D26_MARK, D27_MARK, + D28_MARK, D29_MARK, D30_MARK, D31_MARK, + + WE0_FWE_MARK, /* share with FLCTL */ + WE1_MARK, + WE2_ICIORD_MARK, /* share with PCMCIA */ + WE3_ICIOWR_MARK, /* share with PCMCIA */ + CKO_MARK, BS_MARK, RDWR_MARK, + RD_FSC_MARK, /* share with FLCTL */ + WAIT_PORT177_MARK, /* WAIT Port 90/177 */ + WAIT_PORT90_MARK, + + FCE0_MARK, FCE1_MARK, FRB_MARK, /* FLCTL */ + + /* IRDA */ + IRDA_FIRSEL_MARK, IRDA_IN_MARK, IRDA_OUT_MARK, + + /* ATAPI */ + IDE_D0_MARK, IDE_D1_MARK, IDE_D2_MARK, IDE_D3_MARK, + IDE_D4_MARK, IDE_D5_MARK, IDE_D6_MARK, IDE_D7_MARK, + IDE_D8_MARK, IDE_D9_MARK, IDE_D10_MARK, IDE_D11_MARK, + IDE_D12_MARK, IDE_D13_MARK, IDE_D14_MARK, IDE_D15_MARK, + IDE_A0_MARK, IDE_A1_MARK, IDE_A2_MARK, IDE_CS0_MARK, + IDE_CS1_MARK, IDE_IOWR_MARK, IDE_IORD_MARK, IDE_IORDY_MARK, + IDE_INT_MARK, IDE_RST_MARK, IDE_DIRECTION_MARK, + IDE_EXBUF_ENB_MARK, IDE_IODACK_MARK, IDE_IODREQ_MARK, + + /* RMII */ + RMII_CRS_DV_MARK, RMII_RX_ER_MARK, RMII_RXD0_MARK, + RMII_RXD1_MARK, RMII_TX_EN_MARK, RMII_TXD0_MARK, + RMII_MDC_MARK, RMII_TXD1_MARK, RMII_MDIO_MARK, + RMII_REF50CK_MARK, /* for RMII */ + RMII_REF125CK_MARK, /* for GMII */ + + /* GEther */ + ET_TX_CLK_MARK, ET_TX_EN_MARK, ET_ETXD0_MARK, ET_ETXD1_MARK, + ET_ETXD2_MARK, ET_ETXD3_MARK, + ET_ETXD4_MARK, ET_ETXD5_MARK, /* for GEther */ + ET_ETXD6_MARK, ET_ETXD7_MARK, /* for GEther */ + ET_COL_MARK, ET_TX_ER_MARK, ET_RX_CLK_MARK, ET_RX_DV_MARK, + ET_ERXD0_MARK, ET_ERXD1_MARK, ET_ERXD2_MARK, ET_ERXD3_MARK, + ET_ERXD4_MARK, ET_ERXD5_MARK, /* for GEther */ + ET_ERXD6_MARK, ET_ERXD7_MARK, /* for GEther */ + ET_RX_ER_MARK, ET_CRS_MARK, ET_MDC_MARK, ET_MDIO_MARK, + ET_LINK_MARK, ET_PHY_INT_MARK, ET_WOL_MARK, ET_GTX_CLK_MARK, + + /* DMA0 */ + DREQ0_MARK, DACK0_MARK, + + /* DMA1 */ + DREQ1_MARK, DACK1_MARK, + + /* SYSC */ + RESETOUTS_MARK, RESETP_PULLUP_MARK, RESETP_PLAIN_MARK, + + /* IRREM */ + IROUT_MARK, + + /* SDENC */ + SDENC_CPG_MARK, SDENC_DV_CLKI_MARK, + + /* DEBUG */ + EDEBGREQ_PULLUP_MARK, /* for JTAG */ + EDEBGREQ_PULLDOWN_MARK, + + TRACEAUD_FROM_VIO_MARK, /* for TRACE/AUD */ + TRACEAUD_FROM_LCDC0_MARK, + TRACEAUD_FROM_MEMC_MARK, + + PINMUX_MARK_END, +}; + +static unsigned short pinmux_data[] = { + /* specify valid pin states for each pin in GPIO mode */ + + /* I/O and Pull U/D */ + PORT_DATA_IO_PD(0), PORT_DATA_IO_PD(1), + PORT_DATA_IO_PD(2), PORT_DATA_IO_PD(3), + PORT_DATA_IO_PD(4), PORT_DATA_IO_PD(5), + PORT_DATA_IO_PD(6), PORT_DATA_IO(7), + PORT_DATA_IO(8), PORT_DATA_IO(9), + + PORT_DATA_IO_PD(10), PORT_DATA_IO_PD(11), + PORT_DATA_IO_PD(12), PORT_DATA_IO_PU_PD(13), + PORT_DATA_IO_PD(14), PORT_DATA_IO_PD(15), + PORT_DATA_IO_PD(16), PORT_DATA_IO_PD(17), + PORT_DATA_IO(18), PORT_DATA_IO_PU(19), + + PORT_DATA_IO_PU_PD(20), PORT_DATA_IO_PD(21), + PORT_DATA_IO_PU_PD(22), PORT_DATA_IO(23), + PORT_DATA_IO_PU(24), PORT_DATA_IO_PU(25), + PORT_DATA_IO_PU(26), PORT_DATA_IO_PU(27), + PORT_DATA_IO_PU(28), PORT_DATA_IO_PU(29), + + PORT_DATA_IO_PU(30), PORT_DATA_IO_PD(31), + PORT_DATA_IO_PD(32), PORT_DATA_IO_PD(33), + PORT_DATA_IO_PD(34), PORT_DATA_IO_PU(35), + PORT_DATA_IO_PU(36), PORT_DATA_IO_PD(37), + PORT_DATA_IO_PU(38), PORT_DATA_IO_PD(39), + + PORT_DATA_IO_PU_PD(40), PORT_DATA_IO_PD(41), + PORT_DATA_IO_PD(42), PORT_DATA_IO_PU_PD(43), + PORT_DATA_IO_PU_PD(44), PORT_DATA_IO_PU_PD(45), + PORT_DATA_IO_PU_PD(46), PORT_DATA_IO_PU_PD(47), + PORT_DATA_IO_PU_PD(48), PORT_DATA_IO_PU_PD(49), + + PORT_DATA_IO_PU_PD(50), PORT_DATA_IO_PD(51), + PORT_DATA_IO_PD(52), PORT_DATA_IO_PD(53), + PORT_DATA_IO_PD(54), PORT_DATA_IO_PU_PD(55), + PORT_DATA_IO_PU_PD(56), PORT_DATA_IO_PU_PD(57), + PORT_DATA_IO_PU_PD(58), PORT_DATA_IO_PU_PD(59), + + PORT_DATA_IO_PU_PD(60), PORT_DATA_IO_PD(61), + PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63), + PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65), + PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67), + PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69), + + PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71), + PORT_DATA_IO_PU_PD(72), PORT_DATA_IO_PU_PD(73), + PORT_DATA_IO_PU_PD(74), PORT_DATA_IO_PU_PD(75), + PORT_DATA_IO_PU_PD(76), PORT_DATA_IO_PU_PD(77), + PORT_DATA_IO_PU_PD(78), PORT_DATA_IO_PU_PD(79), + + PORT_DATA_IO_PU_PD(80), PORT_DATA_IO_PU_PD(81), + PORT_DATA_IO(82), PORT_DATA_IO_PU_PD(83), + PORT_DATA_IO(84), PORT_DATA_IO_PD(85), + PORT_DATA_IO_PD(86), PORT_DATA_IO_PD(87), + PORT_DATA_IO_PD(88), PORT_DATA_IO_PD(89), + + PORT_DATA_IO_PD(90), PORT_DATA_IO_PU_PD(91), + PORT_DATA_IO_PU_PD(92), PORT_DATA_IO_PU_PD(93), + PORT_DATA_IO_PU_PD(94), PORT_DATA_IO_PU_PD(95), + PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97), + PORT_DATA_IO_PU_PD(98), PORT_DATA_IO_PU_PD(99), + + PORT_DATA_IO_PU_PD(100), PORT_DATA_IO(101), + PORT_DATA_IO_PU(102), PORT_DATA_IO_PU_PD(103), + PORT_DATA_IO_PU(104), PORT_DATA_IO_PU(105), + PORT_DATA_IO_PU_PD(106), PORT_DATA_IO(107), + PORT_DATA_IO(108), PORT_DATA_IO(109), + + PORT_DATA_IO(110), PORT_DATA_IO(111), + PORT_DATA_IO(112), PORT_DATA_IO(113), + PORT_DATA_IO_PU_PD(114), PORT_DATA_IO(115), + PORT_DATA_IO_PD(116), PORT_DATA_IO_PD(117), + PORT_DATA_IO_PD(118), PORT_DATA_IO_PD(119), + + PORT_DATA_IO_PD(120), PORT_DATA_IO_PD(121), + PORT_DATA_IO_PD(122), PORT_DATA_IO_PD(123), + PORT_DATA_IO_PD(124), PORT_DATA_IO(125), + PORT_DATA_IO(126), PORT_DATA_IO(127), + PORT_DATA_IO(128), PORT_DATA_IO(129), + + PORT_DATA_IO(130), PORT_DATA_IO(131), + PORT_DATA_IO(132), PORT_DATA_IO(133), + PORT_DATA_IO(134), PORT_DATA_IO(135), + PORT_DATA_IO(136), PORT_DATA_IO(137), + PORT_DATA_IO(138), PORT_DATA_IO(139), + + PORT_DATA_IO(140), PORT_DATA_IO(141), + PORT_DATA_IO_PU(142), PORT_DATA_IO_PU(143), + PORT_DATA_IO_PU(144), PORT_DATA_IO_PU(145), + PORT_DATA_IO_PU(146), PORT_DATA_IO_PU(147), + PORT_DATA_IO_PU(148), PORT_DATA_IO_PU(149), + + PORT_DATA_IO_PU(150), PORT_DATA_IO_PU(151), + PORT_DATA_IO_PU(152), PORT_DATA_IO_PU(153), + PORT_DATA_IO_PU(154), PORT_DATA_IO_PU(155), + PORT_DATA_IO_PU(156), PORT_DATA_IO_PU(157), + PORT_DATA_IO_PD(158), PORT_DATA_IO_PD(159), + + PORT_DATA_IO_PU_PD(160), PORT_DATA_IO_PD(161), + PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163), + PORT_DATA_IO_PD(164), PORT_DATA_IO_PD(165), + PORT_DATA_IO_PU(166), PORT_DATA_IO_PU(167), + PORT_DATA_IO_PU(168), PORT_DATA_IO_PU(169), + + PORT_DATA_IO_PU(170), PORT_DATA_IO_PU(171), + PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173), + PORT_DATA_IO_PD(174), PORT_DATA_IO_PD(175), + PORT_DATA_IO_PU(176), PORT_DATA_IO_PU_PD(177), + PORT_DATA_IO_PU(178), PORT_DATA_IO_PD(179), + + PORT_DATA_IO_PD(180), PORT_DATA_IO_PU(181), + PORT_DATA_IO_PU(182), PORT_DATA_IO(183), + PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185), + PORT_DATA_IO_PD(186), PORT_DATA_IO_PD(187), + PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189), + + PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191), + PORT_DATA_IO_PD(192), PORT_DATA_IO_PU_PD(193), + PORT_DATA_IO_PU_PD(194), PORT_DATA_IO_PD(195), + PORT_DATA_IO_PU_PD(196), PORT_DATA_IO_PD(197), + PORT_DATA_IO_PU_PD(198), PORT_DATA_IO_PU_PD(199), + + PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU(201), + PORT_DATA_IO_PU_PD(202), PORT_DATA_IO(203), + PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205), + PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PU_PD(207), + PORT_DATA_IO_PU_PD(208), PORT_DATA_IO_PD(209), + + PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211), + + /* Port0 */ + PINMUX_DATA(DBGMDT2_MARK, PORT0_FN1), + PINMUX_DATA(FSIAISLD_PORT0_MARK, PORT0_FN2, MSEL5CR_3_0), + PINMUX_DATA(FSIAOSLD1_MARK, PORT0_FN3), + PINMUX_DATA(LCD0_D22_PORT0_MARK, PORT0_FN4, MSEL5CR_6_0), + PINMUX_DATA(SCIFA7_RXD_MARK, PORT0_FN6), + PINMUX_DATA(LCD1_D4_MARK, PORT0_FN7), + PINMUX_DATA(IRQ5_PORT0_MARK, PORT0_FN0, MSEL1CR_5_0), + + /* Port1 */ + PINMUX_DATA(DBGMDT1_MARK, PORT1_FN1), + PINMUX_DATA(FMSISLD_PORT1_MARK, PORT1_FN2, MSEL5CR_5_0), + PINMUX_DATA(FSIAOSLD2_MARK, PORT1_FN3), + PINMUX_DATA(LCD0_D23_PORT1_MARK, PORT1_FN4, MSEL5CR_6_0), + PINMUX_DATA(SCIFA7_TXD_MARK, PORT1_FN6), + PINMUX_DATA(LCD1_D3_MARK, PORT1_FN7), + PINMUX_DATA(IRQ5_PORT1_MARK, PORT1_FN0, MSEL1CR_5_1), + + /* Port2 */ + PINMUX_DATA(DBGMDT0_MARK, PORT2_FN1), + PINMUX_DATA(SCIFB_SCK_PORT2_MARK, PORT2_FN2, MSEL5CR_17_1), + PINMUX_DATA(LCD0_D21_PORT2_MARK, PORT2_FN4, MSEL5CR_6_0), + PINMUX_DATA(LCD1_D2_MARK, PORT2_FN7), + PINMUX_DATA(IRQ0_PORT2_MARK, PORT2_FN0, MSEL1CR_0_1), + + /* Port3 */ + PINMUX_DATA(DBGMD21_MARK, PORT3_FN1), + PINMUX_DATA(SCIFB_RXD_PORT3_MARK, PORT3_FN2, MSEL5CR_17_1), + PINMUX_DATA(LCD0_D20_PORT3_MARK, PORT3_FN4, MSEL5CR_6_0), + PINMUX_DATA(LCD1_D1_MARK, PORT3_FN7), + + /* Port4 */ + PINMUX_DATA(DBGMD20_MARK, PORT4_FN1), + PINMUX_DATA(SCIFB_TXD_PORT4_MARK, PORT4_FN2, MSEL5CR_17_1), + PINMUX_DATA(LCD0_D19_PORT4_MARK, PORT4_FN4, MSEL5CR_6_0), + PINMUX_DATA(LCD1_D0_MARK, PORT4_FN7), + + /* Port5 */ + PINMUX_DATA(DBGMD11_MARK, PORT5_FN1), + PINMUX_DATA(BBIF2_TXD2_PORT5_MARK, PORT5_FN2, MSEL5CR_0_0), + PINMUX_DATA(FSIAISLD_PORT5_MARK, PORT5_FN4, MSEL5CR_3_1), + PINMUX_DATA(RSPI_SSL0_A_MARK, PORT5_FN6), + PINMUX_DATA(LCD1_VCPWC_MARK, PORT5_FN7), + + /* Port6 */ + PINMUX_DATA(DBGMD10_MARK, PORT6_FN1), + PINMUX_DATA(BBIF2_TSYNC2_PORT6_MARK, PORT6_FN2, MSEL5CR_0_0), + PINMUX_DATA(FMSISLD_PORT6_MARK, PORT6_FN4, MSEL5CR_5_1), + PINMUX_DATA(RSPI_SSL1_A_MARK, PORT6_FN6), + PINMUX_DATA(LCD1_VEPWC_MARK, PORT6_FN7), + + /* Port7 */ + PINMUX_DATA(FSIAOLR_MARK, PORT7_FN1), + + /* Port8 */ + PINMUX_DATA(FSIAOBT_MARK, PORT8_FN1), + + /* Port9 */ + PINMUX_DATA(FSIAOSLD_MARK, PORT9_FN1), + PINMUX_DATA(FSIASPDIF_PORT9_MARK, PORT9_FN2, MSEL5CR_4_0), + + /* Port10 */ + PINMUX_DATA(FSIAOMC_MARK, PORT10_FN1), + PINMUX_DATA(SCIFA5_RXD_PORT10_MARK, PORT10_FN3, MSEL5CR_14_0, + MSEL5CR_15_0), + PINMUX_DATA(IRQ3_PORT10_MARK, PORT10_FN0, MSEL1CR_3_0), + + /* Port11 */ + PINMUX_DATA(FSIACK_MARK, PORT11_FN1), + PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0), + + /* Port12 */ + PINMUX_DATA(FSIAILR_MARK, PORT12_FN1), + PINMUX_DATA(SCIFA4_RXD_PORT12_MARK, PORT12_FN2, MSEL5CR_12_0, + MSEL5CR_11_0), + PINMUX_DATA(LCD1_RS_MARK, PORT12_FN6), + PINMUX_DATA(LCD1_DISP_MARK, PORT12_FN7), + PINMUX_DATA(IRQ2_PORT12_MARK, PORT12_FN0, MSEL1CR_2_1), + + /* Port13 */ + PINMUX_DATA(FSIAIBT_MARK, PORT13_FN1), + PINMUX_DATA(SCIFA4_TXD_PORT13_MARK, PORT13_FN2, MSEL5CR_12_0, + MSEL5CR_11_0), + PINMUX_DATA(LCD1_RD_MARK, PORT13_FN7), + PINMUX_DATA(IRQ0_PORT13_MARK, PORT13_FN0, MSEL1CR_0_0), + + /* Port14 */ + PINMUX_DATA(FMSOILR_MARK, PORT14_FN1), + PINMUX_DATA(FMSIILR_MARK, PORT14_FN2), + PINMUX_DATA(VIO_CKO1_MARK, PORT14_FN3), + PINMUX_DATA(LCD1_D23_MARK, PORT14_FN7), + PINMUX_DATA(IRQ3_PORT14_MARK, PORT14_FN0, MSEL1CR_3_1), + + /* Port15 */ + PINMUX_DATA(FMSOIBT_MARK, PORT15_FN1), + PINMUX_DATA(FMSIIBT_MARK, PORT15_FN2), + PINMUX_DATA(VIO_CKO2_MARK, PORT15_FN3), + PINMUX_DATA(LCD1_D22_MARK, PORT15_FN7), + PINMUX_DATA(IRQ4_PORT15_MARK, PORT15_FN0, MSEL1CR_4_0), + + /* Port16 */ + PINMUX_DATA(FMSOOLR_MARK, PORT16_FN1), + PINMUX_DATA(FMSIOLR_MARK, PORT16_FN2), + + /* Port17 */ + PINMUX_DATA(FMSOOBT_MARK, PORT17_FN1), + PINMUX_DATA(FMSIOBT_MARK, PORT17_FN2), + + /* Port18 */ + PINMUX_DATA(FMSOSLD_MARK, PORT18_FN1), + PINMUX_DATA(FSIASPDIF_PORT18_MARK, PORT18_FN2, MSEL5CR_4_1), + + /* Port19 */ + PINMUX_DATA(FMSICK_MARK, PORT19_FN1), + PINMUX_DATA(CS5A_PORT19_MARK, PORT19_FN7, MSEL5CR_2_1), + PINMUX_DATA(IRQ10_MARK, PORT19_FN0), + + /* Port20 */ + PINMUX_DATA(FMSOCK_MARK, PORT20_FN1), + PINMUX_DATA(SCIFA5_TXD_PORT20_MARK, PORT20_FN3, MSEL5CR_15_0, + MSEL5CR_14_0), + PINMUX_DATA(IRQ1_MARK, PORT20_FN0), + + /* Port21 */ + PINMUX_DATA(SCIFA1_CTS_MARK, PORT21_FN1), + PINMUX_DATA(SCIFA4_SCK_PORT21_MARK, PORT21_FN2, MSEL5CR_10_0), + PINMUX_DATA(TPU0TO1_MARK, PORT21_FN4), + PINMUX_DATA(VIO1_FIELD_MARK, PORT21_FN5), + PINMUX_DATA(STP0_IPD5_MARK, PORT21_FN6), + PINMUX_DATA(LCD1_D10_MARK, PORT21_FN7), + + /* Port22 */ + PINMUX_DATA(SCIFA2_SCK_PORT22_MARK, PORT22_FN1, MSEL5CR_7_0), + PINMUX_DATA(SIM_D_PORT22_MARK, PORT22_FN4, MSEL5CR_21_0), + PINMUX_DATA(VIO0_D13_PORT22_MARK, PORT22_FN7, MSEL5CR_27_1), + + /* Port23 */ + PINMUX_DATA(SCIFA1_RTS_MARK, PORT23_FN1), + PINMUX_DATA(SCIFA5_SCK_PORT23_MARK, PORT23_FN3, MSEL5CR_13_0), + PINMUX_DATA(TPU0TO0_MARK, PORT23_FN4), + PINMUX_DATA(VIO_CKO_1_MARK, PORT23_FN5), + PINMUX_DATA(STP0_IPD2_MARK, PORT23_FN6), + PINMUX_DATA(LCD1_D7_MARK, PORT23_FN7), + + /* Port24 */ + PINMUX_DATA(VIO0_D15_PORT24_MARK, PORT24_FN1, MSEL5CR_27_0), + PINMUX_DATA(VIO1_D7_MARK, PORT24_FN5), + PINMUX_DATA(SCIFA6_SCK_MARK, PORT24_FN6), + PINMUX_DATA(SDHI2_CD_PORT24_MARK, PORT24_FN7, MSEL5CR_19_0), + + /* Port25 */ + PINMUX_DATA(VIO0_D14_PORT25_MARK, PORT25_FN1, MSEL5CR_27_0), + PINMUX_DATA(VIO1_D6_MARK, PORT25_FN5), + PINMUX_DATA(SCIFA6_RXD_MARK, PORT25_FN6), + PINMUX_DATA(SDHI2_WP_PORT25_MARK, PORT25_FN7, MSEL5CR_19_0), + + /* Port26 */ + PINMUX_DATA(VIO0_D13_PORT26_MARK, PORT26_FN1, MSEL5CR_27_0), + PINMUX_DATA(VIO1_D5_MARK, PORT26_FN5), + PINMUX_DATA(SCIFA6_TXD_MARK, PORT26_FN6), + + /* Port27 - Port39 Function */ + PINMUX_DATA(VIO0_D7_MARK, PORT27_FN1), + PINMUX_DATA(VIO0_D6_MARK, PORT28_FN1), + PINMUX_DATA(VIO0_D5_MARK, PORT29_FN1), + PINMUX_DATA(VIO0_D4_MARK, PORT30_FN1), + PINMUX_DATA(VIO0_D3_MARK, PORT31_FN1), + PINMUX_DATA(VIO0_D2_MARK, PORT32_FN1), + PINMUX_DATA(VIO0_D1_MARK, PORT33_FN1), + PINMUX_DATA(VIO0_D0_MARK, PORT34_FN1), + PINMUX_DATA(VIO0_CLK_MARK, PORT35_FN1), + PINMUX_DATA(VIO_CKO_MARK, PORT36_FN1), + PINMUX_DATA(VIO0_HD_MARK, PORT37_FN1), + PINMUX_DATA(VIO0_FIELD_MARK, PORT38_FN1), + PINMUX_DATA(VIO0_VD_MARK, PORT39_FN1), + + /* Port38 IRQ */ + PINMUX_DATA(IRQ25_MARK, PORT38_FN0), + + /* Port40 */ + PINMUX_DATA(LCD0_D18_PORT40_MARK, PORT40_FN4, MSEL5CR_6_0), + PINMUX_DATA(RSPI_CK_A_MARK, PORT40_FN6), + PINMUX_DATA(LCD1_LCLK_MARK, PORT40_FN7), + + /* Port41 */ + PINMUX_DATA(LCD0_D17_MARK, PORT41_FN1), + PINMUX_DATA(MSIOF2_SS1_MARK, PORT41_FN2), + PINMUX_DATA(IRQ31_PORT41_MARK, PORT41_FN0, MSEL1CR_31_1), + + /* Port42 */ + PINMUX_DATA(LCD0_D16_MARK, PORT42_FN1), + PINMUX_DATA(MSIOF2_MCK1_MARK, PORT42_FN2), + PINMUX_DATA(IRQ12_PORT42_MARK, PORT42_FN0, MSEL1CR_12_1), + + /* Port43 */ + PINMUX_DATA(LCD0_D15_MARK, PORT43_FN1), + PINMUX_DATA(MSIOF2_MCK0_MARK, PORT43_FN2), + PINMUX_DATA(KEYIN0_PORT43_MARK, PORT43_FN3, MSEL4CR_18_0), + PINMUX_DATA(DV_D15_MARK, PORT43_FN6), + + /* Port44 */ + PINMUX_DATA(LCD0_D14_MARK, PORT44_FN1), + PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT44_FN2), + PINMUX_DATA(KEYIN1_PORT44_MARK, PORT44_FN3, MSEL4CR_18_0), + PINMUX_DATA(DV_D14_MARK, PORT44_FN6), + + /* Port45 */ + PINMUX_DATA(LCD0_D13_MARK, PORT45_FN1), + PINMUX_DATA(MSIOF2_RSCK_MARK, PORT45_FN2), + PINMUX_DATA(KEYIN2_PORT45_MARK, PORT45_FN3, MSEL4CR_18_0), + PINMUX_DATA(DV_D13_MARK, PORT45_FN6), + + /* Port46 */ + PINMUX_DATA(LCD0_D12_MARK, PORT46_FN1), + PINMUX_DATA(KEYIN3_PORT46_MARK, PORT46_FN3, MSEL4CR_18_0), + PINMUX_DATA(DV_D12_MARK, PORT46_FN6), + + /* Port47 */ + PINMUX_DATA(LCD0_D11_MARK, PORT47_FN1), + PINMUX_DATA(KEYIN4_MARK, PORT47_FN3), + PINMUX_DATA(DV_D11_MARK, PORT47_FN6), + + /* Port48 */ + PINMUX_DATA(LCD0_D10_MARK, PORT48_FN1), + PINMUX_DATA(KEYIN5_MARK, PORT48_FN3), + PINMUX_DATA(DV_D10_MARK, PORT48_FN6), + + /* Port49 */ + PINMUX_DATA(LCD0_D9_MARK, PORT49_FN1), + PINMUX_DATA(KEYIN6_MARK, PORT49_FN3), + PINMUX_DATA(DV_D9_MARK, PORT49_FN6), + PINMUX_DATA(IRQ30_PORT49_MARK, PORT49_FN0, MSEL1CR_30_1), + + /* Port50 */ + PINMUX_DATA(LCD0_D8_MARK, PORT50_FN1), + PINMUX_DATA(KEYIN7_MARK, PORT50_FN3), + PINMUX_DATA(DV_D8_MARK, PORT50_FN6), + PINMUX_DATA(IRQ29_PORT50_MARK, PORT50_FN0, MSEL1CR_29_1), + + /* Port51 */ + PINMUX_DATA(LCD0_D7_MARK, PORT51_FN1), + PINMUX_DATA(KEYOUT0_MARK, PORT51_FN3), + PINMUX_DATA(DV_D7_MARK, PORT51_FN6), + + /* Port52 */ + PINMUX_DATA(LCD0_D6_MARK, PORT52_FN1), + PINMUX_DATA(KEYOUT1_MARK, PORT52_FN3), + PINMUX_DATA(DV_D6_MARK, PORT52_FN6), + + /* Port53 */ + PINMUX_DATA(LCD0_D5_MARK, PORT53_FN1), + PINMUX_DATA(KEYOUT2_MARK, PORT53_FN3), + PINMUX_DATA(DV_D5_MARK, PORT53_FN6), + + /* Port54 */ + PINMUX_DATA(LCD0_D4_MARK, PORT54_FN1), + PINMUX_DATA(KEYOUT3_MARK, PORT54_FN3), + PINMUX_DATA(DV_D4_MARK, PORT54_FN6), + + /* Port55 */ + PINMUX_DATA(LCD0_D3_MARK, PORT55_FN1), + PINMUX_DATA(KEYOUT4_MARK, PORT55_FN3), + PINMUX_DATA(KEYIN3_PORT55_MARK, PORT55_FN4, MSEL4CR_18_1), + PINMUX_DATA(DV_D3_MARK, PORT55_FN6), + + /* Port56 */ + PINMUX_DATA(LCD0_D2_MARK, PORT56_FN1), + PINMUX_DATA(KEYOUT5_MARK, PORT56_FN3), + PINMUX_DATA(KEYIN2_PORT56_MARK, PORT56_FN4, MSEL4CR_18_1), + PINMUX_DATA(DV_D2_MARK, PORT56_FN6), + PINMUX_DATA(IRQ28_PORT56_MARK, PORT56_FN0, MSEL1CR_28_1), + + /* Port57 */ + PINMUX_DATA(LCD0_D1_MARK, PORT57_FN1), + PINMUX_DATA(KEYOUT6_MARK, PORT57_FN3), + PINMUX_DATA(KEYIN1_PORT57_MARK, PORT57_FN4, MSEL4CR_18_1), + PINMUX_DATA(DV_D1_MARK, PORT57_FN6), + PINMUX_DATA(IRQ27_PORT57_MARK, PORT57_FN0, MSEL1CR_27_1), + + /* Port58 */ + PINMUX_DATA(LCD0_D0_MARK, PORT58_FN1), + PINMUX_DATA(KEYOUT7_MARK, PORT58_FN3), + PINMUX_DATA(KEYIN0_PORT58_MARK, PORT58_FN4, MSEL4CR_18_1), + PINMUX_DATA(DV_D0_MARK, PORT58_FN6), + PINMUX_DATA(IRQ26_PORT58_MARK, PORT58_FN0, MSEL1CR_26_1), + + /* Port59 */ + PINMUX_DATA(LCD0_VCPWC_MARK, PORT59_FN1), + PINMUX_DATA(BBIF2_TSCK2_PORT59_MARK, PORT59_FN2, MSEL5CR_0_0), + PINMUX_DATA(RSPI_MOSI_A_MARK, PORT59_FN6), + + /* Port60 */ + PINMUX_DATA(LCD0_VEPWC_MARK, PORT60_FN1), + PINMUX_DATA(BBIF2_RXD2_PORT60_MARK, PORT60_FN2, MSEL5CR_0_0), + PINMUX_DATA(RSPI_MISO_A_MARK, PORT60_FN6), + + /* Port61 */ + PINMUX_DATA(LCD0_DON_MARK, PORT61_FN1), + PINMUX_DATA(MSIOF2_TXD_MARK, PORT61_FN2), + + /* Port62 */ + PINMUX_DATA(LCD0_DCK_MARK, PORT62_FN1), + PINMUX_DATA(LCD0_WR_MARK, PORT62_FN4), + PINMUX_DATA(DV_CLK_MARK, PORT62_FN6), + PINMUX_DATA(IRQ15_PORT62_MARK, PORT62_FN0, MSEL1CR_15_1), + + /* Port63 */ + PINMUX_DATA(LCD0_VSYN_MARK, PORT63_FN1), + PINMUX_DATA(DV_VSYNC_MARK, PORT63_FN6), + PINMUX_DATA(IRQ14_PORT63_MARK, PORT63_FN0, MSEL1CR_14_1), + + /* Port64 */ + PINMUX_DATA(LCD0_HSYN_MARK, PORT64_FN1), + PINMUX_DATA(LCD0_CS_MARK, PORT64_FN4), + PINMUX_DATA(DV_HSYNC_MARK, PORT64_FN6), + PINMUX_DATA(IRQ13_PORT64_MARK, PORT64_FN0, MSEL1CR_13_1), + + /* Port65 */ + PINMUX_DATA(LCD0_DISP_MARK, PORT65_FN1), + PINMUX_DATA(MSIOF2_TSCK_MARK, PORT65_FN2), + PINMUX_DATA(LCD0_RS_MARK, PORT65_FN4), + + /* Port66 */ + PINMUX_DATA(MEMC_INT_MARK, PORT66_FN1), + PINMUX_DATA(TPU0TO2_PORT66_MARK, PORT66_FN3, MSEL5CR_25_0), + PINMUX_DATA(MMC0_CLK_PORT66_MARK, PORT66_FN4, MSEL4CR_15_0), + PINMUX_DATA(SDHI1_CLK_MARK, PORT66_FN6), + + /* Port67 - Port73 Function1 */ + PINMUX_DATA(MEMC_CS0_MARK, PORT67_FN1), + PINMUX_DATA(MEMC_AD8_MARK, PORT68_FN1), + PINMUX_DATA(MEMC_AD9_MARK, PORT69_FN1), + PINMUX_DATA(MEMC_AD10_MARK, PORT70_FN1), + PINMUX_DATA(MEMC_AD11_MARK, PORT71_FN1), + PINMUX_DATA(MEMC_AD12_MARK, PORT72_FN1), + PINMUX_DATA(MEMC_AD13_MARK, PORT73_FN1), + + /* Port67 - Port73 Function2 */ + PINMUX_DATA(MSIOF1_SS1_PORT67_MARK, PORT67_FN2, MSEL4CR_10_1), + PINMUX_DATA(MSIOF1_RSCK_MARK, PORT68_FN2), + PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT69_FN2), + PINMUX_DATA(MSIOF1_MCK0_MARK, PORT70_FN2), + PINMUX_DATA(MSIOF1_MCK1_MARK, PORT71_FN2), + PINMUX_DATA(MSIOF1_TSCK_PORT72_MARK, PORT72_FN2, MSEL4CR_10_1), + PINMUX_DATA(MSIOF1_TSYNC_PORT73_MARK, PORT73_FN2, MSEL4CR_10_1), + + /* Port67 - Port73 Function4 */ + PINMUX_DATA(MMC0_CMD_PORT67_MARK, PORT67_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D0_PORT68_MARK, PORT68_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D1_PORT69_MARK, PORT69_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D2_PORT70_MARK, PORT70_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D3_PORT71_MARK, PORT71_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D4_PORT72_MARK, PORT72_FN4, MSEL4CR_15_0), + PINMUX_DATA(MMC0_D5_PORT73_MARK, PORT73_FN4, MSEL4CR_15_0), + + /* Port67 - Port73 Function6 */ + PINMUX_DATA(SDHI1_CMD_MARK, PORT67_FN6), + PINMUX_DATA(SDHI1_D0_MARK, PORT68_FN6), + PINMUX_DATA(SDHI1_D1_MARK, PORT69_FN6), + PINMUX_DATA(SDHI1_D2_MARK, PORT70_FN6), + PINMUX_DATA(SDHI1_D3_MARK, PORT71_FN6), + PINMUX_DATA(SDHI1_CD_MARK, PORT72_FN6), + PINMUX_DATA(SDHI1_WP_MARK, PORT73_FN6), + + /* Port67 - Port71 IRQ */ + PINMUX_DATA(IRQ20_MARK, PORT67_FN0), + PINMUX_DATA(IRQ16_PORT68_MARK, PORT68_FN0, MSEL1CR_16_0), + PINMUX_DATA(IRQ17_MARK, PORT69_FN0), + PINMUX_DATA(IRQ18_MARK, PORT70_FN0), + PINMUX_DATA(IRQ19_MARK, PORT71_FN0), + + /* Port74 */ + PINMUX_DATA(MEMC_AD14_MARK, PORT74_FN1), + PINMUX_DATA(MSIOF1_TXD_PORT74_MARK, PORT74_FN2, MSEL4CR_10_1), + PINMUX_DATA(MMC0_D6_PORT74_MARK, PORT74_FN4, MSEL4CR_15_0), + PINMUX_DATA(STP1_IPD7_MARK, PORT74_FN6), + PINMUX_DATA(LCD1_D21_MARK, PORT74_FN7), + + /* Port75 */ + PINMUX_DATA(MEMC_AD15_MARK, PORT75_FN1), + PINMUX_DATA(MSIOF1_RXD_PORT75_MARK, PORT75_FN2, MSEL4CR_10_1), + PINMUX_DATA(MMC0_D7_PORT75_MARK, PORT75_FN4, MSEL4CR_15_0), + PINMUX_DATA(STP1_IPD6_MARK, PORT75_FN6), + PINMUX_DATA(LCD1_D20_MARK, PORT75_FN7), + + /* Port76 - Port80 Function */ + PINMUX_DATA(SDHI0_CMD_MARK, PORT76_FN1), + PINMUX_DATA(SDHI0_D0_MARK, PORT77_FN1), + PINMUX_DATA(SDHI0_D1_MARK, PORT78_FN1), + PINMUX_DATA(SDHI0_D2_MARK, PORT79_FN1), + PINMUX_DATA(SDHI0_D3_MARK, PORT80_FN1), + + /* Port81 */ + PINMUX_DATA(SDHI0_CD_MARK, PORT81_FN1), + PINMUX_DATA(IRQ26_PORT81_MARK, PORT81_FN0, MSEL1CR_26_0), + + /* Port82 - Port88 Function */ + PINMUX_DATA(SDHI0_CLK_MARK, PORT82_FN1), + PINMUX_DATA(SDHI0_WP_MARK, PORT83_FN1), + PINMUX_DATA(RESETOUTS_MARK, PORT84_FN1), + PINMUX_DATA(USB0_PPON_MARK, PORT85_FN1), + PINMUX_DATA(USB0_OCI_MARK, PORT86_FN1), + PINMUX_DATA(USB1_PPON_MARK, PORT87_FN1), + PINMUX_DATA(USB1_OCI_MARK, PORT88_FN1), + + /* Port89 */ + PINMUX_DATA(DREQ0_MARK, PORT89_FN1), + PINMUX_DATA(BBIF2_TSCK2_PORT89_MARK, PORT89_FN2, MSEL5CR_0_1), + PINMUX_DATA(RSPI_SSL3_A_MARK, PORT89_FN6), + + /* Port90 */ + PINMUX_DATA(DACK0_MARK, PORT90_FN1), + PINMUX_DATA(BBIF2_RXD2_PORT90_MARK, PORT90_FN2, MSEL5CR_0_1), + PINMUX_DATA(RSPI_SSL2_A_MARK, PORT90_FN6), + PINMUX_DATA(WAIT_PORT90_MARK, PORT90_FN7, MSEL5CR_2_1), + + /* Port91 */ + PINMUX_DATA(MEMC_AD0_MARK, PORT91_FN1), + PINMUX_DATA(BBIF1_RXD_MARK, PORT91_FN2), + PINMUX_DATA(SCIFA5_TXD_PORT91_MARK, PORT91_FN3, MSEL5CR_15_1, + MSEL5CR_14_0), + PINMUX_DATA(LCD1_D5_MARK, PORT91_FN7), + + /* Port92 */ + PINMUX_DATA(MEMC_AD1_MARK, PORT92_FN1), + PINMUX_DATA(BBIF1_TSYNC_MARK, PORT92_FN2), + PINMUX_DATA(SCIFA5_RXD_PORT92_MARK, PORT92_FN3, MSEL5CR_15_1, + MSEL5CR_14_0), + PINMUX_DATA(STP0_IPD1_MARK, PORT92_FN6), + PINMUX_DATA(LCD1_D6_MARK, PORT92_FN7), + + /* Port93 */ + PINMUX_DATA(MEMC_AD2_MARK, PORT93_FN1), + PINMUX_DATA(BBIF1_TSCK_MARK, PORT93_FN2), + PINMUX_DATA(SCIFA4_TXD_PORT93_MARK, PORT93_FN3, MSEL5CR_12_1, + MSEL5CR_11_0), + PINMUX_DATA(STP0_IPD3_MARK, PORT93_FN6), + PINMUX_DATA(LCD1_D8_MARK, PORT93_FN7), + + /* Port94 */ + PINMUX_DATA(MEMC_AD3_MARK, PORT94_FN1), + PINMUX_DATA(BBIF1_TXD_MARK, PORT94_FN2), + PINMUX_DATA(SCIFA4_RXD_PORT94_MARK, PORT94_FN3, MSEL5CR_12_1, + MSEL5CR_11_0), + PINMUX_DATA(STP0_IPD4_MARK, PORT94_FN6), + PINMUX_DATA(LCD1_D9_MARK, PORT94_FN7), + + /* Port95 */ + PINMUX_DATA(MEMC_CS1_MARK, PORT95_FN1, MSEL4CR_6_0), + PINMUX_DATA(MEMC_A1_MARK, PORT95_FN1, MSEL4CR_6_1), + + PINMUX_DATA(SCIFA2_CTS_MARK, PORT95_FN2), + PINMUX_DATA(SIM_RST_MARK, PORT95_FN4), + PINMUX_DATA(VIO0_D14_PORT95_MARK, PORT95_FN7, MSEL5CR_27_1), + PINMUX_DATA(IRQ22_MARK, PORT95_FN0), + + /* Port96 */ + PINMUX_DATA(MEMC_ADV_MARK, PORT96_FN1, MSEL4CR_6_0), + PINMUX_DATA(MEMC_DREQ0_MARK, PORT96_FN1, MSEL4CR_6_1), + + PINMUX_DATA(SCIFA2_RTS_MARK, PORT96_FN2), + PINMUX_DATA(SIM_CLK_MARK, PORT96_FN4), + PINMUX_DATA(VIO0_D15_PORT96_MARK, PORT96_FN7, MSEL5CR_27_1), + PINMUX_DATA(IRQ23_MARK, PORT96_FN0), + + /* Port97 */ + PINMUX_DATA(MEMC_AD4_MARK, PORT97_FN1), + PINMUX_DATA(BBIF1_RSCK_MARK, PORT97_FN2), + PINMUX_DATA(LCD1_CS_MARK, PORT97_FN6), + PINMUX_DATA(LCD1_HSYN_MARK, PORT97_FN7), + PINMUX_DATA(IRQ12_PORT97_MARK, PORT97_FN0, MSEL1CR_12_0), + + /* Port98 */ + PINMUX_DATA(MEMC_AD5_MARK, PORT98_FN1), + PINMUX_DATA(BBIF1_RSYNC_MARK, PORT98_FN2), + PINMUX_DATA(LCD1_VSYN_MARK, PORT98_FN7), + PINMUX_DATA(IRQ13_PORT98_MARK, PORT98_FN0, MSEL1CR_13_0), + + /* Port99 */ + PINMUX_DATA(MEMC_AD6_MARK, PORT99_FN1), + PINMUX_DATA(BBIF1_FLOW_MARK, PORT99_FN2), + PINMUX_DATA(LCD1_WR_MARK, PORT99_FN6), + PINMUX_DATA(LCD1_DCK_MARK, PORT99_FN7), + PINMUX_DATA(IRQ14_PORT99_MARK, PORT99_FN0, MSEL1CR_14_0), + + /* Port100 */ + PINMUX_DATA(MEMC_AD7_MARK, PORT100_FN1), + PINMUX_DATA(BBIF1_RX_FLOW_N_MARK, PORT100_FN2), + PINMUX_DATA(LCD1_DON_MARK, PORT100_FN7), + PINMUX_DATA(IRQ15_PORT100_MARK, PORT100_FN0, MSEL1CR_15_0), + + /* Port101 */ + PINMUX_DATA(FCE0_MARK, PORT101_FN1), + + /* Port102 */ + PINMUX_DATA(FRB_MARK, PORT102_FN1), + PINMUX_DATA(LCD0_LCLK_PORT102_MARK, PORT102_FN4, MSEL5CR_6_0), + + /* Port103 */ + PINMUX_DATA(CS5B_MARK, PORT103_FN1), + PINMUX_DATA(FCE1_MARK, PORT103_FN2), + PINMUX_DATA(MMC1_CLK_PORT103_MARK, PORT103_FN3, MSEL4CR_15_1), + + /* Port104 */ + PINMUX_DATA(CS6A_MARK, PORT104_FN1), + PINMUX_DATA(MMC1_CMD_PORT104_MARK, PORT104_FN3, MSEL4CR_15_1), + PINMUX_DATA(IRQ11_MARK, PORT104_FN0), + + /* Port105 */ + PINMUX_DATA(CS5A_PORT105_MARK, PORT105_FN1, MSEL5CR_2_0), + PINMUX_DATA(SCIFA3_RTS_PORT105_MARK, PORT105_FN4, MSEL5CR_8_0), + + /* Port106 */ + PINMUX_DATA(IOIS16_MARK, PORT106_FN1), + PINMUX_DATA(IDE_EXBUF_ENB_MARK, PORT106_FN6), + + /* Port107 - Port115 Function */ + PINMUX_DATA(WE3_ICIOWR_MARK, PORT107_FN1), + PINMUX_DATA(WE2_ICIORD_MARK, PORT108_FN1), + PINMUX_DATA(CS0_MARK, PORT109_FN1), + PINMUX_DATA(CS2_MARK, PORT110_FN1), + PINMUX_DATA(CS4_MARK, PORT111_FN1), + PINMUX_DATA(WE1_MARK, PORT112_FN1), + PINMUX_DATA(WE0_FWE_MARK, PORT113_FN1), + PINMUX_DATA(RDWR_MARK, PORT114_FN1), + PINMUX_DATA(RD_FSC_MARK, PORT115_FN1), + + /* Port116 */ + PINMUX_DATA(A25_MARK, PORT116_FN1), + PINMUX_DATA(MSIOF0_SS2_MARK, PORT116_FN2), + PINMUX_DATA(MSIOF1_SS2_PORT116_MARK, PORT116_FN3, MSEL4CR_10_0), + PINMUX_DATA(SCIFA3_SCK_PORT116_MARK, PORT116_FN4, MSEL5CR_8_0), + PINMUX_DATA(GPO1_MARK, PORT116_FN5), + + /* Port117 */ + PINMUX_DATA(A24_MARK, PORT117_FN1), + PINMUX_DATA(MSIOF0_SS1_MARK, PORT117_FN2), + PINMUX_DATA(MSIOF1_SS1_PORT117_MARK, PORT117_FN3, MSEL4CR_10_0), + PINMUX_DATA(SCIFA3_CTS_PORT117_MARK, PORT117_FN4, MSEL5CR_8_0), + PINMUX_DATA(GPO0_MARK, PORT117_FN5), + + /* Port118 */ + PINMUX_DATA(A23_MARK, PORT118_FN1), + PINMUX_DATA(MSIOF0_MCK1_MARK, PORT118_FN2), + PINMUX_DATA(MSIOF1_RXD_PORT118_MARK, PORT118_FN3, MSEL4CR_10_0), + PINMUX_DATA(GPI1_MARK, PORT118_FN5), + PINMUX_DATA(IRQ9_PORT118_MARK, PORT118_FN0, MSEL1CR_9_0), + + /* Port119 */ + PINMUX_DATA(A22_MARK, PORT119_FN1), + PINMUX_DATA(MSIOF0_MCK0_MARK, PORT119_FN2), + PINMUX_DATA(MSIOF1_TXD_PORT119_MARK, PORT119_FN3, MSEL4CR_10_0), + PINMUX_DATA(GPI0_MARK, PORT119_FN5), + PINMUX_DATA(IRQ8_MARK, PORT119_FN0), + + /* Port120 */ + PINMUX_DATA(A21_MARK, PORT120_FN1), + PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2), + PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0), + PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0), + + /* Port121 */ + PINMUX_DATA(A20_MARK, PORT121_FN1), + PINMUX_DATA(MSIOF0_RSCK_MARK, PORT121_FN2), + PINMUX_DATA(MSIOF1_TSCK_PORT121_MARK, PORT121_FN3, MSEL4CR_10_0), + PINMUX_DATA(IRQ6_PORT121_MARK, PORT121_FN0, MSEL1CR_6_0), + + /* Port122 */ + PINMUX_DATA(A19_MARK, PORT122_FN1), + PINMUX_DATA(MSIOF0_RXD_MARK, PORT122_FN2), + + /* Port123 */ + PINMUX_DATA(A18_MARK, PORT123_FN1), + PINMUX_DATA(MSIOF0_TSCK_MARK, PORT123_FN2), + + /* Port124 */ + PINMUX_DATA(A17_MARK, PORT124_FN1), + PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT124_FN2), + + /* Port125 - Port141 Function */ + PINMUX_DATA(A16_MARK, PORT125_FN1), + PINMUX_DATA(A15_MARK, PORT126_FN1), + PINMUX_DATA(A14_MARK, PORT127_FN1), + PINMUX_DATA(A13_MARK, PORT128_FN1), + PINMUX_DATA(A12_MARK, PORT129_FN1), + PINMUX_DATA(A11_MARK, PORT130_FN1), + PINMUX_DATA(A10_MARK, PORT131_FN1), + PINMUX_DATA(A9_MARK, PORT132_FN1), + PINMUX_DATA(A8_MARK, PORT133_FN1), + PINMUX_DATA(A7_MARK, PORT134_FN1), + PINMUX_DATA(A6_MARK, PORT135_FN1), + PINMUX_DATA(A5_FCDE_MARK, PORT136_FN1), + PINMUX_DATA(A4_FOE_MARK, PORT137_FN1), + PINMUX_DATA(A3_MARK, PORT138_FN1), + PINMUX_DATA(A2_MARK, PORT139_FN1), + PINMUX_DATA(A1_MARK, PORT140_FN1), + PINMUX_DATA(CKO_MARK, PORT141_FN1), + + /* Port142 - Port157 Function1 */ + PINMUX_DATA(D15_NAF15_MARK, PORT142_FN1), + PINMUX_DATA(D14_NAF14_MARK, PORT143_FN1), + PINMUX_DATA(D13_NAF13_MARK, PORT144_FN1), + PINMUX_DATA(D12_NAF12_MARK, PORT145_FN1), + PINMUX_DATA(D11_NAF11_MARK, PORT146_FN1), + PINMUX_DATA(D10_NAF10_MARK, PORT147_FN1), + PINMUX_DATA(D9_NAF9_MARK, PORT148_FN1), + PINMUX_DATA(D8_NAF8_MARK, PORT149_FN1), + PINMUX_DATA(D7_NAF7_MARK, PORT150_FN1), + PINMUX_DATA(D6_NAF6_MARK, PORT151_FN1), + PINMUX_DATA(D5_NAF5_MARK, PORT152_FN1), + PINMUX_DATA(D4_NAF4_MARK, PORT153_FN1), + PINMUX_DATA(D3_NAF3_MARK, PORT154_FN1), + PINMUX_DATA(D2_NAF2_MARK, PORT155_FN1), + PINMUX_DATA(D1_NAF1_MARK, PORT156_FN1), + PINMUX_DATA(D0_NAF0_MARK, PORT157_FN1), + + /* Port142 - Port149 Function3 */ + PINMUX_DATA(MMC1_D7_PORT142_MARK, PORT142_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D6_PORT143_MARK, PORT143_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D5_PORT144_MARK, PORT144_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D4_PORT145_MARK, PORT145_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D3_PORT146_MARK, PORT146_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D2_PORT147_MARK, PORT147_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D1_PORT148_MARK, PORT148_FN3, MSEL4CR_15_1), + PINMUX_DATA(MMC1_D0_PORT149_MARK, PORT149_FN3, MSEL4CR_15_1), + + /* Port158 */ + PINMUX_DATA(D31_MARK, PORT158_FN1), + PINMUX_DATA(SCIFA3_SCK_PORT158_MARK, PORT158_FN2, MSEL5CR_8_1), + PINMUX_DATA(RMII_REF125CK_MARK, PORT158_FN3), + PINMUX_DATA(LCD0_D21_PORT158_MARK, PORT158_FN4, MSEL5CR_6_1), + PINMUX_DATA(IRDA_FIRSEL_MARK, PORT158_FN5), + PINMUX_DATA(IDE_D15_MARK, PORT158_FN6), + + /* Port159 */ + PINMUX_DATA(D30_MARK, PORT159_FN1), + PINMUX_DATA(SCIFA3_RXD_PORT159_MARK, PORT159_FN2, MSEL5CR_8_1), + PINMUX_DATA(RMII_REF50CK_MARK, PORT159_FN3), + PINMUX_DATA(LCD0_D23_PORT159_MARK, PORT159_FN4, MSEL5CR_6_1), + PINMUX_DATA(IDE_D14_MARK, PORT159_FN6), + + /* Port160 */ + PINMUX_DATA(D29_MARK, PORT160_FN1), + PINMUX_DATA(SCIFA3_TXD_PORT160_MARK, PORT160_FN2, MSEL5CR_8_1), + PINMUX_DATA(LCD0_D22_PORT160_MARK, PORT160_FN4, MSEL5CR_6_1), + PINMUX_DATA(VIO1_HD_MARK, PORT160_FN5), + PINMUX_DATA(IDE_D13_MARK, PORT160_FN6), + + /* Port161 */ + PINMUX_DATA(D28_MARK, PORT161_FN1), + PINMUX_DATA(SCIFA3_RTS_PORT161_MARK, PORT161_FN2, MSEL5CR_8_1), + PINMUX_DATA(ET_RX_DV_MARK, PORT161_FN3), + PINMUX_DATA(LCD0_D20_PORT161_MARK, PORT161_FN4, MSEL5CR_6_1), + PINMUX_DATA(IRDA_IN_MARK, PORT161_FN5), + PINMUX_DATA(IDE_D12_MARK, PORT161_FN6), + + /* Port162 */ + PINMUX_DATA(D27_MARK, PORT162_FN1), + PINMUX_DATA(SCIFA3_CTS_PORT162_MARK, PORT162_FN2, MSEL5CR_8_1), + PINMUX_DATA(LCD0_D19_PORT162_MARK, PORT162_FN4, MSEL5CR_6_1), + PINMUX_DATA(IRDA_OUT_MARK, PORT162_FN5), + PINMUX_DATA(IDE_D11_MARK, PORT162_FN6), + + /* Port163 */ + PINMUX_DATA(D26_MARK, PORT163_FN1), + PINMUX_DATA(MSIOF2_SS2_MARK, PORT163_FN2), + PINMUX_DATA(ET_COL_MARK, PORT163_FN3), + PINMUX_DATA(LCD0_D18_PORT163_MARK, PORT163_FN4, MSEL5CR_6_1), + PINMUX_DATA(IROUT_MARK, PORT163_FN5), + PINMUX_DATA(IDE_D10_MARK, PORT163_FN6), + + /* Port164 */ + PINMUX_DATA(D25_MARK, PORT164_FN1), + PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT164_FN2), + PINMUX_DATA(ET_PHY_INT_MARK, PORT164_FN3), + PINMUX_DATA(LCD0_RD_MARK, PORT164_FN4), + PINMUX_DATA(IDE_D9_MARK, PORT164_FN6), + + /* Port165 */ + PINMUX_DATA(D24_MARK, PORT165_FN1), + PINMUX_DATA(MSIOF2_RXD_MARK, PORT165_FN2), + PINMUX_DATA(LCD0_LCLK_PORT165_MARK, PORT165_FN4, MSEL5CR_6_1), + PINMUX_DATA(IDE_D8_MARK, PORT165_FN6), + + /* Port166 - Port171 Function1 */ + PINMUX_DATA(D21_MARK, PORT166_FN1), + PINMUX_DATA(D20_MARK, PORT167_FN1), + PINMUX_DATA(D19_MARK, PORT168_FN1), + PINMUX_DATA(D18_MARK, PORT169_FN1), + PINMUX_DATA(D17_MARK, PORT170_FN1), + PINMUX_DATA(D16_MARK, PORT171_FN1), + + /* Port166 - Port171 Function3 */ + PINMUX_DATA(ET_ETXD5_MARK, PORT166_FN3), + PINMUX_DATA(ET_ETXD4_MARK, PORT167_FN3), + PINMUX_DATA(ET_ETXD3_MARK, PORT168_FN3), + PINMUX_DATA(ET_ETXD2_MARK, PORT169_FN3), + PINMUX_DATA(ET_ETXD1_MARK, PORT170_FN3), + PINMUX_DATA(ET_ETXD0_MARK, PORT171_FN3), + + /* Port166 - Port171 Function6 */ + PINMUX_DATA(IDE_D5_MARK, PORT166_FN6), + PINMUX_DATA(IDE_D4_MARK, PORT167_FN6), + PINMUX_DATA(IDE_D3_MARK, PORT168_FN6), + PINMUX_DATA(IDE_D2_MARK, PORT169_FN6), + PINMUX_DATA(IDE_D1_MARK, PORT170_FN6), + PINMUX_DATA(IDE_D0_MARK, PORT171_FN6), + + /* Port167 - Port171 IRQ */ + PINMUX_DATA(IRQ31_PORT167_MARK, PORT167_FN0, MSEL1CR_31_0), + PINMUX_DATA(IRQ27_PORT168_MARK, PORT168_FN0, MSEL1CR_27_0), + PINMUX_DATA(IRQ28_PORT169_MARK, PORT169_FN0, MSEL1CR_28_0), + PINMUX_DATA(IRQ29_PORT170_MARK, PORT170_FN0, MSEL1CR_29_0), + PINMUX_DATA(IRQ30_PORT171_MARK, PORT171_FN0, MSEL1CR_30_0), + + /* Port172 */ + PINMUX_DATA(D23_MARK, PORT172_FN1), + PINMUX_DATA(SCIFB_RTS_PORT172_MARK, PORT172_FN2, MSEL5CR_17_1), + PINMUX_DATA(ET_ETXD7_MARK, PORT172_FN3), + PINMUX_DATA(IDE_D7_MARK, PORT172_FN6), + PINMUX_DATA(IRQ4_PORT172_MARK, PORT172_FN0, MSEL1CR_4_1), + + /* Port173 */ + PINMUX_DATA(D22_MARK, PORT173_FN1), + PINMUX_DATA(SCIFB_CTS_PORT173_MARK, PORT173_FN2, MSEL5CR_17_1), + PINMUX_DATA(ET_ETXD6_MARK, PORT173_FN3), + PINMUX_DATA(IDE_D6_MARK, PORT173_FN6), + PINMUX_DATA(IRQ6_PORT173_MARK, PORT173_FN0, MSEL1CR_6_1), + + /* Port174 */ + PINMUX_DATA(A26_MARK, PORT174_FN1), + PINMUX_DATA(MSIOF0_TXD_MARK, PORT174_FN2), + PINMUX_DATA(ET_RX_CLK_MARK, PORT174_FN3), + PINMUX_DATA(SCIFA3_RXD_PORT174_MARK, PORT174_FN4, MSEL5CR_8_0), + + /* Port175 */ + PINMUX_DATA(A0_MARK, PORT175_FN1), + PINMUX_DATA(BS_MARK, PORT175_FN2), + PINMUX_DATA(ET_WOL_MARK, PORT175_FN3), + PINMUX_DATA(SCIFA3_TXD_PORT175_MARK, PORT175_FN4, MSEL5CR_8_0), + + /* Port176 */ + PINMUX_DATA(ET_GTX_CLK_MARK, PORT176_FN3), + + /* Port177 */ + PINMUX_DATA(WAIT_PORT177_MARK, PORT177_FN1, MSEL5CR_2_0), + PINMUX_DATA(ET_LINK_MARK, PORT177_FN3), + PINMUX_DATA(IDE_IOWR_MARK, PORT177_FN6), + PINMUX_DATA(SDHI2_WP_PORT177_MARK, PORT177_FN7, MSEL5CR_19_1), + + /* Port178 */ + PINMUX_DATA(VIO0_D12_MARK, PORT178_FN1), + PINMUX_DATA(VIO1_D4_MARK, PORT178_FN5), + PINMUX_DATA(IDE_IORD_MARK, PORT178_FN6), + + /* Port179 */ + PINMUX_DATA(VIO0_D11_MARK, PORT179_FN1), + PINMUX_DATA(VIO1_D3_MARK, PORT179_FN5), + PINMUX_DATA(IDE_IORDY_MARK, PORT179_FN6), + + /* Port180 */ + PINMUX_DATA(VIO0_D10_MARK, PORT180_FN1), + PINMUX_DATA(TPU0TO3_MARK, PORT180_FN4), + PINMUX_DATA(VIO1_D2_MARK, PORT180_FN5), + PINMUX_DATA(IDE_INT_MARK, PORT180_FN6), + PINMUX_DATA(IRQ24_MARK, PORT180_FN0), + + /* Port181 */ + PINMUX_DATA(VIO0_D9_MARK, PORT181_FN1), + PINMUX_DATA(VIO1_D1_MARK, PORT181_FN5), + PINMUX_DATA(IDE_RST_MARK, PORT181_FN6), + + /* Port182 */ + PINMUX_DATA(VIO0_D8_MARK, PORT182_FN1), + PINMUX_DATA(VIO1_D0_MARK, PORT182_FN5), + PINMUX_DATA(IDE_DIRECTION_MARK, PORT182_FN6), + + /* Port183 */ + PINMUX_DATA(DREQ1_MARK, PORT183_FN1), + PINMUX_DATA(BBIF2_TXD2_PORT183_MARK, PORT183_FN2, MSEL5CR_0_1), + PINMUX_DATA(ET_TX_EN_MARK, PORT183_FN3), + + /* Port184 */ + PINMUX_DATA(DACK1_MARK, PORT184_FN1), + PINMUX_DATA(BBIF2_TSYNC2_PORT184_MARK, PORT184_FN2, MSEL5CR_0_1), + PINMUX_DATA(ET_TX_CLK_MARK, PORT184_FN3), + + /* Port185 - Port192 Function1 */ + PINMUX_DATA(SCIFA1_SCK_MARK, PORT185_FN1), + PINMUX_DATA(SCIFB_RTS_PORT186_MARK, PORT186_FN1, MSEL5CR_17_0), + PINMUX_DATA(SCIFB_CTS_PORT187_MARK, PORT187_FN1, MSEL5CR_17_0), + PINMUX_DATA(SCIFA0_SCK_MARK, PORT188_FN1), + PINMUX_DATA(SCIFB_SCK_PORT190_MARK, PORT190_FN1, MSEL5CR_17_0), + PINMUX_DATA(SCIFB_RXD_PORT191_MARK, PORT191_FN1, MSEL5CR_17_0), + PINMUX_DATA(SCIFB_TXD_PORT192_MARK, PORT192_FN1, MSEL5CR_17_0), + + /* Port185 - Port192 Function3 */ + PINMUX_DATA(ET_ERXD0_MARK, PORT185_FN3), + PINMUX_DATA(ET_ERXD1_MARK, PORT186_FN3), + PINMUX_DATA(ET_ERXD2_MARK, PORT187_FN3), + PINMUX_DATA(ET_ERXD3_MARK, PORT188_FN3), + PINMUX_DATA(ET_ERXD4_MARK, PORT189_FN3), + PINMUX_DATA(ET_ERXD5_MARK, PORT190_FN3), + PINMUX_DATA(ET_ERXD6_MARK, PORT191_FN3), + PINMUX_DATA(ET_ERXD7_MARK, PORT192_FN3), + + /* Port185 - Port192 Function6 */ + PINMUX_DATA(STP1_IPCLK_MARK, PORT185_FN6), + PINMUX_DATA(STP1_IPD0_PORT186_MARK, PORT186_FN6, MSEL5CR_23_0), + PINMUX_DATA(STP1_IPEN_PORT187_MARK, PORT187_FN6, MSEL5CR_23_0), + PINMUX_DATA(STP1_IPSYNC_MARK, PORT188_FN6), + PINMUX_DATA(STP0_IPCLK_MARK, PORT189_FN6), + PINMUX_DATA(STP0_IPD0_MARK, PORT190_FN6), + PINMUX_DATA(STP0_IPEN_MARK, PORT191_FN6), + PINMUX_DATA(STP0_IPSYNC_MARK, PORT192_FN6), + + /* Port193 */ + PINMUX_DATA(SCIFA0_CTS_MARK, PORT193_FN1), + PINMUX_DATA(RMII_CRS_DV_MARK, PORT193_FN3), + PINMUX_DATA(STP1_IPEN_PORT193_MARK, PORT193_FN6, MSEL5CR_23_1), + PINMUX_DATA(LCD1_D17_MARK, PORT193_FN7), + + /* Port194 */ + PINMUX_DATA(SCIFA0_RTS_MARK, PORT194_FN1), + PINMUX_DATA(RMII_RX_ER_MARK, PORT194_FN3), + PINMUX_DATA(STP1_IPD0_PORT194_MARK, PORT194_FN6, MSEL5CR_23_1), + PINMUX_DATA(LCD1_D16_MARK, PORT194_FN7), + + /* Port195 */ + PINMUX_DATA(SCIFA1_RXD_MARK, PORT195_FN1), + PINMUX_DATA(RMII_RXD0_MARK, PORT195_FN3), + PINMUX_DATA(STP1_IPD3_MARK, PORT195_FN6), + PINMUX_DATA(LCD1_D15_MARK, PORT195_FN7), + + /* Port196 */ + PINMUX_DATA(SCIFA1_TXD_MARK, PORT196_FN1), + PINMUX_DATA(RMII_RXD1_MARK, PORT196_FN3), + PINMUX_DATA(STP1_IPD2_MARK, PORT196_FN6), + PINMUX_DATA(LCD1_D14_MARK, PORT196_FN7), + + /* Port197 */ + PINMUX_DATA(SCIFA0_RXD_MARK, PORT197_FN1), + PINMUX_DATA(VIO1_CLK_MARK, PORT197_FN5), + PINMUX_DATA(STP1_IPD5_MARK, PORT197_FN6), + PINMUX_DATA(LCD1_D19_MARK, PORT197_FN7), + + /* Port198 */ + PINMUX_DATA(SCIFA0_TXD_MARK, PORT198_FN1), + PINMUX_DATA(VIO1_VD_MARK, PORT198_FN5), + PINMUX_DATA(STP1_IPD4_MARK, PORT198_FN6), + PINMUX_DATA(LCD1_D18_MARK, PORT198_FN7), + + /* Port199 */ + PINMUX_DATA(MEMC_NWE_MARK, PORT199_FN1), + PINMUX_DATA(SCIFA2_SCK_PORT199_MARK, PORT199_FN2, MSEL5CR_7_1), + PINMUX_DATA(RMII_TX_EN_MARK, PORT199_FN3), + PINMUX_DATA(SIM_D_PORT199_MARK, PORT199_FN4, MSEL5CR_21_1), + PINMUX_DATA(STP1_IPD1_MARK, PORT199_FN6), + PINMUX_DATA(LCD1_D13_MARK, PORT199_FN7), + + /* Port200 */ + PINMUX_DATA(MEMC_NOE_MARK, PORT200_FN1), + PINMUX_DATA(SCIFA2_RXD_MARK, PORT200_FN2), + PINMUX_DATA(RMII_TXD0_MARK, PORT200_FN3), + PINMUX_DATA(STP0_IPD7_MARK, PORT200_FN6), + PINMUX_DATA(LCD1_D12_MARK, PORT200_FN7), + + /* Port201 */ + PINMUX_DATA(MEMC_WAIT_MARK, PORT201_FN1, MSEL4CR_6_0), + PINMUX_DATA(MEMC_DREQ1_MARK, PORT201_FN1, MSEL4CR_6_1), + + PINMUX_DATA(SCIFA2_TXD_MARK, PORT201_FN2), + PINMUX_DATA(RMII_TXD1_MARK, PORT201_FN3), + PINMUX_DATA(STP0_IPD6_MARK, PORT201_FN6), + PINMUX_DATA(LCD1_D11_MARK, PORT201_FN7), + + /* Port202 */ + PINMUX_DATA(MEMC_BUSCLK_MARK, PORT202_FN1, MSEL4CR_6_0), + PINMUX_DATA(MEMC_A0_MARK, PORT202_FN1, MSEL4CR_6_1), + + PINMUX_DATA(MSIOF1_SS2_PORT202_MARK, PORT202_FN2, MSEL4CR_10_1), + PINMUX_DATA(RMII_MDC_MARK, PORT202_FN3), + PINMUX_DATA(TPU0TO2_PORT202_MARK, PORT202_FN4, MSEL5CR_25_1), + PINMUX_DATA(IDE_CS0_MARK, PORT202_FN6), + PINMUX_DATA(SDHI2_CD_PORT202_MARK, PORT202_FN7, MSEL5CR_19_1), + PINMUX_DATA(IRQ21_MARK, PORT202_FN0), + + /* Port203 - Port208 Function1 */ + PINMUX_DATA(SDHI2_CLK_MARK, PORT203_FN1), + PINMUX_DATA(SDHI2_CMD_MARK, PORT204_FN1), + PINMUX_DATA(SDHI2_D0_MARK, PORT205_FN1), + PINMUX_DATA(SDHI2_D1_MARK, PORT206_FN1), + PINMUX_DATA(SDHI2_D2_MARK, PORT207_FN1), + PINMUX_DATA(SDHI2_D3_MARK, PORT208_FN1), + + /* Port203 - Port208 Function3 */ + PINMUX_DATA(ET_TX_ER_MARK, PORT203_FN3), + PINMUX_DATA(ET_RX_ER_MARK, PORT204_FN3), + PINMUX_DATA(ET_CRS_MARK, PORT205_FN3), + PINMUX_DATA(ET_MDC_MARK, PORT206_FN3), + PINMUX_DATA(ET_MDIO_MARK, PORT207_FN3), + PINMUX_DATA(RMII_MDIO_MARK, PORT208_FN3), + + /* Port203 - Port208 Function6 */ + PINMUX_DATA(IDE_A2_MARK, PORT203_FN6), + PINMUX_DATA(IDE_A1_MARK, PORT204_FN6), + PINMUX_DATA(IDE_A0_MARK, PORT205_FN6), + PINMUX_DATA(IDE_IODACK_MARK, PORT206_FN6), + PINMUX_DATA(IDE_IODREQ_MARK, PORT207_FN6), + PINMUX_DATA(IDE_CS1_MARK, PORT208_FN6), + + /* Port203 - Port208 Function7 */ + PINMUX_DATA(SCIFA4_TXD_PORT203_MARK, PORT203_FN7, MSEL5CR_12_0, + MSEL5CR_11_1), + PINMUX_DATA(SCIFA4_RXD_PORT204_MARK, PORT204_FN7, MSEL5CR_12_0, + MSEL5CR_11_1), + PINMUX_DATA(SCIFA4_SCK_PORT205_MARK, PORT205_FN7, MSEL5CR_10_1), + PINMUX_DATA(SCIFA5_SCK_PORT206_MARK, PORT206_FN7, MSEL5CR_13_1), + PINMUX_DATA(SCIFA5_RXD_PORT207_MARK, PORT207_FN7, MSEL5CR_15_0, + MSEL5CR_14_1), + PINMUX_DATA(SCIFA5_TXD_PORT208_MARK, PORT208_FN7, MSEL5CR_15_0, + MSEL5CR_14_1), + + /* Port209 */ + PINMUX_DATA(VBUS_MARK, PORT209_FN1), + PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1), + + /* Port210 */ + PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1), + + /* Port211 */ + PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1), + + /* LCDC select */ + PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0), + PINMUX_DATA(LCDC1_SELECT_MARK, MSEL3CR_6_1), + + /* SDENC */ + PINMUX_DATA(SDENC_CPG_MARK, MSEL4CR_19_0), + PINMUX_DATA(SDENC_DV_CLKI_MARK, MSEL4CR_19_1), + + /* SYSC */ + PINMUX_DATA(RESETP_PULLUP_MARK, MSEL4CR_4_0), + PINMUX_DATA(RESETP_PLAIN_MARK, MSEL4CR_4_1), + + /* DEBUG */ + PINMUX_DATA(EDEBGREQ_PULLDOWN_MARK, MSEL4CR_1_0), + PINMUX_DATA(EDEBGREQ_PULLUP_MARK, MSEL4CR_1_1), + + PINMUX_DATA(TRACEAUD_FROM_VIO_MARK, MSEL5CR_30_0, MSEL5CR_29_0), + PINMUX_DATA(TRACEAUD_FROM_LCDC0_MARK, MSEL5CR_30_0, MSEL5CR_29_1), + PINMUX_DATA(TRACEAUD_FROM_MEMC_MARK, MSEL5CR_30_1, MSEL5CR_29_0), +}; + +static struct pinmux_gpio pinmux_gpios[] = { + + /* PORT */ + GPIO_PORT_ALL(), + + /* IRQ */ + GPIO_FN(IRQ0_PORT2), GPIO_FN(IRQ0_PORT13), + GPIO_FN(IRQ1), + GPIO_FN(IRQ2_PORT11), GPIO_FN(IRQ2_PORT12), + GPIO_FN(IRQ3_PORT10), GPIO_FN(IRQ3_PORT14), + GPIO_FN(IRQ4_PORT15), GPIO_FN(IRQ4_PORT172), + GPIO_FN(IRQ5_PORT0), GPIO_FN(IRQ5_PORT1), + GPIO_FN(IRQ6_PORT121), GPIO_FN(IRQ6_PORT173), + GPIO_FN(IRQ7_PORT120), GPIO_FN(IRQ7_PORT209), + GPIO_FN(IRQ8), + GPIO_FN(IRQ9_PORT118), GPIO_FN(IRQ9_PORT210), + GPIO_FN(IRQ10), + GPIO_FN(IRQ11), + GPIO_FN(IRQ12_PORT42), GPIO_FN(IRQ12_PORT97), + GPIO_FN(IRQ13_PORT64), GPIO_FN(IRQ13_PORT98), + GPIO_FN(IRQ14_PORT63), GPIO_FN(IRQ14_PORT99), + GPIO_FN(IRQ15_PORT62), GPIO_FN(IRQ15_PORT100), + GPIO_FN(IRQ16_PORT68), GPIO_FN(IRQ16_PORT211), + GPIO_FN(IRQ17), + GPIO_FN(IRQ18), + GPIO_FN(IRQ19), + GPIO_FN(IRQ20), + GPIO_FN(IRQ21), + GPIO_FN(IRQ22), + GPIO_FN(IRQ23), + GPIO_FN(IRQ24), + GPIO_FN(IRQ25), + GPIO_FN(IRQ26_PORT58), GPIO_FN(IRQ26_PORT81), + GPIO_FN(IRQ27_PORT57), GPIO_FN(IRQ27_PORT168), + GPIO_FN(IRQ28_PORT56), GPIO_FN(IRQ28_PORT169), + GPIO_FN(IRQ29_PORT50), GPIO_FN(IRQ29_PORT170), + GPIO_FN(IRQ30_PORT49), GPIO_FN(IRQ30_PORT171), + GPIO_FN(IRQ31_PORT41), GPIO_FN(IRQ31_PORT167), + + /* Function */ + + /* DBGT */ + GPIO_FN(DBGMDT2), GPIO_FN(DBGMDT1), GPIO_FN(DBGMDT0), + GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20), + GPIO_FN(DBGMD21), + + /* FSI */ + GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */ + GPIO_FN(FSIAISLD_PORT5), + GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */ + GPIO_FN(FSIASPDIF_PORT18), + GPIO_FN(FSIAOSLD1), GPIO_FN(FSIAOSLD2), GPIO_FN(FSIAOLR), + GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC), + GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT), + + /* FMSI */ + GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */ + GPIO_FN(FMSISLD_PORT6), + GPIO_FN(FMSIILR), GPIO_FN(FMSIIBT), GPIO_FN(FMSIOLR), + GPIO_FN(FMSIOBT), GPIO_FN(FMSICK), GPIO_FN(FMSOILR), + GPIO_FN(FMSOIBT), GPIO_FN(FMSOOLR), GPIO_FN(FMSOOBT), + GPIO_FN(FMSOSLD), GPIO_FN(FMSOCK), + + /* SCIFA0 */ + GPIO_FN(SCIFA0_SCK), GPIO_FN(SCIFA0_CTS), GPIO_FN(SCIFA0_RTS), + GPIO_FN(SCIFA0_RXD), GPIO_FN(SCIFA0_TXD), + + /* SCIFA1 */ + GPIO_FN(SCIFA1_CTS), GPIO_FN(SCIFA1_SCK), + GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_TXD), GPIO_FN(SCIFA1_RTS), + + /* SCIFA2 */ + GPIO_FN(SCIFA2_SCK_PORT22), /* SCIFA2_SCK Port 22/199 */ + GPIO_FN(SCIFA2_SCK_PORT199), + GPIO_FN(SCIFA2_RXD), GPIO_FN(SCIFA2_TXD), + GPIO_FN(SCIFA2_CTS), GPIO_FN(SCIFA2_RTS), + + /* SCIFA3 */ + GPIO_FN(SCIFA3_RTS_PORT105), /* MSEL5CR_8_0 */ + GPIO_FN(SCIFA3_SCK_PORT116), + GPIO_FN(SCIFA3_CTS_PORT117), + GPIO_FN(SCIFA3_RXD_PORT174), + GPIO_FN(SCIFA3_TXD_PORT175), + + GPIO_FN(SCIFA3_RTS_PORT161), /* MSEL5CR_8_1 */ + GPIO_FN(SCIFA3_SCK_PORT158), + GPIO_FN(SCIFA3_CTS_PORT162), + GPIO_FN(SCIFA3_RXD_PORT159), + GPIO_FN(SCIFA3_TXD_PORT160), + + /* SCIFA4 */ + GPIO_FN(SCIFA4_RXD_PORT12), /* MSEL5CR[12:11] = 00 */ + GPIO_FN(SCIFA4_TXD_PORT13), + + GPIO_FN(SCIFA4_RXD_PORT204), /* MSEL5CR[12:11] = 01 */ + GPIO_FN(SCIFA4_TXD_PORT203), + + GPIO_FN(SCIFA4_RXD_PORT94), /* MSEL5CR[12:11] = 10 */ + GPIO_FN(SCIFA4_TXD_PORT93), + + GPIO_FN(SCIFA4_SCK_PORT21), /* SCIFA4_SCK Port 21/205 */ + GPIO_FN(SCIFA4_SCK_PORT205), + + /* SCIFA5 */ + GPIO_FN(SCIFA5_TXD_PORT20), /* MSEL5CR[15:14] = 00 */ + GPIO_FN(SCIFA5_RXD_PORT10), + + GPIO_FN(SCIFA5_RXD_PORT207), /* MSEL5CR[15:14] = 01 */ + GPIO_FN(SCIFA5_TXD_PORT208), + + GPIO_FN(SCIFA5_TXD_PORT91), /* MSEL5CR[15:14] = 10 */ + GPIO_FN(SCIFA5_RXD_PORT92), + + GPIO_FN(SCIFA5_SCK_PORT23), /* SCIFA5_SCK Port 23/206 */ + GPIO_FN(SCIFA5_SCK_PORT206), + + /* SCIFA6 */ + GPIO_FN(SCIFA6_SCK), GPIO_FN(SCIFA6_RXD), GPIO_FN(SCIFA6_TXD), + + /* SCIFA7 */ + GPIO_FN(SCIFA7_TXD), GPIO_FN(SCIFA7_RXD), + + /* SCIFAB */ + GPIO_FN(SCIFB_SCK_PORT190), /* MSEL5CR_17_0 */ + GPIO_FN(SCIFB_RXD_PORT191), + GPIO_FN(SCIFB_TXD_PORT192), + GPIO_FN(SCIFB_RTS_PORT186), + GPIO_FN(SCIFB_CTS_PORT187), + + GPIO_FN(SCIFB_SCK_PORT2), /* MSEL5CR_17_1 */ + GPIO_FN(SCIFB_RXD_PORT3), + GPIO_FN(SCIFB_TXD_PORT4), + GPIO_FN(SCIFB_RTS_PORT172), + GPIO_FN(SCIFB_CTS_PORT173), + + /* LCD0 */ + GPIO_FN(LCD0_D0), GPIO_FN(LCD0_D1), GPIO_FN(LCD0_D2), + GPIO_FN(LCD0_D3), GPIO_FN(LCD0_D4), GPIO_FN(LCD0_D5), + GPIO_FN(LCD0_D6), GPIO_FN(LCD0_D7), GPIO_FN(LCD0_D8), + GPIO_FN(LCD0_D9), GPIO_FN(LCD0_D10), GPIO_FN(LCD0_D11), + GPIO_FN(LCD0_D12), GPIO_FN(LCD0_D13), GPIO_FN(LCD0_D14), + GPIO_FN(LCD0_D15), GPIO_FN(LCD0_D16), GPIO_FN(LCD0_D17), + GPIO_FN(LCD0_DON), GPIO_FN(LCD0_VCPWC), GPIO_FN(LCD0_VEPWC), + GPIO_FN(LCD0_DCK), GPIO_FN(LCD0_VSYN), + GPIO_FN(LCD0_HSYN), GPIO_FN(LCD0_DISP), + GPIO_FN(LCD0_WR), GPIO_FN(LCD0_RD), + GPIO_FN(LCD0_CS), GPIO_FN(LCD0_RS), + + GPIO_FN(LCD0_D18_PORT163), GPIO_FN(LCD0_D19_PORT162), + GPIO_FN(LCD0_D20_PORT161), GPIO_FN(LCD0_D21_PORT158), + GPIO_FN(LCD0_D22_PORT160), GPIO_FN(LCD0_D23_PORT159), + GPIO_FN(LCD0_LCLK_PORT165), /* MSEL5CR_6_1 */ + + GPIO_FN(LCD0_D18_PORT40), GPIO_FN(LCD0_D19_PORT4), + GPIO_FN(LCD0_D20_PORT3), GPIO_FN(LCD0_D21_PORT2), + GPIO_FN(LCD0_D22_PORT0), GPIO_FN(LCD0_D23_PORT1), + GPIO_FN(LCD0_LCLK_PORT102), /* MSEL5CR_6_0 */ + + /* LCD1 */ + GPIO_FN(LCD1_D0), GPIO_FN(LCD1_D1), GPIO_FN(LCD1_D2), + GPIO_FN(LCD1_D3), GPIO_FN(LCD1_D4), GPIO_FN(LCD1_D5), + GPIO_FN(LCD1_D6), GPIO_FN(LCD1_D7), GPIO_FN(LCD1_D8), + GPIO_FN(LCD1_D9), GPIO_FN(LCD1_D10), GPIO_FN(LCD1_D11), + GPIO_FN(LCD1_D12), GPIO_FN(LCD1_D13), GPIO_FN(LCD1_D14), + GPIO_FN(LCD1_D15), GPIO_FN(LCD1_D16), GPIO_FN(LCD1_D17), + GPIO_FN(LCD1_D18), GPIO_FN(LCD1_D19), GPIO_FN(LCD1_D20), + GPIO_FN(LCD1_D21), GPIO_FN(LCD1_D22), GPIO_FN(LCD1_D23), + GPIO_FN(LCD1_RS), GPIO_FN(LCD1_RD), GPIO_FN(LCD1_CS), + GPIO_FN(LCD1_WR), GPIO_FN(LCD1_DCK), GPIO_FN(LCD1_DON), + GPIO_FN(LCD1_VCPWC), GPIO_FN(LCD1_LCLK), GPIO_FN(LCD1_HSYN), + GPIO_FN(LCD1_VSYN), GPIO_FN(LCD1_VEPWC), GPIO_FN(LCD1_DISP), + + /* RSPI */ + GPIO_FN(RSPI_SSL0_A), GPIO_FN(RSPI_SSL1_A), GPIO_FN(RSPI_SSL2_A), + GPIO_FN(RSPI_SSL3_A), GPIO_FN(RSPI_CK_A), GPIO_FN(RSPI_MOSI_A), + GPIO_FN(RSPI_MISO_A), + + /* VIO CKO */ + GPIO_FN(VIO_CKO1), + GPIO_FN(VIO_CKO2), + GPIO_FN(VIO_CKO_1), + GPIO_FN(VIO_CKO), + + /* VIO0 */ + GPIO_FN(VIO0_D0), GPIO_FN(VIO0_D1), GPIO_FN(VIO0_D2), + GPIO_FN(VIO0_D3), GPIO_FN(VIO0_D4), GPIO_FN(VIO0_D5), + GPIO_FN(VIO0_D6), GPIO_FN(VIO0_D7), GPIO_FN(VIO0_D8), + GPIO_FN(VIO0_D9), GPIO_FN(VIO0_D10), GPIO_FN(VIO0_D11), + GPIO_FN(VIO0_D12), GPIO_FN(VIO0_VD), GPIO_FN(VIO0_HD), + GPIO_FN(VIO0_CLK), GPIO_FN(VIO0_FIELD), + + GPIO_FN(VIO0_D13_PORT26), /* MSEL5CR_27_0 */ + GPIO_FN(VIO0_D14_PORT25), + GPIO_FN(VIO0_D15_PORT24), + + GPIO_FN(VIO0_D13_PORT22), /* MSEL5CR_27_1 */ + GPIO_FN(VIO0_D14_PORT95), + GPIO_FN(VIO0_D15_PORT96), + + /* VIO1 */ + GPIO_FN(VIO1_D0), GPIO_FN(VIO1_D1), GPIO_FN(VIO1_D2), + GPIO_FN(VIO1_D3), GPIO_FN(VIO1_D4), GPIO_FN(VIO1_D5), + GPIO_FN(VIO1_D6), GPIO_FN(VIO1_D7), GPIO_FN(VIO1_VD), + GPIO_FN(VIO1_HD), GPIO_FN(VIO1_CLK), GPIO_FN(VIO1_FIELD), + + /* TPU0 */ + GPIO_FN(TPU0TO0), GPIO_FN(TPU0TO1), GPIO_FN(TPU0TO3), + GPIO_FN(TPU0TO2_PORT66), /* TPU0TO2 Port 66/202 */ + GPIO_FN(TPU0TO2_PORT202), + + /* SSP1 0 */ + GPIO_FN(STP0_IPD0), GPIO_FN(STP0_IPD1), GPIO_FN(STP0_IPD2), + GPIO_FN(STP0_IPD3), GPIO_FN(STP0_IPD4), GPIO_FN(STP0_IPD5), + GPIO_FN(STP0_IPD6), GPIO_FN(STP0_IPD7), GPIO_FN(STP0_IPEN), + GPIO_FN(STP0_IPCLK), GPIO_FN(STP0_IPSYNC), + + /* SSP1 1 */ + GPIO_FN(STP1_IPD1), GPIO_FN(STP1_IPD2), GPIO_FN(STP1_IPD3), + GPIO_FN(STP1_IPD4), GPIO_FN(STP1_IPD5), GPIO_FN(STP1_IPD6), + GPIO_FN(STP1_IPD7), GPIO_FN(STP1_IPCLK), GPIO_FN(STP1_IPSYNC), + + GPIO_FN(STP1_IPD0_PORT186), /* MSEL5CR_23_0 */ + GPIO_FN(STP1_IPEN_PORT187), + + GPIO_FN(STP1_IPD0_PORT194), /* MSEL5CR_23_1 */ + GPIO_FN(STP1_IPEN_PORT193), + + /* SIM */ + GPIO_FN(SIM_RST), GPIO_FN(SIM_CLK), + GPIO_FN(SIM_D_PORT22), /* SIM_D Port 22/199 */ + GPIO_FN(SIM_D_PORT199), + + /* SDHI0 */ + GPIO_FN(SDHI0_D0), GPIO_FN(SDHI0_D1), GPIO_FN(SDHI0_D2), + GPIO_FN(SDHI0_D3), GPIO_FN(SDHI0_CD), GPIO_FN(SDHI0_WP), + GPIO_FN(SDHI0_CMD), GPIO_FN(SDHI0_CLK), + + /* SDHI1 */ + GPIO_FN(SDHI1_D0), GPIO_FN(SDHI1_D1), GPIO_FN(SDHI1_D2), + GPIO_FN(SDHI1_D3), GPIO_FN(SDHI1_CD), GPIO_FN(SDHI1_WP), + GPIO_FN(SDHI1_CMD), GPIO_FN(SDHI1_CLK), + + /* SDHI2 */ + GPIO_FN(SDHI2_D0), GPIO_FN(SDHI2_D1), GPIO_FN(SDHI2_D2), + GPIO_FN(SDHI2_D3), GPIO_FN(SDHI2_CLK), GPIO_FN(SDHI2_CMD), + + GPIO_FN(SDHI2_CD_PORT24), /* MSEL5CR_19_0 */ + GPIO_FN(SDHI2_WP_PORT25), + + GPIO_FN(SDHI2_WP_PORT177), /* MSEL5CR_19_1 */ + GPIO_FN(SDHI2_CD_PORT202), + + /* MSIOF2 */ + GPIO_FN(MSIOF2_TXD), GPIO_FN(MSIOF2_RXD), GPIO_FN(MSIOF2_TSCK), + GPIO_FN(MSIOF2_SS2), GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_SS1), + GPIO_FN(MSIOF2_MCK1), GPIO_FN(MSIOF2_MCK0), GPIO_FN(MSIOF2_RSYNC), + GPIO_FN(MSIOF2_RSCK), + + /* KEYSC */ + GPIO_FN(KEYIN4), GPIO_FN(KEYIN5), + GPIO_FN(KEYIN6), GPIO_FN(KEYIN7), + GPIO_FN(KEYOUT0), GPIO_FN(KEYOUT1), GPIO_FN(KEYOUT2), + GPIO_FN(KEYOUT3), GPIO_FN(KEYOUT4), GPIO_FN(KEYOUT5), + GPIO_FN(KEYOUT6), GPIO_FN(KEYOUT7), + + GPIO_FN(KEYIN0_PORT43), /* MSEL4CR_18_0 */ + GPIO_FN(KEYIN1_PORT44), + GPIO_FN(KEYIN2_PORT45), + GPIO_FN(KEYIN3_PORT46), + + GPIO_FN(KEYIN0_PORT58), /* MSEL4CR_18_1 */ + GPIO_FN(KEYIN1_PORT57), + GPIO_FN(KEYIN2_PORT56), + GPIO_FN(KEYIN3_PORT55), + + /* VOU */ + GPIO_FN(DV_D0), GPIO_FN(DV_D1), GPIO_FN(DV_D2), + GPIO_FN(DV_D3), GPIO_FN(DV_D4), GPIO_FN(DV_D5), + GPIO_FN(DV_D6), GPIO_FN(DV_D7), GPIO_FN(DV_D8), + GPIO_FN(DV_D9), GPIO_FN(DV_D10), GPIO_FN(DV_D11), + GPIO_FN(DV_D12), GPIO_FN(DV_D13), GPIO_FN(DV_D14), + GPIO_FN(DV_D15), GPIO_FN(DV_CLK), + GPIO_FN(DV_VSYNC), GPIO_FN(DV_HSYNC), + + /* MEMC */ + GPIO_FN(MEMC_AD0), GPIO_FN(MEMC_AD1), GPIO_FN(MEMC_AD2), + GPIO_FN(MEMC_AD3), GPIO_FN(MEMC_AD4), GPIO_FN(MEMC_AD5), + GPIO_FN(MEMC_AD6), GPIO_FN(MEMC_AD7), GPIO_FN(MEMC_AD8), + GPIO_FN(MEMC_AD9), GPIO_FN(MEMC_AD10), GPIO_FN(MEMC_AD11), + GPIO_FN(MEMC_AD12), GPIO_FN(MEMC_AD13), GPIO_FN(MEMC_AD14), + GPIO_FN(MEMC_AD15), GPIO_FN(MEMC_CS0), GPIO_FN(MEMC_INT), + GPIO_FN(MEMC_NWE), GPIO_FN(MEMC_NOE), GPIO_FN(MEMC_CS1), + GPIO_FN(MEMC_A1), GPIO_FN(MEMC_ADV), GPIO_FN(MEMC_DREQ0), + GPIO_FN(MEMC_WAIT), GPIO_FN(MEMC_DREQ1), GPIO_FN(MEMC_BUSCLK), + GPIO_FN(MEMC_A0), + + /* MMC */ + GPIO_FN(MMC0_D0_PORT68), GPIO_FN(MMC0_D1_PORT69), + GPIO_FN(MMC0_D2_PORT70), GPIO_FN(MMC0_D3_PORT71), + GPIO_FN(MMC0_D4_PORT72), GPIO_FN(MMC0_D5_PORT73), + GPIO_FN(MMC0_D6_PORT74), GPIO_FN(MMC0_D7_PORT75), + GPIO_FN(MMC0_CLK_PORT66), + GPIO_FN(MMC0_CMD_PORT67), /* MSEL4CR_15_0 */ + + GPIO_FN(MMC1_D0_PORT149), GPIO_FN(MMC1_D1_PORT148), + GPIO_FN(MMC1_D2_PORT147), GPIO_FN(MMC1_D3_PORT146), + GPIO_FN(MMC1_D4_PORT145), GPIO_FN(MMC1_D5_PORT144), + GPIO_FN(MMC1_D6_PORT143), GPIO_FN(MMC1_D7_PORT142), + GPIO_FN(MMC1_CLK_PORT103), + GPIO_FN(MMC1_CMD_PORT104), /* MSEL4CR_15_1 */ + + /* MSIOF0 */ + GPIO_FN(MSIOF0_SS1), GPIO_FN(MSIOF0_SS2), GPIO_FN(MSIOF0_RXD), + GPIO_FN(MSIOF0_TXD), GPIO_FN(MSIOF0_MCK0), GPIO_FN(MSIOF0_MCK1), + GPIO_FN(MSIOF0_RSYNC), GPIO_FN(MSIOF0_RSCK), GPIO_FN(MSIOF0_TSCK), + GPIO_FN(MSIOF0_TSYNC), + + /* MSIOF1 */ + GPIO_FN(MSIOF1_RSCK), GPIO_FN(MSIOF1_RSYNC), + GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1), + + GPIO_FN(MSIOF1_SS2_PORT116), GPIO_FN(MSIOF1_SS1_PORT117), + GPIO_FN(MSIOF1_RXD_PORT118), GPIO_FN(MSIOF1_TXD_PORT119), + GPIO_FN(MSIOF1_TSYNC_PORT120), + GPIO_FN(MSIOF1_TSCK_PORT121), /* MSEL4CR_10_0 */ + + GPIO_FN(MSIOF1_SS1_PORT67), GPIO_FN(MSIOF1_TSCK_PORT72), + GPIO_FN(MSIOF1_TSYNC_PORT73), GPIO_FN(MSIOF1_TXD_PORT74), + GPIO_FN(MSIOF1_RXD_PORT75), + GPIO_FN(MSIOF1_SS2_PORT202), /* MSEL4CR_10_1 */ + + /* GPIO */ + GPIO_FN(GPO0), GPIO_FN(GPI0), + GPIO_FN(GPO1), GPIO_FN(GPI1), + + /* USB0 */ + GPIO_FN(USB0_OCI), GPIO_FN(USB0_PPON), GPIO_FN(VBUS), + + /* USB1 */ + GPIO_FN(USB1_OCI), GPIO_FN(USB1_PPON), + + /* BBIF1 */ + GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_TSYNC), + GPIO_FN(BBIF1_TSCK), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC), + GPIO_FN(BBIF1_FLOW), GPIO_FN(BBIF1_RX_FLOW_N), + + /* BBIF2 */ + GPIO_FN(BBIF2_TXD2_PORT5), /* MSEL5CR_0_0 */ + GPIO_FN(BBIF2_RXD2_PORT60), + GPIO_FN(BBIF2_TSYNC2_PORT6), + GPIO_FN(BBIF2_TSCK2_PORT59), + + GPIO_FN(BBIF2_RXD2_PORT90), /* MSEL5CR_0_1 */ + GPIO_FN(BBIF2_TXD2_PORT183), + GPIO_FN(BBIF2_TSCK2_PORT89), + GPIO_FN(BBIF2_TSYNC2_PORT184), + + /* BSC / FLCTL / PCMCIA */ + GPIO_FN(CS0), GPIO_FN(CS2), GPIO_FN(CS4), + GPIO_FN(CS5B), GPIO_FN(CS6A), + GPIO_FN(CS5A_PORT105), /* CS5A PORT 19/105 */ + GPIO_FN(CS5A_PORT19), + GPIO_FN(IOIS16), /* ? */ + + GPIO_FN(A0), GPIO_FN(A1), GPIO_FN(A2), GPIO_FN(A3), + GPIO_FN(A4_FOE), GPIO_FN(A5_FCDE), /* share with FLCTL */ + GPIO_FN(A6), GPIO_FN(A7), GPIO_FN(A8), GPIO_FN(A9), + GPIO_FN(A10), GPIO_FN(A11), GPIO_FN(A12), GPIO_FN(A13), + GPIO_FN(A14), GPIO_FN(A15), GPIO_FN(A16), GPIO_FN(A17), + GPIO_FN(A18), GPIO_FN(A19), GPIO_FN(A20), GPIO_FN(A21), + GPIO_FN(A22), GPIO_FN(A23), GPIO_FN(A24), GPIO_FN(A25), + GPIO_FN(A26), + + GPIO_FN(D0_NAF0), GPIO_FN(D1_NAF1), /* share with FLCTL */ + GPIO_FN(D2_NAF2), GPIO_FN(D3_NAF3), /* share with FLCTL */ + GPIO_FN(D4_NAF4), GPIO_FN(D5_NAF5), /* share with FLCTL */ + GPIO_FN(D6_NAF6), GPIO_FN(D7_NAF7), /* share with FLCTL */ + GPIO_FN(D8_NAF8), GPIO_FN(D9_NAF9), /* share with FLCTL */ + GPIO_FN(D10_NAF10), GPIO_FN(D11_NAF11), /* share with FLCTL */ + GPIO_FN(D12_NAF12), GPIO_FN(D13_NAF13), /* share with FLCTL */ + GPIO_FN(D14_NAF14), GPIO_FN(D15_NAF15), /* share with FLCTL */ + GPIO_FN(D16), GPIO_FN(D17), GPIO_FN(D18), GPIO_FN(D19), + GPIO_FN(D20), GPIO_FN(D21), GPIO_FN(D22), GPIO_FN(D23), + GPIO_FN(D24), GPIO_FN(D25), GPIO_FN(D26), GPIO_FN(D27), + GPIO_FN(D28), GPIO_FN(D29), GPIO_FN(D30), GPIO_FN(D31), + + GPIO_FN(WE0_FWE), /* share with FLCTL */ + GPIO_FN(WE1), + GPIO_FN(WE2_ICIORD), /* share with PCMCIA */ + GPIO_FN(WE3_ICIOWR), /* share with PCMCIA */ + GPIO_FN(CKO), GPIO_FN(BS), GPIO_FN(RDWR), + GPIO_FN(RD_FSC), /* share with FLCTL */ + GPIO_FN(WAIT_PORT177), /* WAIT Port 90/177 */ + GPIO_FN(WAIT_PORT90), + + GPIO_FN(FCE0), GPIO_FN(FCE1), GPIO_FN(FRB), /* FLCTL */ + + /* IRDA */ + GPIO_FN(IRDA_FIRSEL), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_OUT), + + /* ATAPI */ + GPIO_FN(IDE_D0), GPIO_FN(IDE_D1), GPIO_FN(IDE_D2), + GPIO_FN(IDE_D3), GPIO_FN(IDE_D4), GPIO_FN(IDE_D5), + GPIO_FN(IDE_D6), GPIO_FN(IDE_D7), GPIO_FN(IDE_D8), + GPIO_FN(IDE_D9), GPIO_FN(IDE_D10), GPIO_FN(IDE_D11), + GPIO_FN(IDE_D12), GPIO_FN(IDE_D13), GPIO_FN(IDE_D14), + GPIO_FN(IDE_D15), GPIO_FN(IDE_A0), GPIO_FN(IDE_A1), + GPIO_FN(IDE_A2), GPIO_FN(IDE_CS0), GPIO_FN(IDE_CS1), + GPIO_FN(IDE_IOWR), GPIO_FN(IDE_IORD), GPIO_FN(IDE_IORDY), + GPIO_FN(IDE_INT), GPIO_FN(IDE_RST), GPIO_FN(IDE_DIRECTION), + GPIO_FN(IDE_EXBUF_ENB), GPIO_FN(IDE_IODACK), GPIO_FN(IDE_IODREQ), + + /* RMII */ + GPIO_FN(RMII_CRS_DV), GPIO_FN(RMII_RX_ER), GPIO_FN(RMII_RXD0), + GPIO_FN(RMII_RXD1), GPIO_FN(RMII_TX_EN), GPIO_FN(RMII_TXD0), + GPIO_FN(RMII_MDC), GPIO_FN(RMII_TXD1), GPIO_FN(RMII_MDIO), + GPIO_FN(RMII_REF50CK), GPIO_FN(RMII_REF125CK), /* for GMII */ + + /* GEther */ + GPIO_FN(ET_TX_CLK), GPIO_FN(ET_TX_EN), GPIO_FN(ET_ETXD0), + GPIO_FN(ET_ETXD1), GPIO_FN(ET_ETXD2), GPIO_FN(ET_ETXD3), + GPIO_FN(ET_ETXD4), GPIO_FN(ET_ETXD5), /* for GEther */ + GPIO_FN(ET_ETXD6), GPIO_FN(ET_ETXD7), /* for GEther */ + GPIO_FN(ET_COL), GPIO_FN(ET_TX_ER), GPIO_FN(ET_RX_CLK), + GPIO_FN(ET_RX_DV), GPIO_FN(ET_ERXD0), GPIO_FN(ET_ERXD1), + GPIO_FN(ET_ERXD2), GPIO_FN(ET_ERXD3), + GPIO_FN(ET_ERXD4), GPIO_FN(ET_ERXD5), /* for GEther */ + GPIO_FN(ET_ERXD6), GPIO_FN(ET_ERXD7), /* for GEther */ + GPIO_FN(ET_RX_ER), GPIO_FN(ET_CRS), GPIO_FN(ET_MDC), + GPIO_FN(ET_MDIO), GPIO_FN(ET_LINK), GPIO_FN(ET_PHY_INT), + GPIO_FN(ET_WOL), GPIO_FN(ET_GTX_CLK), + + /* DMA0 */ + GPIO_FN(DREQ0), GPIO_FN(DACK0), + + /* DMA1 */ + GPIO_FN(DREQ1), GPIO_FN(DACK1), + + /* SYSC */ + GPIO_FN(RESETOUTS), + + /* IRREM */ + GPIO_FN(IROUT), + + /* LCDC */ + GPIO_FN(LCDC0_SELECT), + GPIO_FN(LCDC1_SELECT), + + /* SDENC */ + GPIO_FN(SDENC_CPG), + GPIO_FN(SDENC_DV_CLKI), + + /* SYSC */ + GPIO_FN(RESETP_PULLUP), + GPIO_FN(RESETP_PLAIN), + + /* DEBUG */ + GPIO_FN(EDEBGREQ_PULLDOWN), + GPIO_FN(EDEBGREQ_PULLUP), + + GPIO_FN(TRACEAUD_FROM_VIO), + GPIO_FN(TRACEAUD_FROM_LCDC0), + GPIO_FN(TRACEAUD_FROM_MEMC), +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + PORTCR(0, 0xe6050000), /* PORT0CR */ + PORTCR(1, 0xe6050001), /* PORT1CR */ + PORTCR(2, 0xe6050002), /* PORT2CR */ + PORTCR(3, 0xe6050003), /* PORT3CR */ + PORTCR(4, 0xe6050004), /* PORT4CR */ + PORTCR(5, 0xe6050005), /* PORT5CR */ + PORTCR(6, 0xe6050006), /* PORT6CR */ + PORTCR(7, 0xe6050007), /* PORT7CR */ + PORTCR(8, 0xe6050008), /* PORT8CR */ + PORTCR(9, 0xe6050009), /* PORT9CR */ + PORTCR(10, 0xe605000a), /* PORT10CR */ + PORTCR(11, 0xe605000b), /* PORT11CR */ + PORTCR(12, 0xe605000c), /* PORT12CR */ + PORTCR(13, 0xe605000d), /* PORT13CR */ + PORTCR(14, 0xe605000e), /* PORT14CR */ + PORTCR(15, 0xe605000f), /* PORT15CR */ + PORTCR(16, 0xe6050010), /* PORT16CR */ + PORTCR(17, 0xe6050011), /* PORT17CR */ + PORTCR(18, 0xe6050012), /* PORT18CR */ + PORTCR(19, 0xe6050013), /* PORT19CR */ + PORTCR(20, 0xe6050014), /* PORT20CR */ + PORTCR(21, 0xe6050015), /* PORT21CR */ + PORTCR(22, 0xe6050016), /* PORT22CR */ + PORTCR(23, 0xe6050017), /* PORT23CR */ + PORTCR(24, 0xe6050018), /* PORT24CR */ + PORTCR(25, 0xe6050019), /* PORT25CR */ + PORTCR(26, 0xe605001a), /* PORT26CR */ + PORTCR(27, 0xe605001b), /* PORT27CR */ + PORTCR(28, 0xe605001c), /* PORT28CR */ + PORTCR(29, 0xe605001d), /* PORT29CR */ + PORTCR(30, 0xe605001e), /* PORT30CR */ + PORTCR(31, 0xe605001f), /* PORT31CR */ + PORTCR(32, 0xe6050020), /* PORT32CR */ + PORTCR(33, 0xe6050021), /* PORT33CR */ + PORTCR(34, 0xe6050022), /* PORT34CR */ + PORTCR(35, 0xe6050023), /* PORT35CR */ + PORTCR(36, 0xe6050024), /* PORT36CR */ + PORTCR(37, 0xe6050025), /* PORT37CR */ + PORTCR(38, 0xe6050026), /* PORT38CR */ + PORTCR(39, 0xe6050027), /* PORT39CR */ + PORTCR(40, 0xe6050028), /* PORT40CR */ + PORTCR(41, 0xe6050029), /* PORT41CR */ + PORTCR(42, 0xe605002a), /* PORT42CR */ + PORTCR(43, 0xe605002b), /* PORT43CR */ + PORTCR(44, 0xe605002c), /* PORT44CR */ + PORTCR(45, 0xe605002d), /* PORT45CR */ + PORTCR(46, 0xe605002e), /* PORT46CR */ + PORTCR(47, 0xe605002f), /* PORT47CR */ + PORTCR(48, 0xe6050030), /* PORT48CR */ + PORTCR(49, 0xe6050031), /* PORT49CR */ + PORTCR(50, 0xe6050032), /* PORT50CR */ + PORTCR(51, 0xe6050033), /* PORT51CR */ + PORTCR(52, 0xe6050034), /* PORT52CR */ + PORTCR(53, 0xe6050035), /* PORT53CR */ + PORTCR(54, 0xe6050036), /* PORT54CR */ + PORTCR(55, 0xe6050037), /* PORT55CR */ + PORTCR(56, 0xe6050038), /* PORT56CR */ + PORTCR(57, 0xe6050039), /* PORT57CR */ + PORTCR(58, 0xe605003a), /* PORT58CR */ + PORTCR(59, 0xe605003b), /* PORT59CR */ + PORTCR(60, 0xe605003c), /* PORT60CR */ + PORTCR(61, 0xe605003d), /* PORT61CR */ + PORTCR(62, 0xe605003e), /* PORT62CR */ + PORTCR(63, 0xe605003f), /* PORT63CR */ + PORTCR(64, 0xe6050040), /* PORT64CR */ + PORTCR(65, 0xe6050041), /* PORT65CR */ + PORTCR(66, 0xe6050042), /* PORT66CR */ + PORTCR(67, 0xe6050043), /* PORT67CR */ + PORTCR(68, 0xe6050044), /* PORT68CR */ + PORTCR(69, 0xe6050045), /* PORT69CR */ + PORTCR(70, 0xe6050046), /* PORT70CR */ + PORTCR(71, 0xe6050047), /* PORT71CR */ + PORTCR(72, 0xe6050048), /* PORT72CR */ + PORTCR(73, 0xe6050049), /* PORT73CR */ + PORTCR(74, 0xe605004a), /* PORT74CR */ + PORTCR(75, 0xe605004b), /* PORT75CR */ + PORTCR(76, 0xe605004c), /* PORT76CR */ + PORTCR(77, 0xe605004d), /* PORT77CR */ + PORTCR(78, 0xe605004e), /* PORT78CR */ + PORTCR(79, 0xe605004f), /* PORT79CR */ + PORTCR(80, 0xe6050050), /* PORT80CR */ + PORTCR(81, 0xe6050051), /* PORT81CR */ + PORTCR(82, 0xe6050052), /* PORT82CR */ + PORTCR(83, 0xe6050053), /* PORT83CR */ + + PORTCR(84, 0xe6051054), /* PORT84CR */ + PORTCR(85, 0xe6051055), /* PORT85CR */ + PORTCR(86, 0xe6051056), /* PORT86CR */ + PORTCR(87, 0xe6051057), /* PORT87CR */ + PORTCR(88, 0xe6051058), /* PORT88CR */ + PORTCR(89, 0xe6051059), /* PORT89CR */ + PORTCR(90, 0xe605105a), /* PORT90CR */ + PORTCR(91, 0xe605105b), /* PORT91CR */ + PORTCR(92, 0xe605105c), /* PORT92CR */ + PORTCR(93, 0xe605105d), /* PORT93CR */ + PORTCR(94, 0xe605105e), /* PORT94CR */ + PORTCR(95, 0xe605105f), /* PORT95CR */ + PORTCR(96, 0xe6051060), /* PORT96CR */ + PORTCR(97, 0xe6051061), /* PORT97CR */ + PORTCR(98, 0xe6051062), /* PORT98CR */ + PORTCR(99, 0xe6051063), /* PORT99CR */ + PORTCR(100, 0xe6051064), /* PORT100CR */ + PORTCR(101, 0xe6051065), /* PORT101CR */ + PORTCR(102, 0xe6051066), /* PORT102CR */ + PORTCR(103, 0xe6051067), /* PORT103CR */ + PORTCR(104, 0xe6051068), /* PORT104CR */ + PORTCR(105, 0xe6051069), /* PORT105CR */ + PORTCR(106, 0xe605106a), /* PORT106CR */ + PORTCR(107, 0xe605106b), /* PORT107CR */ + PORTCR(108, 0xe605106c), /* PORT108CR */ + PORTCR(109, 0xe605106d), /* PORT109CR */ + PORTCR(110, 0xe605106e), /* PORT110CR */ + PORTCR(111, 0xe605106f), /* PORT111CR */ + PORTCR(112, 0xe6051070), /* PORT112CR */ + PORTCR(113, 0xe6051071), /* PORT113CR */ + PORTCR(114, 0xe6051072), /* PORT114CR */ + + PORTCR(115, 0xe6052073), /* PORT115CR */ + PORTCR(116, 0xe6052074), /* PORT116CR */ + PORTCR(117, 0xe6052075), /* PORT117CR */ + PORTCR(118, 0xe6052076), /* PORT118CR */ + PORTCR(119, 0xe6052077), /* PORT119CR */ + PORTCR(120, 0xe6052078), /* PORT120CR */ + PORTCR(121, 0xe6052079), /* PORT121CR */ + PORTCR(122, 0xe605207a), /* PORT122CR */ + PORTCR(123, 0xe605207b), /* PORT123CR */ + PORTCR(124, 0xe605207c), /* PORT124CR */ + PORTCR(125, 0xe605207d), /* PORT125CR */ + PORTCR(126, 0xe605207e), /* PORT126CR */ + PORTCR(127, 0xe605207f), /* PORT127CR */ + PORTCR(128, 0xe6052080), /* PORT128CR */ + PORTCR(129, 0xe6052081), /* PORT129CR */ + PORTCR(130, 0xe6052082), /* PORT130CR */ + PORTCR(131, 0xe6052083), /* PORT131CR */ + PORTCR(132, 0xe6052084), /* PORT132CR */ + PORTCR(133, 0xe6052085), /* PORT133CR */ + PORTCR(134, 0xe6052086), /* PORT134CR */ + PORTCR(135, 0xe6052087), /* PORT135CR */ + PORTCR(136, 0xe6052088), /* PORT136CR */ + PORTCR(137, 0xe6052089), /* PORT137CR */ + PORTCR(138, 0xe605208a), /* PORT138CR */ + PORTCR(139, 0xe605208b), /* PORT139CR */ + PORTCR(140, 0xe605208c), /* PORT140CR */ + PORTCR(141, 0xe605208d), /* PORT141CR */ + PORTCR(142, 0xe605208e), /* PORT142CR */ + PORTCR(143, 0xe605208f), /* PORT143CR */ + PORTCR(144, 0xe6052090), /* PORT144CR */ + PORTCR(145, 0xe6052091), /* PORT145CR */ + PORTCR(146, 0xe6052092), /* PORT146CR */ + PORTCR(147, 0xe6052093), /* PORT147CR */ + PORTCR(148, 0xe6052094), /* PORT148CR */ + PORTCR(149, 0xe6052095), /* PORT149CR */ + PORTCR(150, 0xe6052096), /* PORT150CR */ + PORTCR(151, 0xe6052097), /* PORT151CR */ + PORTCR(152, 0xe6052098), /* PORT152CR */ + PORTCR(153, 0xe6052099), /* PORT153CR */ + PORTCR(154, 0xe605209a), /* PORT154CR */ + PORTCR(155, 0xe605209b), /* PORT155CR */ + PORTCR(156, 0xe605209c), /* PORT156CR */ + PORTCR(157, 0xe605209d), /* PORT157CR */ + PORTCR(158, 0xe605209e), /* PORT158CR */ + PORTCR(159, 0xe605209f), /* PORT159CR */ + PORTCR(160, 0xe60520a0), /* PORT160CR */ + PORTCR(161, 0xe60520a1), /* PORT161CR */ + PORTCR(162, 0xe60520a2), /* PORT162CR */ + PORTCR(163, 0xe60520a3), /* PORT163CR */ + PORTCR(164, 0xe60520a4), /* PORT164CR */ + PORTCR(165, 0xe60520a5), /* PORT165CR */ + PORTCR(166, 0xe60520a6), /* PORT166CR */ + PORTCR(167, 0xe60520a7), /* PORT167CR */ + PORTCR(168, 0xe60520a8), /* PORT168CR */ + PORTCR(169, 0xe60520a9), /* PORT169CR */ + PORTCR(170, 0xe60520aa), /* PORT170CR */ + PORTCR(171, 0xe60520ab), /* PORT171CR */ + PORTCR(172, 0xe60520ac), /* PORT172CR */ + PORTCR(173, 0xe60520ad), /* PORT173CR */ + PORTCR(174, 0xe60520ae), /* PORT174CR */ + PORTCR(175, 0xe60520af), /* PORT175CR */ + PORTCR(176, 0xe60520b0), /* PORT176CR */ + PORTCR(177, 0xe60520b1), /* PORT177CR */ + PORTCR(178, 0xe60520b2), /* PORT178CR */ + PORTCR(179, 0xe60520b3), /* PORT179CR */ + PORTCR(180, 0xe60520b4), /* PORT180CR */ + PORTCR(181, 0xe60520b5), /* PORT181CR */ + PORTCR(182, 0xe60520b6), /* PORT182CR */ + PORTCR(183, 0xe60520b7), /* PORT183CR */ + PORTCR(184, 0xe60520b8), /* PORT184CR */ + PORTCR(185, 0xe60520b9), /* PORT185CR */ + PORTCR(186, 0xe60520ba), /* PORT186CR */ + PORTCR(187, 0xe60520bb), /* PORT187CR */ + PORTCR(188, 0xe60520bc), /* PORT188CR */ + PORTCR(189, 0xe60520bd), /* PORT189CR */ + PORTCR(190, 0xe60520be), /* PORT190CR */ + PORTCR(191, 0xe60520bf), /* PORT191CR */ + PORTCR(192, 0xe60520c0), /* PORT192CR */ + PORTCR(193, 0xe60520c1), /* PORT193CR */ + PORTCR(194, 0xe60520c2), /* PORT194CR */ + PORTCR(195, 0xe60520c3), /* PORT195CR */ + PORTCR(196, 0xe60520c4), /* PORT196CR */ + PORTCR(197, 0xe60520c5), /* PORT197CR */ + PORTCR(198, 0xe60520c6), /* PORT198CR */ + PORTCR(199, 0xe60520c7), /* PORT199CR */ + PORTCR(200, 0xe60520c8), /* PORT200CR */ + PORTCR(201, 0xe60520c9), /* PORT201CR */ + PORTCR(202, 0xe60520ca), /* PORT202CR */ + PORTCR(203, 0xe60520cb), /* PORT203CR */ + PORTCR(204, 0xe60520cc), /* PORT204CR */ + PORTCR(205, 0xe60520cd), /* PORT205CR */ + PORTCR(206, 0xe60520ce), /* PORT206CR */ + PORTCR(207, 0xe60520cf), /* PORT207CR */ + PORTCR(208, 0xe60520d0), /* PORT208CR */ + PORTCR(209, 0xe60520d1), /* PORT209CR */ + + PORTCR(210, 0xe60530d2), /* PORT210CR */ + PORTCR(211, 0xe60530d3), /* PORT211CR */ + + { PINMUX_CFG_REG("MSEL1CR", 0xe605800c, 32, 1) { + MSEL1CR_31_0, MSEL1CR_31_1, + MSEL1CR_30_0, MSEL1CR_30_1, + MSEL1CR_29_0, MSEL1CR_29_1, + MSEL1CR_28_0, MSEL1CR_28_1, + MSEL1CR_27_0, MSEL1CR_27_1, + MSEL1CR_26_0, MSEL1CR_26_1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + MSEL1CR_16_0, MSEL1CR_16_1, + MSEL1CR_15_0, MSEL1CR_15_1, + MSEL1CR_14_0, MSEL1CR_14_1, + MSEL1CR_13_0, MSEL1CR_13_1, + MSEL1CR_12_0, MSEL1CR_12_1, + 0, 0, 0, 0, + MSEL1CR_9_0, MSEL1CR_9_1, + 0, 0, + MSEL1CR_7_0, MSEL1CR_7_1, + MSEL1CR_6_0, MSEL1CR_6_1, + MSEL1CR_5_0, MSEL1CR_5_1, + MSEL1CR_4_0, MSEL1CR_4_1, + MSEL1CR_3_0, MSEL1CR_3_1, + MSEL1CR_2_0, MSEL1CR_2_1, + 0, 0, + MSEL1CR_0_0, MSEL1CR_0_1, + } + }, + { PINMUX_CFG_REG("MSEL3CR", 0xE6058020, 32, 1) { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + MSEL3CR_15_0, MSEL3CR_15_1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + MSEL3CR_6_0, MSEL3CR_6_1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + } + }, + { PINMUX_CFG_REG("MSEL4CR", 0xE6058024, 32, 1) { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + MSEL4CR_19_0, MSEL4CR_19_1, + MSEL4CR_18_0, MSEL4CR_18_1, + 0, 0, 0, 0, + MSEL4CR_15_0, MSEL4CR_15_1, + 0, 0, 0, 0, 0, 0, 0, 0, + MSEL4CR_10_0, MSEL4CR_10_1, + 0, 0, 0, 0, 0, 0, + MSEL4CR_6_0, MSEL4CR_6_1, + 0, 0, + MSEL4CR_4_0, MSEL4CR_4_1, + 0, 0, 0, 0, + MSEL4CR_1_0, MSEL4CR_1_1, + 0, 0, + } + }, + { PINMUX_CFG_REG("MSEL5CR", 0xE6058028, 32, 1) { + MSEL5CR_31_0, MSEL5CR_31_1, + MSEL5CR_30_0, MSEL5CR_30_1, + MSEL5CR_29_0, MSEL5CR_29_1, + 0, 0, + MSEL5CR_27_0, MSEL5CR_27_1, + 0, 0, + MSEL5CR_25_0, MSEL5CR_25_1, + 0, 0, + MSEL5CR_23_0, MSEL5CR_23_1, + 0, 0, + MSEL5CR_21_0, MSEL5CR_21_1, + 0, 0, + MSEL5CR_19_0, MSEL5CR_19_1, + 0, 0, + MSEL5CR_17_0, MSEL5CR_17_1, + 0, 0, + MSEL5CR_15_0, MSEL5CR_15_1, + MSEL5CR_14_0, MSEL5CR_14_1, + MSEL5CR_13_0, MSEL5CR_13_1, + MSEL5CR_12_0, MSEL5CR_12_1, + MSEL5CR_11_0, MSEL5CR_11_1, + MSEL5CR_10_0, MSEL5CR_10_1, + 0, 0, + MSEL5CR_8_0, MSEL5CR_8_1, + MSEL5CR_7_0, MSEL5CR_7_1, + MSEL5CR_6_0, MSEL5CR_6_1, + MSEL5CR_5_0, MSEL5CR_5_1, + MSEL5CR_4_0, MSEL5CR_4_1, + MSEL5CR_3_0, MSEL5CR_3_1, + MSEL5CR_2_0, MSEL5CR_2_1, + 0, 0, + MSEL5CR_0_0, MSEL5CR_0_1, + } + }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054800, 32) { + PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA, + PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA, + PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA, + PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA, + PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA, + PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA, + PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA, + PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA } + }, + { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054804, 32) { + PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA, + PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA, + PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA, + PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA, + PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA, + PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA, + PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA, + PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA } + }, + { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054808, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA, + PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA, + PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA, + PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA, + PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA } + }, + { PINMUX_DATA_REG("PORTD095_064DR", 0xe6055808, 32) { + PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA, + PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA, + PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 } + }, + { PINMUX_DATA_REG("PORTD127_096DR", 0xe605580c, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, PORT114_DATA, PORT113_DATA, PORT112_DATA, + PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA, + PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA, + PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA, + PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA } + }, + { PINMUX_DATA_REG("PORTR127_096DR", 0xe605680C, 32) { + PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA, + PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA, + PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA, + PORT115_DATA, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 } + }, + { PINMUX_DATA_REG("PORTR159_128DR", 0xe6056810, 32) { + PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA, + PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA, + PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA, + PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA, + PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA, + PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA, + PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA, + PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA } + }, + { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056814, 32) { + PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA, + PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA, + PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA, + PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA, + PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA, + PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA, + PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA, + PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA } + }, + { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056818, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, PORT209_DATA, PORT208_DATA, + PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA, + PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA, + PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA, + PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA } + }, + { PINMUX_DATA_REG("PORTU223_192DR", 0xe6057818, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + PORT211_DATA, PORT210_DATA, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 } + }, + { }, +}; + +static struct pinmux_irq pinmux_irqs[] = { + PINMUX_IRQ(evt2irq(0x0200), PORT2_FN0, PORT13_FN0), /* IRQ0A */ + PINMUX_IRQ(evt2irq(0x0220), PORT20_FN0), /* IRQ1A */ + PINMUX_IRQ(evt2irq(0x0240), PORT11_FN0, PORT12_FN0), /* IRQ2A */ + PINMUX_IRQ(evt2irq(0x0260), PORT10_FN0, PORT14_FN0), /* IRQ3A */ + PINMUX_IRQ(evt2irq(0x0280), PORT15_FN0, PORT172_FN0), /* IRQ4A */ + PINMUX_IRQ(evt2irq(0x02A0), PORT0_FN0, PORT1_FN0), /* IRQ5A */ + PINMUX_IRQ(evt2irq(0x02C0), PORT121_FN0, PORT173_FN0), /* IRQ6A */ + PINMUX_IRQ(evt2irq(0x02E0), PORT120_FN0, PORT209_FN0), /* IRQ7A */ + PINMUX_IRQ(evt2irq(0x0300), PORT119_FN0), /* IRQ8A */ + PINMUX_IRQ(evt2irq(0x0320), PORT118_FN0, PORT210_FN0), /* IRQ9A */ + PINMUX_IRQ(evt2irq(0x0340), PORT19_FN0), /* IRQ10A */ + PINMUX_IRQ(evt2irq(0x0360), PORT104_FN0), /* IRQ11A */ + PINMUX_IRQ(evt2irq(0x0380), PORT42_FN0, PORT97_FN0), /* IRQ12A */ + PINMUX_IRQ(evt2irq(0x03A0), PORT64_FN0, PORT98_FN0), /* IRQ13A */ + PINMUX_IRQ(evt2irq(0x03C0), PORT63_FN0, PORT99_FN0), /* IRQ14A */ + PINMUX_IRQ(evt2irq(0x03E0), PORT62_FN0, PORT100_FN0), /* IRQ15A */ + PINMUX_IRQ(evt2irq(0x3200), PORT68_FN0, PORT211_FN0), /* IRQ16A */ + PINMUX_IRQ(evt2irq(0x3220), PORT69_FN0), /* IRQ17A */ + PINMUX_IRQ(evt2irq(0x3240), PORT70_FN0), /* IRQ18A */ + PINMUX_IRQ(evt2irq(0x3260), PORT71_FN0), /* IRQ19A */ + PINMUX_IRQ(evt2irq(0x3280), PORT67_FN0), /* IRQ20A */ + PINMUX_IRQ(evt2irq(0x32A0), PORT202_FN0), /* IRQ21A */ + PINMUX_IRQ(evt2irq(0x32C0), PORT95_FN0), /* IRQ22A */ + PINMUX_IRQ(evt2irq(0x32E0), PORT96_FN0), /* IRQ23A */ + PINMUX_IRQ(evt2irq(0x3300), PORT180_FN0), /* IRQ24A */ + PINMUX_IRQ(evt2irq(0x3320), PORT38_FN0), /* IRQ25A */ + PINMUX_IRQ(evt2irq(0x3340), PORT58_FN0, PORT81_FN0), /* IRQ26A */ + PINMUX_IRQ(evt2irq(0x3360), PORT57_FN0, PORT168_FN0), /* IRQ27A */ + PINMUX_IRQ(evt2irq(0x3380), PORT56_FN0, PORT169_FN0), /* IRQ28A */ + PINMUX_IRQ(evt2irq(0x33A0), PORT50_FN0, PORT170_FN0), /* IRQ29A */ + PINMUX_IRQ(evt2irq(0x33C0), PORT49_FN0, PORT171_FN0), /* IRQ30A */ + PINMUX_IRQ(evt2irq(0x33E0), PORT41_FN0, PORT167_FN0), /* IRQ31A */ +}; + +static struct pinmux_info r8a7740_pinmux_info = { + .name = "r8a7740_pfc", + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, + PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, + PINMUX_INPUT_END }, + .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, + PINMUX_INPUT_PULLUP_END }, + .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, + PINMUX_INPUT_PULLDOWN_END }, + .output = { PINMUX_OUTPUT_BEGIN, + PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, + PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, + PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_PORT0, + .last_gpio = GPIO_FN_TRACEAUD_FROM_MEMC, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), + + .gpio_irq = pinmux_irqs, + .gpio_irq_size = ARRAY_SIZE(pinmux_irqs), +}; + +void r8a7740_pinmux_init(void) +{ + register_pinmux(&r8a7740_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.c new file mode 100644 index 0000000..580aba3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.c
@@ -0,0 +1,1814 @@ +/* + * arch/arm/cpu/armv7/rmobile/pfc-r8a7790.c + * This file is r8a7790 processor support - PFC hardware block. + * + * Copy from linux-kernel:drivers/pinctrl/sh-pfc/pfc-r8a7790.c + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Magnus Damm + * Copyright (C) 2012 Renesas Solutions Corp. + * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <sh_pfc.h> +#include <asm/gpio.h> +#include "pfc-r8a7790.h" + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + GP_ALL(IN), + PINMUX_INPUT_END, + + PINMUX_OUTPUT_BEGIN, + GP_ALL(OUT), + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + + /* GPSR0 */ + FN_IP0_2_0, FN_IP0_5_3, FN_IP0_8_6, FN_IP0_11_9, FN_IP0_15_12, + FN_IP0_19_16, FN_IP0_22_20, FN_IP0_26_23, FN_IP0_30_27, + FN_IP1_3_0, FN_IP1_7_4, FN_IP1_11_8, FN_IP1_14_12, + FN_IP1_17_15, FN_IP1_21_18, FN_IP1_25_22, FN_IP1_27_26, + FN_IP1_29_28, FN_IP2_2_0, FN_IP2_5_3, FN_IP2_8_6, FN_IP2_11_9, + FN_IP2_14_12, FN_IP2_17_15, FN_IP2_21_18, FN_IP2_25_22, + FN_IP2_28_26, FN_IP3_3_0, FN_IP3_7_4, FN_IP3_11_8, + FN_IP3_14_12, FN_IP3_17_15, + + /* GPSR1 */ + FN_IP3_19_18, FN_IP3_22_20, FN_IP3_25_23, FN_IP3_28_26, + FN_IP3_31_29, FN_IP4_2_0, FN_IP4_5_3, FN_IP4_8_6, FN_IP4_11_9, + FN_IP4_14_12, FN_IP4_17_15, FN_IP4_20_18, FN_IP4_23_21, + FN_IP4_26_24, FN_IP4_29_27, FN_IP5_2_0, FN_IP5_5_3, FN_IP5_9_6, + FN_IP5_12_10, FN_IP5_14_13, FN_IP5_17_15, FN_IP5_20_18, + FN_IP5_23_21, FN_IP5_26_24, FN_IP5_29_27, FN_IP6_2_0, + FN_IP6_5_3, FN_IP6_8_6, FN_IP6_10_9, FN_IP6_13_11, + + /* GPSR2 */ + FN_IP7_28_27, FN_IP7_30_29, FN_IP8_1_0, FN_IP8_3_2, FN_IP8_5_4, + FN_IP8_7_6, FN_IP8_9_8, FN_IP8_11_10, FN_IP8_13_12, FN_IP8_15_14, + FN_IP8_17_16, FN_IP8_19_18, FN_IP8_21_20, FN_IP8_23_22, + FN_IP8_25_24, FN_IP8_26, FN_IP8_27, FN_VI1_DATA7_VI1_B7, + FN_IP6_16_14, FN_IP6_19_17, FN_IP6_22_20, FN_IP6_25_23, + FN_IP6_28_26, FN_IP6_31_29, FN_IP7_2_0, FN_IP7_5_3, FN_IP7_7_6, + FN_IP7_9_8, FN_IP7_12_10, FN_IP7_15_13, + + /* GPSR3 */ + FN_IP8_28, FN_IP8_30_29, FN_IP9_1_0, FN_IP9_3_2, FN_IP9_5_4, + FN_IP9_7_6, FN_IP9_11_8, FN_IP9_15_12, FN_IP9_17_16, FN_IP9_19_18, + FN_IP9_21_20, FN_IP9_23_22, FN_IP9_25_24, FN_IP9_27_26, + FN_IP9_31_28, FN_IP10_3_0, FN_IP10_6_4, FN_IP10_10_7, FN_IP10_14_11, + FN_IP10_18_15, FN_IP10_22_19, FN_IP10_25_23, FN_IP10_29_26, + FN_IP11_3_0, FN_IP11_4, FN_IP11_6_5, FN_IP11_8_7, FN_IP11_10_9, + FN_IP11_12_11, FN_IP11_14_13, FN_IP11_17_15, FN_IP11_21_18, + + /* GPSR4 */ + FN_IP11_23_22, FN_IP11_26_24, FN_IP11_29_27, FN_IP11_31_30, + FN_IP12_1_0, FN_IP12_3_2, FN_IP12_5_4, FN_IP12_7_6, FN_IP12_10_8, + FN_IP12_13_11, FN_IP12_16_14, FN_IP12_19_17, FN_IP12_22_20, + FN_IP12_24_23, FN_IP12_27_25, FN_IP12_30_28, FN_IP13_2_0, + FN_IP13_6_3, FN_IP13_9_7, FN_IP13_12_10, FN_IP13_15_13, + FN_IP13_18_16, FN_IP13_22_19, FN_IP13_25_23, FN_IP13_28_26, + FN_IP13_30_29, FN_IP14_2_0, FN_IP14_5_3, FN_IP14_8_6, FN_IP14_11_9, + FN_IP14_15_12, FN_IP14_18_16, + + /* GPSR5 */ + FN_IP14_21_19, FN_IP14_24_22, FN_IP14_27_25, FN_IP14_30_28, + FN_IP15_2_0, FN_IP15_5_3, FN_IP15_8_6, FN_IP15_11_9, FN_IP15_13_12, + FN_IP15_15_14, FN_IP15_17_16, FN_IP15_19_18, FN_IP15_22_20, + FN_IP15_25_23, FN_IP15_27_26, FN_IP15_29_28, FN_IP16_2_0, + FN_IP16_5_3, FN_USB0_PWEN, FN_USB0_OVC_VBUS, FN_IP16_6, FN_IP16_7, + FN_USB2_PWEN, FN_USB2_OVC, FN_AVS1, FN_AVS2, FN_DU_DOTCLKIN0, + FN_IP7_26_25, FN_DU_DOTCLKIN2, FN_IP7_18_16, FN_IP7_21_19, FN_IP7_24_22, + + /* IPSR0 - IPSR5 */ + /* IPSR6 */ + FN_DACK0, FN_IRQ0, FN_INTC_IRQ0_N, FN_SSI_SCK6_B, + FN_VI1_VSYNC_N, FN_VI1_VSYNC_N_B, FN_SSI_WS78_C, + FN_DREQ1_N, FN_VI1_CLKENB, FN_VI1_CLKENB_B, + FN_SSI_SDATA7_C, FN_SSI_SCK78_B, FN_DACK1, FN_IRQ1, + FN_INTC_IRQ1_N, FN_SSI_WS6_B, FN_SSI_SDATA8_C, + FN_DREQ2_N, FN_HSCK1_B, FN_HCTS0_N_B, + FN_MSIOF0_TXD_B, FN_DACK2, FN_IRQ2, FN_INTC_IRQ2_N, + FN_SSI_SDATA6_B, FN_HRTS0_N_B, FN_MSIOF0_RXD_B, + FN_ETH_CRS_DV, FN_RMII_CRS_DV, FN_STP_ISCLK_0_B, + FN_TS_SDEN0_D, FN_GLO_Q0_C, FN_SCL2_E, + FN_SCL2_CIS_E, FN_ETH_RX_ER, FN_RMII_RX_ER, + FN_STP_ISD_0_B, FN_TS_SPSYNC0_D, FN_GLO_Q1_C, + FN_SDA2_E, FN_SDA2_CIS_E, FN_ETH_RXD0, FN_RMII_RXD0, + FN_STP_ISEN_0_B, FN_TS_SDAT0_D, FN_GLO_I0_C, + FN_SCIFB1_SCK_G, FN_SCK1_E, FN_ETH_RXD1, + FN_RMII_RXD1, FN_HRX0_E, FN_STP_ISSYNC_0_B, + FN_TS_SCK0_D, FN_GLO_I1_C, FN_SCIFB1_RXD_G, + FN_RX1_E, FN_ETH_LINK, FN_RMII_LINK, FN_HTX0_E, + FN_STP_IVCXO27_0_B, FN_SCIFB1_TXD_G, FN_TX1_E, + FN_ETH_REF_CLK, FN_RMII_REF_CLK, FN_HCTS0_N_E, + FN_STP_IVCXO27_1_B, FN_HRX0_F, + + /* IPSR7 */ + FN_ETH_MDIO, FN_RMII_MDIO, FN_HRTS0_N_E, + FN_SIM0_D_C, FN_HCTS0_N_F, FN_ETH_TXD1, + FN_RMII_TXD1, FN_HTX0_F, FN_BPFCLK_G, FN_RDS_CLK_F, + FN_ETH_TX_EN, FN_RMII_TX_EN, FN_SIM0_CLK_C, + FN_HRTS0_N_F, FN_ETH_MAGIC, FN_RMII_MAGIC, + FN_SIM0_RST_C, FN_ETH_TXD0, FN_RMII_TXD0, + FN_STP_ISCLK_1_B, FN_TS_SDEN1_C, FN_GLO_SCLK_C, + FN_ETH_MDC, FN_RMII_MDC, FN_STP_ISD_1_B, + FN_TS_SPSYNC1_C, FN_GLO_SDATA_C, FN_PWM0, + FN_SCIFA2_SCK_C, FN_STP_ISEN_1_B, FN_TS_SDAT1_C, + FN_GLO_SS_C, FN_PWM1, FN_SCIFA2_TXD_C, + FN_STP_ISSYNC_1_B, FN_TS_SCK1_C, FN_GLO_RFON_C, + FN_PCMOE_N, FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C, + FN_PCMWE_N, FN_IECLK_C, FN_DU1_DOTCLKIN, + FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, FN_VI0_CLK, + FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1, + FN_VI0_DATA0_VI0_B0, FN_ATACS10_N, FN_AVB_RXD2, + FN_MII_RXD2, + + /* IPSR8 */ + FN_VI0_DATA1_VI0_B1, FN_ATARD0_N, FN_AVB_RXD3, + FN_MII_RXD3, FN_VI0_DATA2_VI0_B2, FN_ATAWR0_N, + FN_AVB_RXD4, FN_VI0_DATA3_VI0_B3, FN_ATADIR0_N, + FN_AVB_RXD5, FN_VI0_DATA4_VI0_B4, FN_ATAG0_N, + FN_AVB_RXD6, FN_VI0_DATA5_VI0_B5, FN_EX_WAIT1, + FN_AVB_RXD7, FN_VI0_DATA6_VI0_B6, FN_AVB_RX_ER, + FN_MII_RX_ER, FN_VI0_DATA7_VI0_B7, FN_AVB_RX_CLK, + FN_MII_RX_CLK, FN_VI1_CLK, FN_AVB_RX_DV, + FN_MII_RX_DV, FN_VI1_DATA0_VI1_B0, FN_SCIFA1_SCK_D, + FN_AVB_CRS, FN_MII_CRS, FN_VI1_DATA1_VI1_B1, + FN_SCIFA1_RXD_D, FN_AVB_MDC, FN_MII_MDC, + FN_VI1_DATA2_VI1_B2, FN_SCIFA1_TXD_D, FN_AVB_MDIO, + FN_MII_MDIO, FN_VI1_DATA3_VI1_B3, FN_SCIFA1_CTS_N_D, + FN_AVB_GTX_CLK, FN_VI1_DATA4_VI1_B4, FN_SCIFA1_RTS_N_D, + FN_AVB_MAGIC, FN_MII_MAGIC, FN_VI1_DATA5_VI1_B5, + FN_AVB_PHY_INT, FN_VI1_DATA6_VI1_B6, FN_AVB_GTXREFCLK, + FN_SD0_CLK, FN_VI1_DATA0_VI1_B0_B, FN_SD0_CMD, + FN_SCIFB1_SCK_B, FN_VI1_DATA1_VI1_B1_B, + + /* IPSR9 */ + FN_SD0_DAT0, FN_SCIFB1_RXD_B, FN_VI1_DATA2_VI1_B2_B, + FN_SD0_DAT1, FN_SCIFB1_TXD_B, FN_VI1_DATA3_VI1_B3_B, + FN_SD0_DAT2, FN_SCIFB1_CTS_N_B, FN_VI1_DATA4_VI1_B4_B, + FN_SD0_DAT3, FN_SCIFB1_RTS_N_B, FN_VI1_DATA5_VI1_B5_B, + FN_SD0_CD, FN_MMC0_D6, FN_TS_SDEN0_B, FN_USB0_EXTP, + FN_GLO_SCLK, FN_VI1_DATA6_VI1_B6_B, FN_SCL1_B, + FN_SCL1_CIS_B, FN_VI2_DATA6_VI2_B6_B, FN_SD0_WP, + FN_MMC0_D7, FN_TS_SPSYNC0_B, FN_USB0_IDIN, + FN_GLO_SDATA, FN_VI1_DATA7_VI1_B7_B, FN_SDA1_B, + FN_SDA1_CIS_B, FN_VI2_DATA7_VI2_B7_B, FN_SD1_CLK, + FN_AVB_TX_EN, FN_MII_TX_EN, FN_SD1_CMD, + FN_AVB_TX_ER, FN_MII_TX_ER, FN_SCIFB0_SCK_B, + FN_SD1_DAT0, FN_AVB_TX_CLK, FN_MII_TX_CLK, + FN_SCIFB0_RXD_B, FN_SD1_DAT1, FN_AVB_LINK, + FN_MII_LINK, FN_SCIFB0_TXD_B, FN_SD1_DAT2, + FN_AVB_COL, FN_MII_COL, FN_SCIFB0_CTS_N_B, + FN_SD1_DAT3, FN_AVB_RXD0, FN_MII_RXD0, + FN_SCIFB0_RTS_N_B, FN_SD1_CD, FN_MMC1_D6, + FN_TS_SDEN1, FN_USB1_EXTP, FN_GLO_SS, FN_VI0_CLK_B, + FN_SCL2_D, FN_SCL2_CIS_D, FN_SIM0_CLK_B, + FN_VI3_CLK_B, + + /* IPSR10 */ + FN_SD1_WP, FN_MMC1_D7, FN_TS_SPSYNC1, FN_USB1_IDIN, + FN_GLO_RFON, FN_VI1_CLK_B, FN_SDA2_D, FN_SDA2_CIS_D, + FN_SIM0_D_B, FN_SD2_CLK, FN_MMC0_CLK, FN_SIM0_CLK, + FN_VI0_DATA0_VI0_B0_B, FN_TS_SDEN0_C, FN_GLO_SCLK_B, + FN_VI3_DATA0_B, FN_SD2_CMD, FN_MMC0_CMD, FN_SIM0_D, + FN_VI0_DATA1_VI0_B1_B, FN_SCIFB1_SCK_E, FN_SCK1_D, + FN_TS_SPSYNC0_C, FN_GLO_SDATA_B, FN_VI3_DATA1_B, + FN_SD2_DAT0, FN_MMC0_D0, FN_FMCLK_B, + FN_VI0_DATA2_VI0_B2_B, FN_SCIFB1_RXD_E, FN_RX1_D, + FN_TS_SDAT0_C, FN_GLO_SS_B, FN_VI3_DATA2_B, + FN_SD2_DAT1, FN_MMC0_D1, FN_FMIN_B, FN_RDS_DATA, + FN_VI0_DATA3_VI0_B3_B, FN_SCIFB1_TXD_E, FN_TX1_D, + FN_TS_SCK0_C, FN_GLO_RFON_B, FN_VI3_DATA3_B, + FN_SD2_DAT2, FN_MMC0_D2, FN_BPFCLK_B, FN_RDS_CLK, + FN_VI0_DATA4_VI0_B4_B, FN_HRX0_D, FN_TS_SDEN1_B, + FN_GLO_Q0_B, FN_VI3_DATA4_B, FN_SD2_DAT3, + FN_MMC0_D3, FN_SIM0_RST, FN_VI0_DATA5_VI0_B5_B, + FN_HTX0_D, FN_TS_SPSYNC1_B, FN_GLO_Q1_B, + FN_VI3_DATA5_B, FN_SD2_CD, FN_MMC0_D4, + FN_TS_SDAT0_B, FN_USB2_EXTP, FN_GLO_I0, + FN_VI0_DATA6_VI0_B6_B, FN_HCTS0_N_D, FN_TS_SDAT1_B, + FN_GLO_I0_B, FN_VI3_DATA6_B, + + /* IPSR11 */ + FN_SD2_WP, FN_MMC0_D5, FN_TS_SCK0_B, FN_USB2_IDIN, + FN_GLO_I1, FN_VI0_DATA7_VI0_B7_B, FN_HRTS0_N_D, + FN_TS_SCK1_B, FN_GLO_I1_B, FN_VI3_DATA7_B, + FN_SD3_CLK, FN_MMC1_CLK, FN_SD3_CMD, FN_MMC1_CMD, + FN_MTS_N, FN_SD3_DAT0, FN_MMC1_D0, FN_STM_N, + FN_SD3_DAT1, FN_MMC1_D1, FN_MDATA, FN_SD3_DAT2, + FN_MMC1_D2, FN_SDATA, FN_SD3_DAT3, FN_MMC1_D3, + FN_SCKZ, FN_SD3_CD, FN_MMC1_D4, FN_TS_SDAT1, + FN_VSP, FN_GLO_Q0, FN_SIM0_RST_B, FN_SD3_WP, + FN_MMC1_D5, FN_TS_SCK1, FN_GLO_Q1, FN_FMIN_C, + FN_RDS_DATA_B, FN_FMIN_E, FN_RDS_DATA_D, FN_FMIN_F, + FN_RDS_DATA_E, FN_MLB_CLK, FN_SCL2_B, FN_SCL2_CIS_B, + FN_MLB_SIG, FN_SCIFB1_RXD_D, FN_RX1_C, FN_SDA2_B, + FN_SDA2_CIS_B, FN_MLB_DAT, FN_SPV_EVEN, + FN_SCIFB1_TXD_D, FN_TX1_C, FN_BPFCLK_C, + FN_RDS_CLK_B, FN_SSI_SCK0129, FN_CAN_CLK_B, + FN_MOUT0, + + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + FN_SEL_SCIF1_4, + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, + FN_SEL_SCIFB1_4, + FN_SEL_SCIFB1_5, FN_SEL_SCIFB1_6, + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, FN_SEL_SCIFA1_3, + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + FN_SEL_SOF1_0, FN_SEL_SOF1_1, + FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2, + FN_SEL_SSI6_0, FN_SEL_SSI6_1, + FN_SEL_SSI5_0, FN_SEL_SSI5_1, FN_SEL_SSI5_2, + FN_SEL_VI3_0, FN_SEL_VI3_1, + FN_SEL_VI2_0, FN_SEL_VI2_1, + FN_SEL_VI1_0, FN_SEL_VI1_1, + FN_SEL_VI0_0, FN_SEL_VI0_1, + FN_SEL_TSIF1_0, FN_SEL_TSIF1_1, FN_SEL_TSIF1_2, + FN_SEL_LBS_0, FN_SEL_LBS_1, + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + FN_SEL_SOF3_0, FN_SEL_SOF3_1, + FN_SEL_SOF0_0, FN_SEL_SOF0_1, + + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, + FN_SEL_SCIFCLK_0, FN_SEL_SCIFCLK_1, + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, FN_SEL_SCIFA2_2, + FN_SEL_CAN1_0, FN_SEL_CAN1_1, + FN_SEL_ADI_0, FN_SEL_ADI_1, + FN_SEL_SSP_0, FN_SEL_SSP_1, + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3, + FN_SEL_FM_4, FN_SEL_FM_5, FN_SEL_FM_6, + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, FN_SEL_HSCIF0_3, + FN_SEL_HSCIF0_4, FN_SEL_HSCIF0_5, + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, + FN_SEL_RDS_0, FN_SEL_RDS_1, FN_SEL_RDS_2, + FN_SEL_RDS_3, FN_SEL_RDS_4, FN_SEL_RDS_5, + FN_SEL_SIM_0, FN_SEL_SIM_1, FN_SEL_SIM_2, + FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2, + + FN_SEL_IICDVFS_0, FN_SEL_IICDVFS_1, + FN_SEL_IIC0_0, FN_SEL_IIC0_1, + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + FN_SEL_IIC2_4, + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, + FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3, + FN_SEL_I2C2_4, + FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + + VI1_DATA7_VI1_B7_MARK, + + USB0_PWEN_MARK, USB0_OVC_VBUS_MARK, + USB2_PWEN_MARK, USB2_OVC_MARK, AVS1_MARK, AVS2_MARK, + DU_DOTCLKIN0_MARK, DU_DOTCLKIN2_MARK, + + D0_MARK, MSIOF3_SCK_B_MARK, VI3_DATA0_MARK, VI0_G4_MARK, VI0_G4_B_MARK, + D1_MARK, MSIOF3_SYNC_B_MARK, VI3_DATA1_MARK, VI0_G5_MARK, + VI0_G5_B_MARK, D2_MARK, MSIOF3_RXD_B_MARK, VI3_DATA2_MARK, + VI0_G6_MARK, VI0_G6_B_MARK, D3_MARK, MSIOF3_TXD_B_MARK, + VI3_DATA3_MARK, VI0_G7_MARK, VI0_G7_B_MARK, D4_MARK, + SCIFB1_RXD_F_MARK, SCIFB0_RXD_C_MARK, VI3_DATA4_MARK, + VI0_R0_MARK, VI0_R0_B_MARK, RX0_B_MARK, D5_MARK, + SCIFB1_TXD_F_MARK, SCIFB0_TXD_C_MARK, VI3_DATA5_MARK, + VI0_R1_MARK, VI0_R1_B_MARK, TX0_B_MARK, D6_MARK, + SCL2_C_MARK, VI3_DATA6_MARK, VI0_R2_MARK, VI0_R2_B_MARK, + SCL2_CIS_C_MARK, D7_MARK, AD_DI_B_MARK, SDA2_C_MARK, + VI3_DATA7_MARK, VI0_R3_MARK, VI0_R3_B_MARK, SDA2_CIS_C_MARK, + D8_MARK, SCIFA1_SCK_C_MARK, AVB_TXD0_MARK, MII_TXD0_MARK, + VI0_G0_MARK, VI0_G0_B_MARK, VI2_DATA0_VI2_B0_MARK, + + D9_MARK, SCIFA1_RXD_C_MARK, AVB_TXD1_MARK, MII_TXD1_MARK, + VI0_G1_MARK, VI0_G1_B_MARK, VI2_DATA1_VI2_B1_MARK, D10_MARK, + SCIFA1_TXD_C_MARK, AVB_TXD2_MARK, MII_TXD2_MARK, + VI0_G2_MARK, VI0_G2_B_MARK, VI2_DATA2_VI2_B2_MARK, D11_MARK, + SCIFA1_CTS_N_C_MARK, AVB_TXD3_MARK, MII_TXD3_MARK, + VI0_G3_MARK, VI0_G3_B_MARK, VI2_DATA3_VI2_B3_MARK, + D12_MARK, SCIFA1_RTS_N_C_MARK, AVB_TXD4_MARK, + VI0_HSYNC_N_MARK, VI0_HSYNC_N_B_MARK, VI2_DATA4_VI2_B4_MARK, + D13_MARK, AVB_TXD5_MARK, VI0_VSYNC_N_MARK, + VI0_VSYNC_N_B_MARK, VI2_DATA5_VI2_B5_MARK, D14_MARK, + SCIFB1_RXD_C_MARK, AVB_TXD6_MARK, RX1_B_MARK, + VI0_CLKENB_MARK, VI0_CLKENB_B_MARK, VI2_DATA6_VI2_B6_MARK, + D15_MARK, SCIFB1_TXD_C_MARK, AVB_TXD7_MARK, TX1_B_MARK, + VI0_FIELD_MARK, VI0_FIELD_B_MARK, VI2_DATA7_VI2_B7_MARK, + A0_MARK, PWM3_MARK, A1_MARK, PWM4_MARK, + + A2_MARK, PWM5_MARK, MSIOF1_SS1_B_MARK, A3_MARK, + PWM6_MARK, MSIOF1_SS2_B_MARK, A4_MARK, MSIOF1_TXD_B_MARK, + TPU0TO0_MARK, A5_MARK, SCIFA1_TXD_B_MARK, TPU0TO1_MARK, + A6_MARK, SCIFA1_RTS_N_B_MARK, TPU0TO2_MARK, A7_MARK, + SCIFA1_SCK_B_MARK, AUDIO_CLKOUT_B_MARK, TPU0TO3_MARK, + A8_MARK, SCIFA1_RXD_B_MARK, SSI_SCK5_B_MARK, VI0_R4_MARK, + VI0_R4_B_MARK, SCIFB2_RXD_C_MARK, VI2_DATA0_VI2_B0_B_MARK, + A9_MARK, SCIFA1_CTS_N_B_MARK, SSI_WS5_B_MARK, VI0_R5_MARK, + VI0_R5_B_MARK, SCIFB2_TXD_C_MARK, VI2_DATA1_VI2_B1_B_MARK, + A10_MARK, SSI_SDATA5_B_MARK, MSIOF2_SYNC_MARK, VI0_R6_MARK, + VI0_R6_B_MARK, VI2_DATA2_VI2_B2_B_MARK, + + A11_MARK, SCIFB2_CTS_N_B_MARK, MSIOF2_SCK_MARK, VI1_R0_MARK, + VI1_R0_B_MARK, VI2_G0_MARK, VI2_DATA3_VI2_B3_B_MARK, + A12_MARK, SCIFB2_RXD_B_MARK, MSIOF2_TXD_MARK, VI1_R1_MARK, + VI1_R1_B_MARK, VI2_G1_MARK, VI2_DATA4_VI2_B4_B_MARK, + A13_MARK, SCIFB2_RTS_N_B_MARK, EX_WAIT2_MARK, + MSIOF2_RXD_MARK, VI1_R2_MARK, VI1_R2_B_MARK, VI2_G2_MARK, + VI2_DATA5_VI2_B5_B_MARK, A14_MARK, SCIFB2_TXD_B_MARK, + ATACS11_N_MARK, MSIOF2_SS1_MARK, A15_MARK, SCIFB2_SCK_B_MARK, + ATARD1_N_MARK, MSIOF2_SS2_MARK, A16_MARK, ATAWR1_N_MARK, + A17_MARK, AD_DO_B_MARK, ATADIR1_N_MARK, A18_MARK, + AD_CLK_B_MARK, ATAG1_N_MARK, A19_MARK, AD_NCS_N_B_MARK, + ATACS01_N_MARK, EX_WAIT0_B_MARK, A20_MARK, SPCLK_MARK, + VI1_R3_MARK, VI1_R3_B_MARK, VI2_G4_MARK, + + A21_MARK, MOSI_IO0_MARK, VI1_R4_MARK, VI1_R4_B_MARK, VI2_G5_MARK, + A22_MARK, MISO_IO1_MARK, VI1_R5_MARK, VI1_R5_B_MARK, + VI2_G6_MARK, A23_MARK, IO2_MARK, VI1_G7_MARK, + VI1_G7_B_MARK, VI2_G7_MARK, A24_MARK, IO3_MARK, + VI1_R7_MARK, VI1_R7_B_MARK, VI2_CLKENB_MARK, + VI2_CLKENB_B_MARK, A25_MARK, SSL_MARK, VI1_G6_MARK, + VI1_G6_B_MARK, VI2_FIELD_MARK, VI2_FIELD_B_MARK, CS0_N_MARK, + VI1_R6_MARK, VI1_R6_B_MARK, VI2_G3_MARK, MSIOF0_SS2_B_MARK, + CS1_N_A26_MARK, SPEEDIN_MARK, VI0_R7_MARK, VI0_R7_B_MARK, + VI2_CLK_MARK, VI2_CLK_B_MARK, EX_CS0_N_MARK, HRX1_B_MARK, + VI1_G5_MARK, VI1_G5_B_MARK, VI2_R0_MARK, HTX0_B_MARK, + MSIOF0_SS1_B_MARK, EX_CS1_N_MARK, GPS_CLK_MARK, + HCTS1_N_B_MARK, VI1_FIELD_MARK, VI1_FIELD_B_MARK, + VI2_R1_MARK, EX_CS2_N_MARK, GPS_SIGN_MARK, HRTS1_N_B_MARK, + VI3_CLKENB_MARK, VI1_G0_MARK, VI1_G0_B_MARK, VI2_R2_MARK, + + EX_CS3_N_MARK, GPS_MAG_MARK, VI3_FIELD_MARK, + VI1_G1_MARK, VI1_G1_B_MARK, VI2_R3_MARK, + EX_CS4_N_MARK, MSIOF1_SCK_B_MARK, VI3_HSYNC_N_MARK, + VI2_HSYNC_N_MARK, SCL1_MARK, VI2_HSYNC_N_B_MARK, + INTC_EN0_N_MARK, SCL1_CIS_MARK, EX_CS5_N_MARK, CAN0_RX_MARK, + MSIOF1_RXD_B_MARK, VI3_VSYNC_N_MARK, VI1_G2_MARK, + VI1_G2_B_MARK, VI2_R4_MARK, SDA1_MARK, INTC_EN1_N_MARK, + SDA1_CIS_MARK, BS_N_MARK, IETX_MARK, HTX1_B_MARK, + CAN1_TX_MARK, DRACK0_MARK, IETX_C_MARK, RD_N_MARK, + CAN0_TX_MARK, SCIFA0_SCK_B_MARK, RD_WR_N_MARK, VI1_G3_MARK, + VI1_G3_B_MARK, VI2_R5_MARK, SCIFA0_RXD_B_MARK, + INTC_IRQ4_N_MARK, WE0_N_MARK, IECLK_MARK, CAN_CLK_MARK, + VI2_VSYNC_N_MARK, SCIFA0_TXD_B_MARK, VI2_VSYNC_N_B_MARK, + WE1_N_MARK, IERX_MARK, CAN1_RX_MARK, VI1_G4_MARK, + VI1_G4_B_MARK, VI2_R6_MARK, SCIFA0_CTS_N_B_MARK, + IERX_C_MARK, EX_WAIT0_MARK, IRQ3_MARK, INTC_IRQ3_N_MARK, + VI3_CLK_MARK, SCIFA0_RTS_N_B_MARK, HRX0_B_MARK, + MSIOF0_SCK_B_MARK, DREQ0_N_MARK, VI1_HSYNC_N_MARK, + VI1_HSYNC_N_B_MARK, VI2_R7_MARK, SSI_SCK78_C_MARK, + SSI_WS78_B_MARK, + + DACK0_MARK, IRQ0_MARK, INTC_IRQ0_N_MARK, SSI_SCK6_B_MARK, + VI1_VSYNC_N_MARK, VI1_VSYNC_N_B_MARK, SSI_WS78_C_MARK, + DREQ1_N_MARK, VI1_CLKENB_MARK, VI1_CLKENB_B_MARK, + SSI_SDATA7_C_MARK, SSI_SCK78_B_MARK, DACK1_MARK, IRQ1_MARK, + INTC_IRQ1_N_MARK, SSI_WS6_B_MARK, SSI_SDATA8_C_MARK, + DREQ2_N_MARK, HSCK1_B_MARK, HCTS0_N_B_MARK, + MSIOF0_TXD_B_MARK, DACK2_MARK, IRQ2_MARK, INTC_IRQ2_N_MARK, + SSI_SDATA6_B_MARK, HRTS0_N_B_MARK, MSIOF0_RXD_B_MARK, + ETH_CRS_DV_MARK, RMII_CRS_DV_MARK, STP_ISCLK_0_B_MARK, + TS_SDEN0_D_MARK, GLO_Q0_C_MARK, SCL2_E_MARK, + SCL2_CIS_E_MARK, ETH_RX_ER_MARK, RMII_RX_ER_MARK, + STP_ISD_0_B_MARK, TS_SPSYNC0_D_MARK, GLO_Q1_C_MARK, + SDA2_E_MARK, SDA2_CIS_E_MARK, ETH_RXD0_MARK, RMII_RXD0_MARK, + STP_ISEN_0_B_MARK, TS_SDAT0_D_MARK, GLO_I0_C_MARK, + SCIFB1_SCK_G_MARK, SCK1_E_MARK, ETH_RXD1_MARK, + RMII_RXD1_MARK, HRX0_E_MARK, STP_ISSYNC_0_B_MARK, + TS_SCK0_D_MARK, GLO_I1_C_MARK, SCIFB1_RXD_G_MARK, + RX1_E_MARK, ETH_LINK_MARK, RMII_LINK_MARK, HTX0_E_MARK, + STP_IVCXO27_0_B_MARK, SCIFB1_TXD_G_MARK, TX1_E_MARK, + ETH_REF_CLK_MARK, RMII_REF_CLK_MARK, HCTS0_N_E_MARK, + STP_IVCXO27_1_B_MARK, HRX0_F_MARK, + + ETH_MDIO_MARK, RMII_MDIO_MARK, HRTS0_N_E_MARK, + SIM0_D_C_MARK, HCTS0_N_F_MARK, ETH_TXD1_MARK, + RMII_TXD1_MARK, HTX0_F_MARK, BPFCLK_G_MARK, RDS_CLK_F_MARK, + ETH_TX_EN_MARK, RMII_TX_EN_MARK, SIM0_CLK_C_MARK, + HRTS0_N_F_MARK, ETH_MAGIC_MARK, RMII_MAGIC_MARK, + SIM0_RST_C_MARK, ETH_TXD0_MARK, RMII_TXD0_MARK, + STP_ISCLK_1_B_MARK, TS_SDEN1_C_MARK, GLO_SCLK_C_MARK, + ETH_MDC_MARK, RMII_MDC_MARK, STP_ISD_1_B_MARK, + TS_SPSYNC1_C_MARK, GLO_SDATA_C_MARK, PWM0_MARK, + SCIFA2_SCK_C_MARK, STP_ISEN_1_B_MARK, TS_SDAT1_C_MARK, + GLO_SS_C_MARK, PWM1_MARK, SCIFA2_TXD_C_MARK, + STP_ISSYNC_1_B_MARK, TS_SCK1_C_MARK, GLO_RFON_C_MARK, + PCMOE_N_MARK, PWM2_MARK, PWMFSW0_MARK, SCIFA2_RXD_C_MARK, + PCMWE_N_MARK, IECLK_C_MARK, DU1_DOTCLKIN_MARK, + AUDIO_CLKC_MARK, AUDIO_CLKOUT_C_MARK, VI0_CLK_MARK, + ATACS00_N_MARK, AVB_RXD1_MARK, MII_RXD1_MARK, + VI0_DATA0_VI0_B0_MARK, ATACS10_N_MARK, AVB_RXD2_MARK, + MII_RXD2_MARK, + + VI0_DATA1_VI0_B1_MARK, ATARD0_N_MARK, AVB_RXD3_MARK, + MII_RXD3_MARK, VI0_DATA2_VI0_B2_MARK, ATAWR0_N_MARK, + AVB_RXD4_MARK, VI0_DATA3_VI0_B3_MARK, ATADIR0_N_MARK, + AVB_RXD5_MARK, VI0_DATA4_VI0_B4_MARK, ATAG0_N_MARK, + AVB_RXD6_MARK, VI0_DATA5_VI0_B5_MARK, EX_WAIT1_MARK, + AVB_RXD7_MARK, VI0_DATA6_VI0_B6_MARK, AVB_RX_ER_MARK, + MII_RX_ER_MARK, VI0_DATA7_VI0_B7_MARK, AVB_RX_CLK_MARK, + MII_RX_CLK_MARK, VI1_CLK_MARK, AVB_RX_DV_MARK, + MII_RX_DV_MARK, VI1_DATA0_VI1_B0_MARK, SCIFA1_SCK_D_MARK, + AVB_CRS_MARK, MII_CRS_MARK, VI1_DATA1_VI1_B1_MARK, + SCIFA1_RXD_D_MARK, AVB_MDC_MARK, MII_MDC_MARK, + VI1_DATA2_VI1_B2_MARK, SCIFA1_TXD_D_MARK, AVB_MDIO_MARK, + MII_MDIO_MARK, VI1_DATA3_VI1_B3_MARK, SCIFA1_CTS_N_D_MARK, + AVB_GTX_CLK_MARK, VI1_DATA4_VI1_B4_MARK, SCIFA1_RTS_N_D_MARK, + AVB_MAGIC_MARK, MII_MAGIC_MARK, VI1_DATA5_VI1_B5_MARK, + AVB_PHY_INT_MARK, VI1_DATA6_VI1_B6_MARK, AVB_GTXREFCLK_MARK, + SD0_CLK_MARK, VI1_DATA0_VI1_B0_B_MARK, SD0_CMD_MARK, + SCIFB1_SCK_B_MARK, VI1_DATA1_VI1_B1_B_MARK, + + SD0_DAT0_MARK, SCIFB1_RXD_B_MARK, VI1_DATA2_VI1_B2_B_MARK, + SD0_DAT1_MARK, SCIFB1_TXD_B_MARK, VI1_DATA3_VI1_B3_B_MARK, + SD0_DAT2_MARK, SCIFB1_CTS_N_B_MARK, VI1_DATA4_VI1_B4_B_MARK, + SD0_DAT3_MARK, SCIFB1_RTS_N_B_MARK, VI1_DATA5_VI1_B5_B_MARK, + SD0_CD_MARK, MMC0_D6_MARK, TS_SDEN0_B_MARK, USB0_EXTP_MARK, + GLO_SCLK_MARK, VI1_DATA6_VI1_B6_B_MARK, SCL1_B_MARK, + SCL1_CIS_B_MARK, VI2_DATA6_VI2_B6_B_MARK, SD0_WP_MARK, + MMC0_D7_MARK, TS_SPSYNC0_B_MARK, USB0_IDIN_MARK, + GLO_SDATA_MARK, VI1_DATA7_VI1_B7_B_MARK, SDA1_B_MARK, + SDA1_CIS_B_MARK, VI2_DATA7_VI2_B7_B_MARK, SD1_CLK_MARK, + AVB_TX_EN_MARK, MII_TX_EN_MARK, SD1_CMD_MARK, + AVB_TX_ER_MARK, MII_TX_ER_MARK, SCIFB0_SCK_B_MARK, + SD1_DAT0_MARK, AVB_TX_CLK_MARK, MII_TX_CLK_MARK, + SCIFB0_RXD_B_MARK, SD1_DAT1_MARK, AVB_LINK_MARK, + MII_LINK_MARK, SCIFB0_TXD_B_MARK, SD1_DAT2_MARK, + AVB_COL_MARK, MII_COL_MARK, SCIFB0_CTS_N_B_MARK, + SD1_DAT3_MARK, AVB_RXD0_MARK, MII_RXD0_MARK, + SCIFB0_RTS_N_B_MARK, SD1_CD_MARK, MMC1_D6_MARK, + TS_SDEN1_MARK, USB1_EXTP_MARK, GLO_SS_MARK, VI0_CLK_B_MARK, + SCL2_D_MARK, SCL2_CIS_D_MARK, SIM0_CLK_B_MARK, + VI3_CLK_B_MARK, + + SD1_WP_MARK, MMC1_D7_MARK, TS_SPSYNC1_MARK, USB1_IDIN_MARK, + GLO_RFON_MARK, VI1_CLK_B_MARK, SDA2_D_MARK, SDA2_CIS_D_MARK, + SIM0_D_B_MARK, SD2_CLK_MARK, MMC0_CLK_MARK, SIM0_CLK_MARK, + VI0_DATA0_VI0_B0_B_MARK, TS_SDEN0_C_MARK, GLO_SCLK_B_MARK, + VI3_DATA0_B_MARK, SD2_CMD_MARK, MMC0_CMD_MARK, SIM0_D_MARK, + VI0_DATA1_VI0_B1_B_MARK, SCIFB1_SCK_E_MARK, SCK1_D_MARK, + TS_SPSYNC0_C_MARK, GLO_SDATA_B_MARK, VI3_DATA1_B_MARK, + SD2_DAT0_MARK, MMC0_D0_MARK, FMCLK_B_MARK, + VI0_DATA2_VI0_B2_B_MARK, SCIFB1_RXD_E_MARK, RX1_D_MARK, + TS_SDAT0_C_MARK, GLO_SS_B_MARK, VI3_DATA2_B_MARK, + SD2_DAT1_MARK, MMC0_D1_MARK, FMIN_B_MARK, RDS_DATA_MARK, + VI0_DATA3_VI0_B3_B_MARK, SCIFB1_TXD_E_MARK, TX1_D_MARK, + TS_SCK0_C_MARK, GLO_RFON_B_MARK, VI3_DATA3_B_MARK, + SD2_DAT2_MARK, MMC0_D2_MARK, BPFCLK_B_MARK, RDS_CLK_MARK, + VI0_DATA4_VI0_B4_B_MARK, HRX0_D_MARK, TS_SDEN1_B_MARK, + GLO_Q0_B_MARK, VI3_DATA4_B_MARK, SD2_DAT3_MARK, + MMC0_D3_MARK, SIM0_RST_MARK, VI0_DATA5_VI0_B5_B_MARK, + HTX0_D_MARK, TS_SPSYNC1_B_MARK, GLO_Q1_B_MARK, + VI3_DATA5_B_MARK, SD2_CD_MARK, MMC0_D4_MARK, + TS_SDAT0_B_MARK, USB2_EXTP_MARK, GLO_I0_MARK, + VI0_DATA6_VI0_B6_B_MARK, HCTS0_N_D_MARK, TS_SDAT1_B_MARK, + GLO_I0_B_MARK, VI3_DATA6_B_MARK, + + SD2_WP_MARK, MMC0_D5_MARK, TS_SCK0_B_MARK, USB2_IDIN_MARK, + GLO_I1_MARK, VI0_DATA7_VI0_B7_B_MARK, HRTS0_N_D_MARK, + TS_SCK1_B_MARK, GLO_I1_B_MARK, VI3_DATA7_B_MARK, + SD3_CLK_MARK, MMC1_CLK_MARK, SD3_CMD_MARK, MMC1_CMD_MARK, + MTS_N_MARK, SD3_DAT0_MARK, MMC1_D0_MARK, STM_N_MARK, + SD3_DAT1_MARK, MMC1_D1_MARK, MDATA_MARK, SD3_DAT2_MARK, + MMC1_D2_MARK, SDATA_MARK, SD3_DAT3_MARK, MMC1_D3_MARK, + SCKZ_MARK, SD3_CD_MARK, MMC1_D4_MARK, TS_SDAT1_MARK, + VSP_MARK, GLO_Q0_MARK, SIM0_RST_B_MARK, SD3_WP_MARK, + MMC1_D5_MARK, TS_SCK1_MARK, GLO_Q1_MARK, FMIN_C_MARK, + RDS_DATA_B_MARK, FMIN_E_MARK, RDS_DATA_D_MARK, FMIN_F_MARK, + RDS_DATA_E_MARK, MLB_CLK_MARK, SCL2_B_MARK, SCL2_CIS_B_MARK, + MLB_SIG_MARK, SCIFB1_RXD_D_MARK, RX1_C_MARK, SDA2_B_MARK, + SDA2_CIS_B_MARK, MLB_DAT_MARK, SPV_EVEN_MARK, + SCIFB1_TXD_D_MARK, TX1_C_MARK, BPFCLK_C_MARK, + RDS_CLK_B_MARK, SSI_SCK0129_MARK, CAN_CLK_B_MARK, + MOUT0_MARK, + + SSI_WS0129_MARK, CAN0_TX_B_MARK, MOUT1_MARK, + SSI_SDATA0_MARK, CAN0_RX_B_MARK, MOUT2_MARK, + SSI_SDATA1_MARK, CAN1_TX_B_MARK, MOUT5_MARK, + SSI_SDATA2_MARK, CAN1_RX_B_MARK, SSI_SCK1_MARK, MOUT6_MARK, + SSI_SCK34_MARK, STP_OPWM_0_MARK, SCIFB0_SCK_MARK, + MSIOF1_SCK_MARK, CAN_DEBUG_HW_TRIGGER_MARK, SSI_WS34_MARK, + STP_IVCXO27_0_MARK, SCIFB0_RXD_MARK, MSIOF1_SYNC_MARK, + CAN_STEP0_MARK, SSI_SDATA3_MARK, STP_ISCLK_0_MARK, + SCIFB0_TXD_MARK, MSIOF1_SS1_MARK, CAN_TXCLK_MARK, + SSI_SCK4_MARK, STP_ISD_0_MARK, SCIFB0_CTS_N_MARK, + MSIOF1_SS2_MARK, SSI_SCK5_C_MARK, CAN_DEBUGOUT0_MARK, + SSI_WS4_MARK, STP_ISEN_0_MARK, SCIFB0_RTS_N_MARK, + MSIOF1_TXD_MARK, SSI_WS5_C_MARK, CAN_DEBUGOUT1_MARK, + SSI_SDATA4_MARK, STP_ISSYNC_0_MARK, MSIOF1_RXD_MARK, + CAN_DEBUGOUT2_MARK, SSI_SCK5_MARK, SCIFB1_SCK_MARK, + IERX_B_MARK, DU2_EXHSYNC_DU2_HSYNC_MARK, QSTH_QHS_MARK, + CAN_DEBUGOUT3_MARK, SSI_WS5_MARK, SCIFB1_RXD_MARK, + IECLK_B_MARK, DU2_EXVSYNC_DU2_VSYNC_MARK, QSTB_QHE_MARK, + CAN_DEBUGOUT4_MARK, + + SSI_SDATA5_MARK, SCIFB1_TXD_MARK, IETX_B_MARK, DU2_DR2_MARK, + LCDOUT2_MARK, CAN_DEBUGOUT5_MARK, SSI_SCK6_MARK, + SCIFB1_CTS_N_MARK, BPFCLK_D_MARK, RDS_CLK_C_MARK, + DU2_DR3_MARK, LCDOUT3_MARK, CAN_DEBUGOUT6_MARK, + BPFCLK_F_MARK, RDS_CLK_E_MARK, SSI_WS6_MARK, + SCIFB1_RTS_N_MARK, CAN0_TX_D_MARK, DU2_DR4_MARK, + LCDOUT4_MARK, CAN_DEBUGOUT7_MARK, SSI_SDATA6_MARK, + FMIN_D_MARK, RDS_DATA_C_MARK, DU2_DR5_MARK, LCDOUT5_MARK, + CAN_DEBUGOUT8_MARK, SSI_SCK78_MARK, STP_IVCXO27_1_MARK, + SCK1_MARK, SCIFA1_SCK_MARK, DU2_DR6_MARK, LCDOUT6_MARK, + CAN_DEBUGOUT9_MARK, SSI_WS78_MARK, STP_ISCLK_1_MARK, + SCIFB2_SCK_MARK, SCIFA2_CTS_N_MARK, DU2_DR7_MARK, + LCDOUT7_MARK, CAN_DEBUGOUT10_MARK, SSI_SDATA7_MARK, + STP_ISD_1_MARK, SCIFB2_RXD_MARK, SCIFA2_RTS_N_MARK, + TCLK2_MARK, QSTVA_QVS_MARK, CAN_DEBUGOUT11_MARK, + BPFCLK_E_MARK, RDS_CLK_D_MARK, SSI_SDATA7_B_MARK, + FMIN_G_MARK, RDS_DATA_F_MARK, SSI_SDATA8_MARK, + STP_ISEN_1_MARK, SCIFB2_TXD_MARK, CAN0_TX_C_MARK, + CAN_DEBUGOUT12_MARK, SSI_SDATA8_B_MARK, SSI_SDATA9_MARK, + STP_ISSYNC_1_MARK, SCIFB2_CTS_N_MARK, SSI_WS1_MARK, + SSI_SDATA5_C_MARK, CAN_DEBUGOUT13_MARK, AUDIO_CLKA_MARK, + SCIFB2_RTS_N_MARK, CAN_DEBUGOUT14_MARK, + + AUDIO_CLKB_MARK, SCIF_CLK_MARK, CAN0_RX_D_MARK, + DVC_MUTE_MARK, CAN0_RX_C_MARK, CAN_DEBUGOUT15_MARK, + REMOCON_MARK, SCIFA0_SCK_MARK, HSCK1_MARK, SCK0_MARK, + MSIOF3_SS2_MARK, DU2_DG2_MARK, LCDOUT10_MARK, SDA1_C_MARK, + SDA1_CIS_C_MARK, SCIFA0_RXD_MARK, HRX1_MARK, RX0_MARK, + DU2_DR0_MARK, LCDOUT0_MARK, SCIFA0_TXD_MARK, HTX1_MARK, + TX0_MARK, DU2_DR1_MARK, LCDOUT1_MARK, SCIFA0_CTS_N_MARK, + HCTS1_N_MARK, CTS0_N_MARK, MSIOF3_SYNC_MARK, DU2_DG3_MARK, + LCDOUT11_MARK, PWM0_B_MARK, SCL1_C_MARK, SCL1_CIS_C_MARK, + SCIFA0_RTS_N_MARK, HRTS1_N_MARK, RTS0_N_TANS_MARK, + MSIOF3_SS1_MARK, DU2_DG0_MARK, LCDOUT8_MARK, PWM1_B_MARK, + SCIFA1_RXD_MARK, AD_DI_MARK, RX1_MARK, + DU2_EXODDF_DU2_ODDF_DISP_CDE_MARK, QCPV_QDE_MARK, + SCIFA1_TXD_MARK, AD_DO_MARK, TX1_MARK, DU2_DG1_MARK, + LCDOUT9_MARK, SCIFA1_CTS_N_MARK, AD_CLK_MARK, + CTS1_N_MARK, MSIOF3_RXD_MARK, DU0_DOTCLKOUT_MARK, QCLK_MARK, + SCIFA1_RTS_N_MARK, AD_NCS_N_MARK, RTS1_N_TANS_MARK, + MSIOF3_TXD_MARK, DU1_DOTCLKOUT_MARK, QSTVB_QVE_MARK, + HRTS0_N_C_MARK, + + SCIFA2_SCK_MARK, FMCLK_MARK, MSIOF3_SCK_MARK, DU2_DG7_MARK, + LCDOUT15_MARK, SCIF_CLK_B_MARK, SCIFA2_RXD_MARK, FMIN_MARK, + DU2_DB0_MARK, LCDOUT16_MARK, SCL2_MARK, SCL2_CIS_MARK, + SCIFA2_TXD_MARK, BPFCLK_MARK, DU2_DB1_MARK, LCDOUT17_MARK, + SDA2_MARK, SDA2_CIS_MARK, HSCK0_MARK, TS_SDEN0_MARK, + DU2_DG4_MARK, LCDOUT12_MARK, HCTS0_N_C_MARK, HRX0_MARK, + DU2_DB2_MARK, LCDOUT18_MARK, HTX0_MARK, DU2_DB3_MARK, + LCDOUT19_MARK, HCTS0_N_MARK, SSI_SCK9_MARK, DU2_DB4_MARK, + LCDOUT20_MARK, HRTS0_N_MARK, SSI_WS9_MARK, DU2_DB5_MARK, + LCDOUT21_MARK, MSIOF0_SCK_MARK, TS_SDAT0_MARK, ADICLK_MARK, + DU2_DB6_MARK, LCDOUT22_MARK, MSIOF0_SYNC_MARK, TS_SCK0_MARK, + SSI_SCK2_MARK, ADIDATA_MARK, DU2_DB7_MARK, LCDOUT23_MARK, + SCIFA2_RXD_B_MARK, MSIOF0_SS1_MARK, ADICHS0_MARK, + DU2_DG5_MARK, LCDOUT13_MARK, MSIOF0_TXD_MARK, ADICHS1_MARK, + DU2_DG6_MARK, LCDOUT14_MARK, + + MSIOF0_SS2_MARK, AUDIO_CLKOUT_MARK, ADICHS2_MARK, + DU2_DISP_MARK, QPOLA_MARK, HTX0_C_MARK, SCIFA2_TXD_B_MARK, + MSIOF0_RXD_MARK, TS_SPSYNC0_MARK, SSI_WS2_MARK, + ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, HRX0_C_MARK, + USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK, + TCLK1_B_MARK, + PINMUX_MARK_END, +}; + +static pinmux_enum_t pinmux_data[] = { + PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ + + PINMUX_DATA(VI1_DATA7_VI1_B7_MARK, FN_VI1_DATA7_VI1_B7), + PINMUX_DATA(USB0_PWEN_MARK, FN_USB0_PWEN), + PINMUX_DATA(USB0_OVC_VBUS_MARK, FN_USB0_OVC_VBUS), + PINMUX_DATA(USB2_PWEN_MARK, FN_USB2_PWEN), + PINMUX_DATA(USB2_OVC_MARK, FN_USB2_OVC), + PINMUX_DATA(AVS1_MARK, FN_AVS1), + PINMUX_DATA(AVS2_MARK, FN_AVS2), + PINMUX_DATA(DU_DOTCLKIN0_MARK, FN_DU_DOTCLKIN0), + PINMUX_DATA(DU_DOTCLKIN2_MARK, FN_DU_DOTCLKIN2), + + PINMUX_IPSR_DATA(IP6_2_0, DACK0), + PINMUX_IPSR_DATA(IP6_2_0, IRQ0), + PINMUX_IPSR_DATA(IP6_2_0, INTC_IRQ0_N), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SSI_SCK6_B, SEL_SSI6_1), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, VI1_VSYNC_N, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, VI1_VSYNC_N_B, SEL_VI1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SSI_WS78_C, SEL_SSI7_2), + PINMUX_IPSR_DATA(IP6_5_3, DREQ1_N), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, VI1_CLKENB, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, VI1_CLKENB_B, SEL_VI1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SSI_SDATA7_C, SEL_SSI7_2), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SSI_SCK78_B, SEL_SSI7_1), + PINMUX_IPSR_DATA(IP6_8_6, DACK1), + PINMUX_IPSR_DATA(IP6_8_6, IRQ1), + PINMUX_IPSR_DATA(IP6_8_6, INTC_IRQ1_N), + PINMUX_IPSR_MODSEL_DATA(IP6_8_6, SSI_WS6_B, SEL_SSI6_1), + PINMUX_IPSR_MODSEL_DATA(IP6_8_6, SSI_SDATA8_C, SEL_SSI8_2), + PINMUX_IPSR_DATA(IP6_10_9, DREQ2_N), + PINMUX_IPSR_MODSEL_DATA(IP6_10_9, HSCK1_B, SEL_HSCIF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_10_9, HCTS0_N_B, SEL_HSCIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP6_10_9, MSIOF0_TXD_B, SEL_SOF0_1), + PINMUX_IPSR_DATA(IP6_13_11, DACK2), + PINMUX_IPSR_DATA(IP6_13_11, IRQ2), + PINMUX_IPSR_DATA(IP6_13_11, INTC_IRQ2_N), + PINMUX_IPSR_MODSEL_DATA(IP6_13_11, SSI_SDATA6_B, SEL_SSI6_1), + PINMUX_IPSR_MODSEL_DATA(IP6_13_11, HRTS0_N_B, SEL_HSCIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP6_13_11, MSIOF0_RXD_B, SEL_SOF0_1), + PINMUX_IPSR_DATA(IP6_16_14, ETH_CRS_DV), + PINMUX_IPSR_DATA(IP6_16_14, RMII_CRS_DV), + PINMUX_IPSR_MODSEL_DATA(IP6_16_14, STP_ISCLK_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_16_14, TS_SDEN0_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP6_16_14, GLO_Q0_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_16_14, SCL2_E, SEL_IIC2_4), + PINMUX_IPSR_MODSEL_DATA(IP6_16_14, SCL2_CIS_E, SEL_I2C2_4), + PINMUX_IPSR_DATA(IP6_19_17, ETH_RX_ER), + PINMUX_IPSR_DATA(IP6_19_17, RMII_RX_ER), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, STP_ISD_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, TS_SPSYNC0_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, GLO_Q1_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, SDA2_E, SEL_IIC2_4), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, SDA2_CIS_E, SEL_I2C2_4), + PINMUX_IPSR_DATA(IP6_22_20, ETH_RXD0), + PINMUX_IPSR_DATA(IP6_22_20, RMII_RXD0), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, STP_ISEN_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, TS_SDAT0_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, GLO_I0_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCIFB1_SCK_G, SEL_SCIFB1_6), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCK1_E, SEL_SCIF1_4), + PINMUX_IPSR_DATA(IP6_25_23, ETH_RXD1), + PINMUX_IPSR_DATA(IP6_25_23, RMII_RXD1), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, HRX0_E, SEL_HSCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, STP_ISSYNC_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, TS_SCK0_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, GLO_I1_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, SCIFB1_RXD_G, SEL_SCIFB1_6), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, RX1_E, SEL_SCIF1_4), + PINMUX_IPSR_DATA(IP6_28_26, ETH_LINK), + PINMUX_IPSR_DATA(IP6_28_26, RMII_LINK), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, HTX0_E, SEL_HSCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, STP_IVCXO27_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, SCIFB1_TXD_G, SEL_SCIFB1_6), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, TX1_E, SEL_SCIF1_4), + PINMUX_IPSR_DATA(IP6_31_29, ETH_REF_CLK), + PINMUX_IPSR_DATA(IP6_31_29, RMII_REF_CLK), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, HCTS0_N_E, SEL_HSCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, STP_IVCXO27_1_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, HRX0_F, SEL_HSCIF0_5), + + PINMUX_IPSR_DATA(IP7_2_0, ETH_MDIO), + PINMUX_IPSR_DATA(IP7_2_0, RMII_MDIO), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, HRTS0_N_E, SEL_HSCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, SIM0_D_C, SEL_SIM_2), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, HCTS0_N_F, SEL_HSCIF0_5), + PINMUX_IPSR_DATA(IP7_5_3, ETH_TXD1), + PINMUX_IPSR_DATA(IP7_5_3, RMII_TXD1), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, HTX0_F, SEL_HSCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, BPFCLK_G, SEL_SIM_2), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, RDS_CLK_F, SEL_HSCIF0_5), + PINMUX_IPSR_DATA(IP7_7_6, ETH_TX_EN), + PINMUX_IPSR_DATA(IP7_7_6, RMII_TX_EN), + PINMUX_IPSR_MODSEL_DATA(IP7_7_6, SIM0_CLK_C, SEL_SIM_2), + PINMUX_IPSR_MODSEL_DATA(IP7_7_6, HRTS0_N_F, SEL_HSCIF0_5), + PINMUX_IPSR_DATA(IP7_9_8, ETH_MAGIC), + PINMUX_IPSR_DATA(IP7_9_8, RMII_MAGIC), + PINMUX_IPSR_MODSEL_DATA(IP7_9_8, SIM0_RST_C, SEL_SIM_2), + PINMUX_IPSR_DATA(IP7_12_10, ETH_TXD0), + PINMUX_IPSR_DATA(IP7_12_10, RMII_TXD0), + PINMUX_IPSR_MODSEL_DATA(IP7_12_10, STP_ISCLK_1_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP7_12_10, TS_SDEN1_C, SEL_TSIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP7_12_10, GLO_SCLK_C, SEL_GPS_2), + PINMUX_IPSR_DATA(IP7_15_13, ETH_MDC), + PINMUX_IPSR_DATA(IP7_15_13, RMII_MDC), + PINMUX_IPSR_MODSEL_DATA(IP7_15_13, STP_ISD_1_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP7_15_13, TS_SPSYNC1_C, SEL_TSIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP7_15_13, GLO_SDATA_C, SEL_GPS_2), + PINMUX_IPSR_DATA(IP7_18_16, PWM0), + PINMUX_IPSR_MODSEL_DATA(IP7_18_16, SCIFA2_SCK_C, SEL_SCIFA2_2), + PINMUX_IPSR_MODSEL_DATA(IP7_18_16, STP_ISEN_1_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP7_18_16, TS_SDAT1_C, SEL_TSIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP7_18_16, GLO_SS_C, SEL_GPS_2), + PINMUX_IPSR_DATA(IP7_21_19, PWM1), + PINMUX_IPSR_MODSEL_DATA(IP7_21_19, SCIFA2_TXD_C, SEL_SCIFA2_2), + PINMUX_IPSR_MODSEL_DATA(IP7_21_19, STP_ISSYNC_1_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP7_21_19, TS_SCK1_C, SEL_TSIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP7_21_19, GLO_RFON_C, SEL_GPS_2), + PINMUX_IPSR_DATA(IP7_21_19, PCMOE_N), + PINMUX_IPSR_DATA(IP7_24_22, PWM2), + PINMUX_IPSR_DATA(IP7_24_22, PWMFSW0), + PINMUX_IPSR_MODSEL_DATA(IP7_24_22, SCIFA2_RXD_C, SEL_SCIFA2_2), + PINMUX_IPSR_DATA(IP7_24_22, PCMWE_N), + PINMUX_IPSR_MODSEL_DATA(IP7_24_22, IECLK_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP7_26_25, DU1_DOTCLKIN), + PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKC), + PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKOUT_C), + PINMUX_IPSR_MODSEL_DATA(IP7_28_27, VI0_CLK, SEL_VI0_0), + PINMUX_IPSR_DATA(IP7_28_27, ATACS00_N), + PINMUX_IPSR_DATA(IP7_28_27, AVB_RXD1), + PINMUX_IPSR_DATA(IP7_28_27, MII_RXD1), + PINMUX_IPSR_MODSEL_DATA(IP7_30_29, VI0_DATA0_VI0_B0, SEL_VI0_0), + PINMUX_IPSR_DATA(IP7_30_29, ATACS10_N), + PINMUX_IPSR_DATA(IP7_30_29, AVB_RXD2), + PINMUX_IPSR_DATA(IP7_30_29, MII_RXD2), + + PINMUX_IPSR_MODSEL_DATA(IP8_1_0, VI0_DATA1_VI0_B1, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_1_0, ATARD0_N), + PINMUX_IPSR_DATA(IP8_1_0, AVB_RXD3), + PINMUX_IPSR_DATA(IP8_1_0, MII_RXD3), + PINMUX_IPSR_MODSEL_DATA(IP8_3_2, VI0_DATA2_VI0_B2, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_3_2, ATAWR0_N), + PINMUX_IPSR_DATA(IP8_3_2, AVB_RXD4), + PINMUX_IPSR_MODSEL_DATA(IP8_5_4, VI0_DATA3_VI0_B3, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_5_4, ATADIR0_N), + PINMUX_IPSR_DATA(IP8_5_4, AVB_RXD5), + PINMUX_IPSR_MODSEL_DATA(IP8_7_6, VI0_DATA4_VI0_B4, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_7_6, ATAG0_N), + PINMUX_IPSR_DATA(IP8_7_6, AVB_RXD6), + PINMUX_IPSR_MODSEL_DATA(IP8_9_8, VI0_DATA5_VI0_B5, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_9_8, EX_WAIT1), + PINMUX_IPSR_DATA(IP8_9_8, AVB_RXD7), + PINMUX_IPSR_MODSEL_DATA(IP8_11_10, VI0_DATA6_VI0_B6, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_11_10, AVB_RX_ER), + PINMUX_IPSR_DATA(IP8_11_10, MII_RX_ER), + PINMUX_IPSR_MODSEL_DATA(IP8_13_12, VI0_DATA7_VI0_B7, SEL_VI0_0), + PINMUX_IPSR_DATA(IP8_13_12, AVB_RX_CLK), + PINMUX_IPSR_DATA(IP8_13_12, MII_RX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP8_15_14, VI1_CLK, SEL_VI1_0), + PINMUX_IPSR_DATA(IP8_15_14, AVB_RX_DV), + PINMUX_IPSR_DATA(IP8_15_14, MII_RX_DV), + PINMUX_IPSR_MODSEL_DATA(IP8_17_16, VI1_DATA0_VI1_B0, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_17_16, SCIFA1_SCK_D, SEL_SCIFA1_3), + PINMUX_IPSR_DATA(IP8_17_16, AVB_CRS), + PINMUX_IPSR_DATA(IP8_17_16, MII_CRS), + PINMUX_IPSR_MODSEL_DATA(IP8_19_18, VI1_DATA1_VI1_B1, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_19_18, SCIFA1_RXD_D, SEL_SCIFA1_3), + PINMUX_IPSR_DATA(IP8_19_18, AVB_MDC), + PINMUX_IPSR_DATA(IP8_19_18, MII_MDC), + PINMUX_IPSR_MODSEL_DATA(IP8_21_20, VI1_DATA2_VI1_B2, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_21_20, SCIFA1_TXD_D, SEL_SCIFA1_3), + PINMUX_IPSR_DATA(IP8_21_20, AVB_MDIO), + PINMUX_IPSR_DATA(IP8_21_20, MII_MDIO), + PINMUX_IPSR_MODSEL_DATA(IP8_23_22, VI1_DATA3_VI1_B3, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_23_22, SCIFA1_CTS_N_D, SEL_SCIFA1_3), + PINMUX_IPSR_DATA(IP8_23_22, AVB_GTX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP8_25_24, VI1_DATA4_VI1_B4, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_25_24, SCIFA1_RTS_N_D, SEL_SCIFA1_3), + PINMUX_IPSR_DATA(IP8_25_24, AVB_MAGIC), + PINMUX_IPSR_DATA(IP8_25_24, MII_MAGIC), + PINMUX_IPSR_MODSEL_DATA(IP8_26, VI1_DATA5_VI1_B5, SEL_VI1_0), + PINMUX_IPSR_MODSEL_DATA(IP8_26, AVB_PHY_INT, SEL_SCIFA1_3), + PINMUX_IPSR_MODSEL_DATA(IP8_27, VI1_DATA6_VI1_B6, SEL_VI1_0), + PINMUX_IPSR_DATA(IP8_27, AVB_GTXREFCLK), + PINMUX_IPSR_DATA(IP8_28, SD0_CLK), + PINMUX_IPSR_MODSEL_DATA(IP8_28, VI1_DATA0_VI1_B0_B, SEL_VI1_1), + PINMUX_IPSR_DATA(IP8_30_29, SD0_CMD), + PINMUX_IPSR_MODSEL_DATA(IP8_30_29, SCIFB1_SCK_B, SEL_SCIFB1_1), + PINMUX_IPSR_MODSEL_DATA(IP8_30_29, VI1_DATA1_VI1_B1_B, SEL_VI1_1), + + PINMUX_IPSR_DATA(IP9_1_0, SD0_DAT0), + PINMUX_IPSR_MODSEL_DATA(IP9_1_0, SCIFB1_RXD_B, SEL_SCIFB1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_1_0, VI1_DATA2_VI1_B2_B, SEL_VI1_1), + PINMUX_IPSR_DATA(IP9_3_2, SD0_DAT1), + PINMUX_IPSR_MODSEL_DATA(IP9_3_2, SCIFB1_TXD_B, SEL_SCIFB1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_3_2, VI1_DATA3_VI1_B3_B, SEL_VI1_1), + PINMUX_IPSR_DATA(IP9_5_4, SD0_DAT2), + PINMUX_IPSR_MODSEL_DATA(IP9_5_4, SCIFB1_CTS_N_B, SEL_SCIFB1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_5_4, VI1_DATA4_VI1_B4_B, SEL_VI1_1), + PINMUX_IPSR_DATA(IP9_7_6, SD0_DAT3), + PINMUX_IPSR_MODSEL_DATA(IP9_7_6, SCIFB1_RTS_N_B, SEL_SCIFB1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_7_6, VI1_DATA5_VI1_B5_B, SEL_VI1_1), + PINMUX_IPSR_DATA(IP9_11_8, SD0_CD), + PINMUX_IPSR_DATA(IP9_11_8, MMC0_D6), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, TS_SDEN0_B, SEL_TSIF0_1), + PINMUX_IPSR_DATA(IP9_11_8, USB0_EXTP), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, GLO_SCLK, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, VI1_DATA6_VI1_B6_B, SEL_VI1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, SCL1_B, SEL_IIC1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, SCL1_CIS_B, SEL_I2C1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_11_8, VI2_DATA6_VI2_B6_B, SEL_VI2_1), + PINMUX_IPSR_DATA(IP9_15_12, SD0_WP), + PINMUX_IPSR_DATA(IP9_15_12, MMC0_D7), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, TS_SPSYNC0_B, SEL_TSIF0_1), + PINMUX_IPSR_DATA(IP9_15_12, USB0_IDIN), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, GLO_SDATA, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, VI1_DATA7_VI1_B7_B, SEL_VI1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, SDA1_B, SEL_IIC1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, SDA1_CIS_B, SEL_I2C1_1), + PINMUX_IPSR_MODSEL_DATA(IP9_15_12, VI2_DATA7_VI2_B7_B, SEL_VI2_1), + PINMUX_IPSR_DATA(IP9_17_16, SD1_CLK), + PINMUX_IPSR_DATA(IP9_17_16, AVB_TX_EN), + PINMUX_IPSR_DATA(IP9_17_16, MII_TX_EN), + PINMUX_IPSR_DATA(IP9_19_18, SD1_CMD), + PINMUX_IPSR_DATA(IP9_19_18, AVB_TX_ER), + PINMUX_IPSR_DATA(IP9_19_18, MII_TX_ER), + PINMUX_IPSR_MODSEL_DATA(IP9_19_18, SCIFB0_SCK_B, SEL_SCIFB_1), + PINMUX_IPSR_DATA(IP9_21_20, SD1_DAT0), + PINMUX_IPSR_DATA(IP9_21_20, AVB_TX_CLK), + PINMUX_IPSR_DATA(IP9_21_20, MII_TX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP9_21_20, SCIFB0_RXD_B, SEL_SCIFB_1), + PINMUX_IPSR_DATA(IP9_23_22, SD1_DAT1), + PINMUX_IPSR_DATA(IP9_23_22, AVB_LINK), + PINMUX_IPSR_DATA(IP9_23_22, MII_LINK), + PINMUX_IPSR_MODSEL_DATA(IP9_23_22, SCIFB0_TXD_B, SEL_SCIFB_1), + PINMUX_IPSR_DATA(IP9_25_24, SD1_DAT2), + PINMUX_IPSR_DATA(IP9_25_24, AVB_COL), + PINMUX_IPSR_DATA(IP9_25_24, MII_COL), + PINMUX_IPSR_MODSEL_DATA(IP9_25_24, SCIFB0_CTS_N_B, SEL_SCIFB_1), + PINMUX_IPSR_DATA(IP9_27_26, SD1_DAT3), + PINMUX_IPSR_DATA(IP9_27_26, AVB_RXD0), + PINMUX_IPSR_DATA(IP9_27_26, MII_RXD0), + PINMUX_IPSR_MODSEL_DATA(IP9_27_26, SCIFB0_RTS_N_B, SEL_SCIFB_1), + PINMUX_IPSR_DATA(IP9_31_28, SD1_CD), + PINMUX_IPSR_DATA(IP9_31_28, MMC1_D6), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, TS_SDEN1, SEL_TSIF1_0), + PINMUX_IPSR_DATA(IP9_31_28, USB1_EXTP), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, GLO_SS, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, VI0_CLK_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SCL2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SCL2_CIS_D, SEL_I2C2_3), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SIM0_CLK_B, SEL_SIM_1), + PINMUX_IPSR_MODSEL_DATA(IP9_31_28, VI3_CLK_B, SEL_VI3_1), + + PINMUX_IPSR_DATA(IP10_3_0, SD1_WP), + PINMUX_IPSR_DATA(IP10_3_0, MMC1_D7), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, TS_SPSYNC1, SEL_TSIF1_0), + PINMUX_IPSR_DATA(IP10_3_0, USB1_IDIN), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, GLO_RFON, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, VI1_CLK_B, SEL_VI1_1), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SDA2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SDA2_CIS_D, SEL_I2C2_3), + PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SIM0_D_B, SEL_SIM_1), + PINMUX_IPSR_DATA(IP10_6_4, SD2_CLK), + PINMUX_IPSR_DATA(IP10_6_4, MMC0_CLK), + PINMUX_IPSR_MODSEL_DATA(IP10_6_4, SIM0_CLK, SEL_SIM_0), + PINMUX_IPSR_MODSEL_DATA(IP10_6_4, VI0_DATA0_VI0_B0_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_6_4, TS_SDEN0_C, SEL_TSIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP10_6_4, GLO_SCLK_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_6_4, VI3_DATA0_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_10_7, SD2_CMD), + PINMUX_IPSR_DATA(IP10_10_7, MMC0_CMD), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SIM0_D, SEL_SIM_0), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, VI0_DATA1_VI0_B1_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SCIFB1_SCK_E, SEL_SCIFB1_4), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SCK1_D, SEL_SCIF1_3), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, TS_SPSYNC0_C, SEL_TSIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, GLO_SDATA_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_10_7, VI3_DATA1_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_14_11, SD2_DAT0), + PINMUX_IPSR_DATA(IP10_14_11, MMC0_D0), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, FMCLK_B, SEL_FM_1), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, VI0_DATA2_VI0_B2_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, SCIFB1_RXD_E, SEL_SCIFB1_4), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, RX1_D, SEL_SCIF1_3), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, TS_SDAT0_C, SEL_TSIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, GLO_SS_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_14_11, VI3_DATA2_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_18_15, SD2_DAT1), + PINMUX_IPSR_DATA(IP10_18_15, MMC0_D1), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, FMIN_B, SEL_FM_1), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, RDS_DATA, SEL_RDS_0), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, VI0_DATA3_VI0_B3_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, SCIFB1_TXD_E, SEL_SCIFB1_4), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, TX1_D, SEL_SCIF1_3), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, TS_SCK0_C, SEL_TSIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, GLO_RFON_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_18_15, VI3_DATA3_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_22_19, SD2_DAT2), + PINMUX_IPSR_DATA(IP10_22_19, MMC0_D2), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, BPFCLK_B, SEL_FM_1), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, RDS_CLK, SEL_RDS_0), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, VI0_DATA4_VI0_B4_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, HRX0_D, SEL_HSCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, TS_SDEN1_B, SEL_TSIF1_1), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, GLO_Q0_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_22_19, VI3_DATA4_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_25_23, SD2_DAT3), + PINMUX_IPSR_DATA(IP10_25_23, MMC0_D3), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, SIM0_RST, SEL_SIM_0), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, VI0_DATA5_VI0_B5_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, HTX0_D, SEL_HSCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, TS_SPSYNC1_B, SEL_TSIF1_1), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, GLO_Q1_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_25_23, VI3_DATA5_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP10_29_26, SD2_CD), + PINMUX_IPSR_DATA(IP10_29_26, MMC0_D4), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, TS_SDAT0_B, SEL_TSIF0_1), + PINMUX_IPSR_DATA(IP10_29_26, USB2_EXTP), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, GLO_I0, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, VI0_DATA6_VI0_B6_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, HCTS0_N_D, SEL_HSCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, TS_SDAT1_B, SEL_TSIF1_1), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, GLO_I0_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP10_29_26, VI3_DATA6_B, SEL_VI3_1), + + PINMUX_IPSR_DATA(IP11_3_0, SD2_WP), + PINMUX_IPSR_DATA(IP11_3_0, MMC0_D5), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, TS_SCK0_B, SEL_TSIF0_1), + PINMUX_IPSR_DATA(IP11_3_0, USB2_IDIN), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, GLO_I1, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, VI0_DATA7_VI0_B7_B, SEL_VI0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, HRTS0_N_D, SEL_HSCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, TS_SCK1_B, SEL_TSIF1_1), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, GLO_I1_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_3_0, VI3_DATA7_B, SEL_VI3_1), + PINMUX_IPSR_DATA(IP11_4, SD3_CLK), + PINMUX_IPSR_DATA(IP11_4, MMC1_CLK), + PINMUX_IPSR_DATA(IP11_6_5, SD3_CMD), + PINMUX_IPSR_DATA(IP11_6_5, MMC1_CMD), + PINMUX_IPSR_DATA(IP11_6_5, MTS_N), + PINMUX_IPSR_DATA(IP11_8_7, SD3_DAT0), + PINMUX_IPSR_DATA(IP11_8_7, MMC1_D0), + PINMUX_IPSR_DATA(IP11_8_7, STM_N), + PINMUX_IPSR_DATA(IP11_10_9, SD3_DAT1), + PINMUX_IPSR_DATA(IP11_10_9, MMC1_D1), + PINMUX_IPSR_DATA(IP11_10_9, MDATA), + PINMUX_IPSR_DATA(IP11_12_11, SD3_DAT2), + PINMUX_IPSR_DATA(IP11_12_11, MMC1_D2), + PINMUX_IPSR_DATA(IP11_12_11, SDATA), + PINMUX_IPSR_DATA(IP11_14_13, SD3_DAT3), + PINMUX_IPSR_DATA(IP11_14_13, MMC1_D3), + PINMUX_IPSR_DATA(IP11_14_13, SCKZ), + PINMUX_IPSR_DATA(IP11_17_15, SD3_CD), + PINMUX_IPSR_DATA(IP11_17_15, MMC1_D4), + PINMUX_IPSR_MODSEL_DATA(IP11_17_15, TS_SDAT1, SEL_TSIF1_0), + PINMUX_IPSR_DATA(IP11_17_15, VSP), + PINMUX_IPSR_MODSEL_DATA(IP11_17_15, GLO_Q0, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP11_17_15, SIM0_RST_B, SEL_SIM_1), + PINMUX_IPSR_DATA(IP11_21_18, SD3_WP), + PINMUX_IPSR_DATA(IP11_21_18, MMC1_D5), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, TS_SCK1, SEL_TSIF1_0), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, GLO_Q1, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_C, SEL_FM_2), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_B, SEL_RDS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_E, SEL_FM_4), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_D, SEL_RDS_3), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_F, SEL_FM_5), + PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_E, SEL_RDS_4), + PINMUX_IPSR_DATA(IP11_23_22, MLB_CLK), + PINMUX_IPSR_MODSEL_DATA(IP11_23_22, SCL2_B, SEL_IIC2_1), + PINMUX_IPSR_MODSEL_DATA(IP11_23_22, SCL2_CIS_B, SEL_I2C2_1), + PINMUX_IPSR_DATA(IP11_26_24, MLB_SIG), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SCIFB1_RXD_D, SEL_SCIFB1_3), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, RX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SDA2_B, SEL_IIC2_1), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SDA2_CIS_B, SEL_I2C2_1), + PINMUX_IPSR_DATA(IP11_29_27, MLB_DAT), + PINMUX_IPSR_DATA(IP11_29_27, SPV_EVEN), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, SCIFB1_TXD_D, SEL_SCIFB1_3), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, TX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, BPFCLK_C, SEL_FM_2), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, RDS_CLK_B, SEL_RDS_1), + PINMUX_IPSR_DATA(IP11_31_30, SSI_SCK0129), + PINMUX_IPSR_MODSEL_DATA(IP11_31_30, CAN_CLK_B, SEL_CANCLK_1), + PINMUX_IPSR_DATA(IP11_31_30, MOUT0), + +}; + +static struct pinmux_gpio pinmux_gpios[] = { + PINMUX_GPIO_GP_ALL(), + + GPIO_FN(VI1_DATA7_VI1_B7), GPIO_FN(USB0_PWEN), GPIO_FN(USB0_OVC_VBUS), + GPIO_FN(USB2_PWEN), GPIO_FN(USB2_OVC), GPIO_FN(AVS1), GPIO_FN(AVS2), + GPIO_FN(DU_DOTCLKIN0), GPIO_FN(DU_DOTCLKIN2), + + /* IPSR0 - IPSR5 */ + /*IPSR6*/ + GPIO_FN(DACK0), GPIO_FN(IRQ0), GPIO_FN(INTC_IRQ0_N), + GPIO_FN(SSI_SCK6_B), GPIO_FN(VI1_VSYNC_N), GPIO_FN(VI1_VSYNC_N_B), + GPIO_FN(SSI_WS78_C), GPIO_FN(DREQ1_N), GPIO_FN(VI1_CLKENB), + GPIO_FN(VI1_CLKENB_B), GPIO_FN(SSI_SDATA7_C), GPIO_FN(SSI_SCK78_B), + GPIO_FN(DACK1), GPIO_FN(IRQ1), GPIO_FN(INTC_IRQ1_N), GPIO_FN(SSI_WS6_B), + GPIO_FN(SSI_SDATA8_C), GPIO_FN(DREQ2_N), GPIO_FN(HSCK1_B), + GPIO_FN(HCTS0_N_B), GPIO_FN(MSIOF0_TXD_B), GPIO_FN(DACK2), + GPIO_FN(IRQ2), GPIO_FN(INTC_IRQ2_N), GPIO_FN(SSI_SDATA6_B), + GPIO_FN(HRTS0_N_B), GPIO_FN(MSIOF0_RXD_B), GPIO_FN(ETH_CRS_DV), + GPIO_FN(RMII_CRS_DV), GPIO_FN(STP_ISCLK_0_B), GPIO_FN(TS_SDEN0_D), + GPIO_FN(GLO_Q0_C), GPIO_FN(SCL2_E), GPIO_FN(SCL2_CIS_E), + GPIO_FN(ETH_RX_ER), GPIO_FN(RMII_RX_ER), GPIO_FN(STP_ISD_0_B), + GPIO_FN(TS_SPSYNC0_D), GPIO_FN(GLO_Q1_C), GPIO_FN(SDA2_E), + GPIO_FN(SDA2_CIS_E), GPIO_FN(ETH_RXD0), GPIO_FN(RMII_RXD0), + GPIO_FN(STP_ISEN_0_B), GPIO_FN(TS_SDAT0_D), GPIO_FN(GLO_I0_C), + GPIO_FN(SCIFB1_SCK_G), GPIO_FN(SCK1_E), GPIO_FN(ETH_RXD1), + GPIO_FN(RMII_RXD1), GPIO_FN(HRX0_E), GPIO_FN(STP_ISSYNC_0_B), + GPIO_FN(TS_SCK0_D), GPIO_FN(GLO_I1_C), GPIO_FN(SCIFB1_RXD_G), + GPIO_FN(RX1_E), GPIO_FN(ETH_LINK), GPIO_FN(RMII_LINK), GPIO_FN(HTX0_E), + GPIO_FN(STP_IVCXO27_0_B), GPIO_FN(SCIFB1_TXD_G), GPIO_FN(TX1_E), + GPIO_FN(ETH_REF_CLK), GPIO_FN(RMII_REF_CLK), GPIO_FN(HCTS0_N_E), + GPIO_FN(STP_IVCXO27_1_B), GPIO_FN(HRX0_F), + + /*IPSR7*/ + GPIO_FN(ETH_MDIO), GPIO_FN(RMII_MDIO), GPIO_FN(HRTS0_N_E), + GPIO_FN(SIM0_D_C), GPIO_FN(HCTS0_N_F), GPIO_FN(ETH_TXD1), + GPIO_FN(RMII_TXD1), GPIO_FN(HTX0_F), GPIO_FN(BPFCLK_G), + GPIO_FN(RDS_CLK_F), GPIO_FN(ETH_TX_EN), GPIO_FN(RMII_TX_EN), + GPIO_FN(SIM0_CLK_C), GPIO_FN(HRTS0_N_F), GPIO_FN(ETH_MAGIC), + GPIO_FN(RMII_MAGIC), GPIO_FN(SIM0_RST_C), GPIO_FN(ETH_TXD0), + GPIO_FN(RMII_TXD0), GPIO_FN(STP_ISCLK_1_B), GPIO_FN(TS_SDEN1_C), + GPIO_FN(GLO_SCLK_C), GPIO_FN(ETH_MDC), GPIO_FN(RMII_MDC), + GPIO_FN(STP_ISD_1_B), GPIO_FN(TS_SPSYNC1_C), GPIO_FN(GLO_SDATA_C), + GPIO_FN(PWM0), GPIO_FN(SCIFA2_SCK_C), GPIO_FN(STP_ISEN_1_B), + GPIO_FN(TS_SDAT1_C), GPIO_FN(GLO_SS_C), GPIO_FN(PWM1), + GPIO_FN(SCIFA2_TXD_C), GPIO_FN(STP_ISSYNC_1_B), GPIO_FN(TS_SCK1_C), + GPIO_FN(GLO_RFON_C), GPIO_FN(PCMOE_N), GPIO_FN(PWM2), GPIO_FN(PWMFSW0), + GPIO_FN(SCIFA2_RXD_C), GPIO_FN(PCMWE_N), GPIO_FN(IECLK_C), + GPIO_FN(DU1_DOTCLKIN), GPIO_FN(AUDIO_CLKC), GPIO_FN(AUDIO_CLKOUT_C), + GPIO_FN(VI0_CLK), GPIO_FN(ATACS00_N), GPIO_FN(AVB_RXD1), + GPIO_FN(MII_RXD1), GPIO_FN(VI0_DATA0_VI0_B0), GPIO_FN(ATACS10_N), + GPIO_FN(AVB_RXD2), GPIO_FN(MII_RXD2), + + /*IPSR8*/ + GPIO_FN(VI0_DATA1_VI0_B1), GPIO_FN(ATARD0_N), GPIO_FN(AVB_RXD3), + GPIO_FN(MII_RXD3), GPIO_FN(VI0_DATA2_VI0_B2), GPIO_FN(ATAWR0_N), + GPIO_FN(AVB_RXD4), GPIO_FN(VI0_DATA3_VI0_B3), GPIO_FN(ATADIR0_N), + GPIO_FN(AVB_RXD5), GPIO_FN(VI0_DATA4_VI0_B4), GPIO_FN(ATAG0_N), + GPIO_FN(AVB_RXD6), GPIO_FN(VI0_DATA5_VI0_B5), GPIO_FN(EX_WAIT1), + GPIO_FN(AVB_RXD7), GPIO_FN(VI0_DATA6_VI0_B6), GPIO_FN(AVB_RX_ER), + GPIO_FN(MII_RX_ER), GPIO_FN(VI0_DATA7_VI0_B7), GPIO_FN(AVB_RX_CLK), + GPIO_FN(MII_RX_CLK), GPIO_FN(VI1_CLK), GPIO_FN(AVB_RX_DV), + GPIO_FN(MII_RX_DV), GPIO_FN(VI1_DATA0_VI1_B0), GPIO_FN(SCIFA1_SCK_D), + GPIO_FN(AVB_CRS), GPIO_FN(MII_CRS), GPIO_FN(VI1_DATA1_VI1_B1), + GPIO_FN(SCIFA1_RXD_D), GPIO_FN(AVB_MDC), GPIO_FN(MII_MDC), + GPIO_FN(VI1_DATA2_VI1_B2), GPIO_FN(SCIFA1_TXD_D), GPIO_FN(AVB_MDIO), + GPIO_FN(MII_MDIO), GPIO_FN(VI1_DATA3_VI1_B3), GPIO_FN(SCIFA1_CTS_N_D), + GPIO_FN(AVB_GTX_CLK), GPIO_FN(VI1_DATA4_VI1_B4), + GPIO_FN(SCIFA1_RTS_N_D), GPIO_FN(AVB_MAGIC), GPIO_FN(MII_MAGIC), + GPIO_FN(VI1_DATA5_VI1_B5), GPIO_FN(AVB_PHY_INT), + GPIO_FN(VI1_DATA6_VI1_B6), GPIO_FN(AVB_GTXREFCLK), + GPIO_FN(SD0_CLK), GPIO_FN(VI1_DATA0_VI1_B0_B), GPIO_FN(SD0_CMD), + GPIO_FN(SCIFB1_SCK_B), GPIO_FN(VI1_DATA1_VI1_B1_B), + + /*IPSR9*/ + GPIO_FN(SD0_DAT0), GPIO_FN(SCIFB1_RXD_B), GPIO_FN(VI1_DATA2_VI1_B2_B), + GPIO_FN(SD0_DAT1), GPIO_FN(SCIFB1_TXD_B), GPIO_FN(VI1_DATA3_VI1_B3_B), + GPIO_FN(SD0_DAT2), GPIO_FN(SCIFB1_CTS_N_B), GPIO_FN(VI1_DATA4_VI1_B4_B), + GPIO_FN(SD0_DAT3), GPIO_FN(SCIFB1_RTS_N_B), GPIO_FN(VI1_DATA5_VI1_B5_B), + GPIO_FN(SD0_CD), GPIO_FN(MMC0_D6), GPIO_FN(TS_SDEN0_B), + GPIO_FN(USB0_EXTP), GPIO_FN(GLO_SCLK), GPIO_FN(VI1_DATA6_VI1_B6_B), + GPIO_FN(SCL1_B), GPIO_FN(SCL1_CIS_B), GPIO_FN(VI2_DATA6_VI2_B6_B), + GPIO_FN(SD0_WP), GPIO_FN(MMC0_D7), GPIO_FN(TS_SPSYNC0_B), + GPIO_FN(USB0_IDIN), GPIO_FN(GLO_SDATA), GPIO_FN(VI1_DATA7_VI1_B7_B), + GPIO_FN(SDA1_B), GPIO_FN(SDA1_CIS_B), GPIO_FN(VI2_DATA7_VI2_B7_B), + GPIO_FN(SD1_CLK), GPIO_FN(AVB_TX_EN), GPIO_FN(MII_TX_EN), + GPIO_FN(SD1_CMD), GPIO_FN(AVB_TX_ER), GPIO_FN(MII_TX_ER), + GPIO_FN(SCIFB0_SCK_B), GPIO_FN(SD1_DAT0), GPIO_FN(AVB_TX_CLK), + GPIO_FN(MII_TX_CLK), GPIO_FN(SCIFB0_RXD_B), GPIO_FN(SD1_DAT1), + GPIO_FN(AVB_LINK), GPIO_FN(MII_LINK), GPIO_FN(SCIFB0_TXD_B), + GPIO_FN(SD1_DAT2), GPIO_FN(AVB_COL), GPIO_FN(MII_COL), + GPIO_FN(SCIFB0_CTS_N_B), GPIO_FN(SD1_DAT3), GPIO_FN(AVB_RXD0), + GPIO_FN(MII_RXD0), GPIO_FN(SCIFB0_RTS_N_B), GPIO_FN(SD1_CD), + GPIO_FN(MMC1_D6), GPIO_FN(TS_SDEN1), GPIO_FN(USB1_EXTP), + GPIO_FN(GLO_SS), GPIO_FN(VI0_CLK_B), GPIO_FN(SCL2_D), + GPIO_FN(SCL2_CIS_D), GPIO_FN(SIM0_CLK_B), GPIO_FN(VI3_CLK_B), + + /*IPSR10*/ + GPIO_FN(SD1_WP), GPIO_FN(MMC1_D7), GPIO_FN(TS_SPSYNC1), + GPIO_FN(USB1_IDIN), GPIO_FN(GLO_RFON), GPIO_FN(VI1_CLK_B), + GPIO_FN(SDA2_D), GPIO_FN(SDA2_CIS_D), GPIO_FN(SIM0_D_B), + GPIO_FN(SD2_CLK), GPIO_FN(MMC0_CLK), GPIO_FN(SIM0_CLK), + GPIO_FN(VI0_DATA0_VI0_B0_B), GPIO_FN(TS_SDEN0_C), GPIO_FN(GLO_SCLK_B), + GPIO_FN(VI3_DATA0_B), GPIO_FN(SD2_CMD), GPIO_FN(MMC0_CMD), + GPIO_FN(SIM0_D), GPIO_FN(VI0_DATA1_VI0_B1_B), GPIO_FN(SCIFB1_SCK_E), + GPIO_FN(SCK1_D), GPIO_FN(TS_SPSYNC0_C), GPIO_FN(GLO_SDATA_B), + GPIO_FN(VI3_DATA1_B), GPIO_FN(SD2_DAT0), GPIO_FN(MMC0_D0), + GPIO_FN(FMCLK_B), GPIO_FN(VI0_DATA2_VI0_B2_B), GPIO_FN(SCIFB1_RXD_E), + GPIO_FN(RX1_D), GPIO_FN(TS_SDAT0_C), GPIO_FN(GLO_SS_B), + GPIO_FN(VI3_DATA2_B), GPIO_FN(SD2_DAT1), GPIO_FN(MMC0_D1), + GPIO_FN(FMIN_B), GPIO_FN(RDS_DATA), GPIO_FN(VI0_DATA3_VI0_B3_B), + GPIO_FN(SCIFB1_TXD_E), GPIO_FN(TX1_D), GPIO_FN(TS_SCK0_C), + GPIO_FN(GLO_RFON_B), GPIO_FN(VI3_DATA3_B), GPIO_FN(SD2_DAT2), + GPIO_FN(MMC0_D2), GPIO_FN(BPFCLK_B), GPIO_FN(RDS_CLK), + GPIO_FN(VI0_DATA4_VI0_B4_B), GPIO_FN(HRX0_D), GPIO_FN(TS_SDEN1_B), + GPIO_FN(GLO_Q0_B), GPIO_FN(VI3_DATA4_B), GPIO_FN(SD2_DAT3), + GPIO_FN(MMC0_D3), GPIO_FN(SIM0_RST), GPIO_FN(VI0_DATA5_VI0_B5_B), + GPIO_FN(HTX0_D), GPIO_FN(TS_SPSYNC1_B), GPIO_FN(GLO_Q1_B), + GPIO_FN(VI3_DATA5_B), GPIO_FN(SD2_CD), GPIO_FN(MMC0_D4), + GPIO_FN(TS_SDAT0_B), GPIO_FN(USB2_EXTP), GPIO_FN(GLO_I0), + GPIO_FN(VI0_DATA6_VI0_B6_B), GPIO_FN(HCTS0_N_D), GPIO_FN(TS_SDAT1_B), + GPIO_FN(GLO_I0_B), GPIO_FN(VI3_DATA6_B), + + /*IPSR11*/ + GPIO_FN(SD2_WP), GPIO_FN(MMC0_D5), GPIO_FN(TS_SCK0_B), + GPIO_FN(USB2_IDIN), GPIO_FN(GLO_I1), GPIO_FN(VI0_DATA7_VI0_B7_B), + GPIO_FN(HRTS0_N_D), GPIO_FN(TS_SCK1_B), GPIO_FN(GLO_I1_B), + GPIO_FN(VI3_DATA7_B), GPIO_FN(SD3_CLK), GPIO_FN(MMC1_CLK), + GPIO_FN(SD3_CMD), GPIO_FN(MMC1_CMD), GPIO_FN(MTS_N), GPIO_FN(SD3_DAT0), + GPIO_FN(MMC1_D0), GPIO_FN(STM_N), GPIO_FN(SD3_DAT1), GPIO_FN(MMC1_D1), + GPIO_FN(MDATA), GPIO_FN(SD3_DAT2), GPIO_FN(MMC1_D2), GPIO_FN(SDATA), + GPIO_FN(SD3_DAT3), GPIO_FN(MMC1_D3), GPIO_FN(SCKZ), GPIO_FN(SD3_CD), + GPIO_FN(MMC1_D4), GPIO_FN(TS_SDAT1), GPIO_FN(VSP), GPIO_FN(GLO_Q0), + GPIO_FN(SIM0_RST_B), GPIO_FN(SD3_WP), GPIO_FN(MMC1_D5), + GPIO_FN(TS_SCK1), GPIO_FN(GLO_Q1), GPIO_FN(FMIN_C), GPIO_FN(RDS_DATA_B), + GPIO_FN(FMIN_E), GPIO_FN(RDS_DATA_D), GPIO_FN(FMIN_F), + GPIO_FN(RDS_DATA_E), GPIO_FN(MLB_CLK), GPIO_FN(SCL2_B), + GPIO_FN(SCL2_CIS_B), GPIO_FN(MLB_SIG), GPIO_FN(SCIFB1_RXD_D), + GPIO_FN(RX1_C), GPIO_FN(SDA2_B), GPIO_FN(SDA2_CIS_B), GPIO_FN(MLB_DAT), + GPIO_FN(SPV_EVEN), GPIO_FN(SCIFB1_TXD_D), GPIO_FN(TX1_C), + GPIO_FN(BPFCLK_C), GPIO_FN(RDS_CLK_B), GPIO_FN(SSI_SCK0129), + GPIO_FN(CAN_CLK_B), GPIO_FN(MOUT0), + +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + { PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) { + GP_0_31_FN, FN_IP3_17_15, + GP_0_30_FN, FN_IP3_14_12, + GP_0_29_FN, FN_IP3_11_8, + GP_0_28_FN, FN_IP3_7_4, + GP_0_27_FN, FN_IP3_3_0, + GP_0_26_FN, FN_IP2_28_26, + GP_0_25_FN, FN_IP2_25_22, + GP_0_24_FN, FN_IP2_21_18, + GP_0_23_FN, FN_IP2_17_15, + GP_0_22_FN, FN_IP2_14_12, + GP_0_21_FN, FN_IP2_11_9, + GP_0_20_FN, FN_IP2_8_6, + GP_0_19_FN, FN_IP2_5_3, + GP_0_18_FN, FN_IP2_2_0, + GP_0_17_FN, FN_IP1_29_28, + GP_0_16_FN, FN_IP1_27_26, + GP_0_15_FN, FN_IP1_25_22, + GP_0_14_FN, FN_IP1_21_18, + GP_0_13_FN, FN_IP1_17_15, + GP_0_12_FN, FN_IP1_14_12, + GP_0_11_FN, FN_IP1_11_8, + GP_0_10_FN, FN_IP1_7_4, + GP_0_9_FN, FN_IP1_3_0, + GP_0_8_FN, FN_IP0_30_27, + GP_0_7_FN, FN_IP0_26_23, + GP_0_6_FN, FN_IP0_22_20, + GP_0_5_FN, FN_IP0_19_16, + GP_0_4_FN, FN_IP0_15_12, + GP_0_3_FN, FN_IP0_11_9, + GP_0_2_FN, FN_IP0_8_6, + GP_0_1_FN, FN_IP0_5_3, + GP_0_0_FN, FN_IP0_2_0 } + }, + { PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) { + 0, 0, + 0, 0, + GP_1_29_FN, FN_IP6_13_11, + GP_1_28_FN, FN_IP6_10_9, + GP_1_27_FN, FN_IP6_8_6, + GP_1_26_FN, FN_IP6_5_3, + GP_1_25_FN, FN_IP6_2_0, + GP_1_24_FN, FN_IP5_29_27, + GP_1_23_FN, FN_IP5_26_24, + GP_1_22_FN, FN_IP5_23_21, + GP_1_21_FN, FN_IP5_20_18, + GP_1_20_FN, FN_IP5_17_15, + GP_1_19_FN, FN_IP5_14_13, + GP_1_18_FN, FN_IP5_12_10, + GP_1_17_FN, FN_IP5_9_6, + GP_1_16_FN, FN_IP5_5_3, + GP_1_15_FN, FN_IP5_2_0, + GP_1_14_FN, FN_IP4_29_27, + GP_1_13_FN, FN_IP4_26_24, + GP_1_12_FN, FN_IP4_23_21, + GP_1_11_FN, FN_IP4_20_18, + GP_1_10_FN, FN_IP4_17_15, + GP_1_9_FN, FN_IP4_14_12, + GP_1_8_FN, FN_IP4_11_9, + GP_1_7_FN, FN_IP4_8_6, + GP_1_6_FN, FN_IP4_5_3, + GP_1_5_FN, FN_IP4_2_0, + GP_1_4_FN, FN_IP3_31_29, + GP_1_3_FN, FN_IP3_28_26, + GP_1_2_FN, FN_IP3_25_23, + GP_1_1_FN, FN_IP3_22_20, + GP_1_0_FN, FN_IP3_19_18, } + }, + { PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) { + 0, 0, + 0, 0, + GP_2_29_FN, FN_IP7_15_13, + GP_2_28_FN, FN_IP7_12_10, + GP_2_27_FN, FN_IP7_9_8, + GP_2_26_FN, FN_IP7_7_6, + GP_2_25_FN, FN_IP7_5_3, + GP_2_24_FN, FN_IP7_2_0, + GP_2_23_FN, FN_IP6_31_29, + GP_2_22_FN, FN_IP6_28_26, + GP_2_21_FN, FN_IP6_25_23, + GP_2_20_FN, FN_IP6_22_20, + GP_2_19_FN, FN_IP6_19_17, + GP_2_18_FN, FN_IP6_16_14, + GP_2_17_FN, FN_VI1_DATA7_VI1_B7, + GP_2_16_FN, FN_IP8_27, + GP_2_15_FN, FN_IP8_26, + GP_2_14_FN, FN_IP8_25_24, + GP_2_13_FN, FN_IP8_23_22, + GP_2_12_FN, FN_IP8_21_20, + GP_2_11_FN, FN_IP8_19_18, + GP_2_10_FN, FN_IP8_17_16, + GP_2_9_FN, FN_IP8_15_14, + GP_2_8_FN, FN_IP8_13_12, + GP_2_7_FN, FN_IP8_11_10, + GP_2_6_FN, FN_IP8_9_8, + GP_2_5_FN, FN_IP8_7_6, + GP_2_4_FN, FN_IP8_5_4, + GP_2_3_FN, FN_IP8_3_2, + GP_2_2_FN, FN_IP8_1_0, + GP_2_1_FN, FN_IP7_30_29, + GP_2_0_FN, FN_IP7_28_27 } + }, + { PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) { + GP_3_31_FN, FN_IP11_21_18, + GP_3_30_FN, FN_IP11_17_15, + GP_3_29_FN, FN_IP11_14_13, + GP_3_28_FN, FN_IP11_12_11, + GP_3_27_FN, FN_IP11_10_9, + GP_3_26_FN, FN_IP11_8_7, + GP_3_25_FN, FN_IP11_6_5, + GP_3_24_FN, FN_IP11_4, + GP_3_23_FN, FN_IP11_3_0, + GP_3_22_FN, FN_IP10_29_26, + GP_3_21_FN, FN_IP10_25_23, + GP_3_20_FN, FN_IP10_22_19, + GP_3_19_FN, FN_IP10_18_15, + GP_3_18_FN, FN_IP10_14_11, + GP_3_17_FN, FN_IP10_10_7, + GP_3_16_FN, FN_IP10_6_4, + GP_3_15_FN, FN_IP10_3_0, + GP_3_14_FN, FN_IP9_31_28, + GP_3_13_FN, FN_IP9_27_26, + GP_3_12_FN, FN_IP9_25_24, + GP_3_11_FN, FN_IP9_23_22, + GP_3_10_FN, FN_IP9_21_20, + GP_3_9_FN, FN_IP9_19_18, + GP_3_8_FN, FN_IP9_17_16, + GP_3_7_FN, FN_IP9_15_12, + GP_3_6_FN, FN_IP9_11_8, + GP_3_5_FN, FN_IP9_7_6, + GP_3_4_FN, FN_IP9_5_4, + GP_3_3_FN, FN_IP9_3_2, + GP_3_2_FN, FN_IP9_1_0, + GP_3_1_FN, FN_IP8_30_29, + GP_3_0_FN, FN_IP8_28 } + }, + { PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) { + GP_4_31_FN, FN_IP14_18_16, + GP_4_30_FN, FN_IP14_15_12, + GP_4_29_FN, FN_IP14_11_9, + GP_4_28_FN, FN_IP14_8_6, + GP_4_27_FN, FN_IP14_5_3, + GP_4_26_FN, FN_IP14_2_0, + GP_4_25_FN, FN_IP13_30_29, + GP_4_24_FN, FN_IP13_28_26, + GP_4_23_FN, FN_IP13_25_23, + GP_4_22_FN, FN_IP13_22_19, + GP_4_21_FN, FN_IP13_18_16, + GP_4_20_FN, FN_IP13_15_13, + GP_4_19_FN, FN_IP13_12_10, + GP_4_18_FN, FN_IP13_9_7, + GP_4_17_FN, FN_IP13_6_3, + GP_4_16_FN, FN_IP13_2_0, + GP_4_15_FN, FN_IP12_30_28, + GP_4_14_FN, FN_IP12_27_25, + GP_4_13_FN, FN_IP12_24_23, + GP_4_12_FN, FN_IP12_22_20, + GP_4_11_FN, FN_IP12_19_17, + GP_4_10_FN, FN_IP12_16_14, + GP_4_9_FN, FN_IP12_13_11, + GP_4_8_FN, FN_IP12_10_8, + GP_4_7_FN, FN_IP12_7_6, + GP_4_6_FN, FN_IP12_5_4, + GP_4_5_FN, FN_IP12_3_2, + GP_4_4_FN, FN_IP12_1_0, + GP_4_3_FN, FN_IP11_31_30, + GP_4_2_FN, FN_IP11_29_27, + GP_4_1_FN, FN_IP11_26_24, + GP_4_0_FN, FN_IP11_23_22 } + }, + { PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) { + GP_5_31_FN, FN_IP7_24_22, + GP_5_30_FN, FN_IP7_21_19, + GP_5_29_FN, FN_IP7_18_16, + GP_5_28_FN, FN_DU_DOTCLKIN2, + GP_5_27_FN, FN_IP7_26_25, + GP_5_26_FN, FN_DU_DOTCLKIN0, + GP_5_25_FN, FN_AVS2, + GP_5_24_FN, FN_AVS1, + GP_5_23_FN, FN_USB2_OVC, + GP_5_22_FN, FN_USB2_PWEN, + GP_5_21_FN, FN_IP16_7, + GP_5_20_FN, FN_IP16_6, + GP_5_19_FN, FN_USB0_OVC_VBUS, + GP_5_18_FN, FN_USB0_PWEN, + GP_5_17_FN, FN_IP16_5_3, + GP_5_16_FN, FN_IP16_2_0, + GP_5_15_FN, FN_IP15_29_28, + GP_5_14_FN, FN_IP15_27_26, + GP_5_13_FN, FN_IP15_25_23, + GP_5_12_FN, FN_IP15_22_20, + GP_5_11_FN, FN_IP15_19_18, + GP_5_10_FN, FN_IP15_17_16, + GP_5_9_FN, FN_IP15_15_14, + GP_5_8_FN, FN_IP15_13_12, + GP_5_7_FN, FN_IP15_11_9, + GP_5_6_FN, FN_IP15_8_6, + GP_5_5_FN, FN_IP15_5_3, + GP_5_4_FN, FN_IP15_2_0, + GP_5_3_FN, FN_IP14_30_28, + GP_5_2_FN, FN_IP14_27_25, + GP_5_1_FN, FN_IP14_24_22, + GP_5_0_FN, FN_IP14_21_19 } + }, + /* IPSR0 - IPSR5 */ + { PINMUX_CFG_REG_VAR("IPSR6", 0xE6060038, 32, + 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3) { + /* IP6_31_29 [3] */ + FN_ETH_REF_CLK, FN_RMII_REF_CLK, FN_HCTS0_N_E, + FN_STP_IVCXO27_1_B, FN_HRX0_F, 0, 0, 0, + /* IP6_28_26 [3] */ + FN_ETH_LINK, FN_RMII_LINK, FN_HTX0_E, + FN_STP_IVCXO27_0_B, FN_SCIFB1_TXD_G, FN_TX1_E, 0, 0, + /* IP6_25_23 [3] */ + FN_ETH_RXD1, FN_RMII_RXD1, FN_HRX0_E, FN_STP_ISSYNC_0_B, + FN_TS_SCK0_D, FN_GLO_I1_C, FN_SCIFB1_RXD_G, FN_RX1_E, + /* IP6_22_20 [3] */ + FN_ETH_RXD0, FN_RMII_RXD0, FN_STP_ISEN_0_B, FN_TS_SDAT0_D, + FN_GLO_I0_C, FN_SCIFB1_SCK_G, FN_SCK1_E, 0, + /* IP6_19_17 [3] */ + FN_ETH_RX_ER, FN_RMII_RX_ER, FN_STP_ISD_0_B, + FN_TS_SPSYNC0_D, FN_GLO_Q1_C, FN_SDA2_E, FN_SDA2_CIS_E, 0, + /* IP6_16_14 [3] */ + FN_ETH_CRS_DV, FN_RMII_CRS_DV, FN_STP_ISCLK_0_B, + FN_TS_SDEN0_D, FN_GLO_Q0_C, FN_SCL2_E, + FN_SCL2_CIS_E, 0, + /* IP6_13_11 [3] */ + FN_DACK2, FN_IRQ2, FN_INTC_IRQ2_N, + FN_SSI_SDATA6_B, FN_HRTS0_N_B, FN_MSIOF0_RXD_B, 0, 0, + /* IP6_10_9 [2] */ + FN_DREQ2_N, FN_HSCK1_B, FN_HCTS0_N_B, FN_MSIOF0_TXD_B, + /* IP6_8_6 [3] */ + FN_DACK1, FN_IRQ1, FN_INTC_IRQ1_N, FN_SSI_WS6_B, + FN_SSI_SDATA8_C, 0, 0, 0, + /* IP6_5_3 [3] */ + FN_DREQ1_N, FN_VI1_CLKENB, FN_VI1_CLKENB_B, + FN_SSI_SDATA7_C, FN_SSI_SCK78_B, 0, 0, 0, + /* IP6_2_0 [3] */ + FN_DACK0, FN_IRQ0, FN_INTC_IRQ0_N, FN_SSI_SCK6_B, + FN_VI1_VSYNC_N, FN_VI1_VSYNC_N_B, FN_SSI_WS78_C, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32, + 1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 3) { + /* IP7_31 [1] */ + 0, 0, + /* IP7_30_29 [2] */ + FN_VI0_DATA0_VI0_B0, FN_ATACS10_N, FN_AVB_RXD2, + FN_MII_RXD2, + /* IP7_28_27 [2] */ + FN_VI0_CLK, FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1, + /* IP7_26_25 [2] */ + FN_DU1_DOTCLKIN, FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, 0, + /* IP7_24_22 [3] */ + FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C, FN_PCMWE_N, FN_IECLK_C, + 0, 0, 0, + /* IP7_21_19 [3] */ + FN_PWM1, FN_SCIFA2_TXD_C, FN_STP_ISSYNC_1_B, FN_TS_SCK1_C, + FN_GLO_RFON_C, FN_PCMOE_N, 0, 0, + /* IP7_18_16 [3] */ + FN_PWM0, FN_SCIFA2_SCK_C, FN_STP_ISEN_1_B, FN_TS_SDAT1_C, + FN_GLO_SS_C, 0, 0, 0, + /* IP7_15_13 [3] */ + FN_ETH_MDC, FN_RMII_MDC, FN_STP_ISD_1_B, + FN_TS_SPSYNC1_C, FN_GLO_SDATA_C, 0, 0, 0, + /* IP7_12_10 [3] */ + FN_ETH_TXD0, FN_RMII_TXD0, FN_STP_ISCLK_1_B, FN_TS_SDEN1_C, + FN_GLO_SCLK_C, 0, 0, 0, + /* IP7_9_8 [2] */ + FN_ETH_MAGIC, FN_RMII_MAGIC, FN_SIM0_RST_C, 0, + /* IP7_7_6 [2] */ + FN_ETH_TX_EN, FN_RMII_TX_EN, FN_SIM0_CLK_C, FN_HRTS0_N_F, + /* IP7_5_3 [3] */ + FN_ETH_TXD1, FN_RMII_TXD1, FN_HTX0_F, FN_BPFCLK_G, FN_RDS_CLK_F, + 0, 0, 0, + /* IP7_2_0 [3] */ + FN_ETH_MDIO, FN_RMII_MDIO, FN_HRTS0_N_E, + FN_SIM0_D_C, FN_HCTS0_N_F, 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR8", 0xE6060040, 32, + 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2) { + /* IP8_31 [1] */ + 0, 0, + /* IP8_30_29 [2] */ + FN_SD0_CMD, FN_SCIFB1_SCK_B, FN_VI1_DATA1_VI1_B1_B, 0, + /* IP8_28 [1] */ + FN_SD0_CLK, FN_VI1_DATA0_VI1_B0_B, + /* IP8_27 [1] */ + FN_VI1_DATA6_VI1_B6, FN_AVB_GTXREFCLK, + /* IP8_26 [1] */ + FN_VI1_DATA5_VI1_B5, FN_AVB_PHY_INT, + /* IP8_25_24 [2] */ + FN_VI1_DATA4_VI1_B4, FN_SCIFA1_RTS_N_D, + FN_AVB_MAGIC, FN_MII_MAGIC, + /* IP8_23_22 [2] */ + FN_VI1_DATA3_VI1_B3, FN_SCIFA1_CTS_N_D, FN_AVB_GTX_CLK, 0, + /* IP8_21_20 [2] */ + FN_VI1_DATA2_VI1_B2, FN_SCIFA1_TXD_D, FN_AVB_MDIO, + FN_MII_MDIO, + /* IP8_19_18 [2] */ + FN_VI1_DATA1_VI1_B1, FN_SCIFA1_RXD_D, FN_AVB_MDC, FN_MII_MDC, + /* IP8_17_16 [2] */ + FN_VI1_DATA0_VI1_B0, FN_SCIFA1_SCK_D, FN_AVB_CRS, FN_MII_CRS, + /* IP8_15_14 [2] */ + FN_VI1_CLK, FN_AVB_RX_DV, FN_MII_RX_DV, 0, + /* IP8_13_12 [2] */ + FN_VI0_DATA7_VI0_B7, FN_AVB_RX_CLK, FN_MII_RX_CLK, 0, + /* IP8_11_10 [2] */ + FN_VI0_DATA6_VI0_B6, FN_AVB_RX_ER, FN_MII_RX_ER, 0, + /* IP8_9_8 [2] */ + FN_VI0_DATA5_VI0_B5, FN_EX_WAIT1, FN_AVB_RXD7, 0, + /* IP8_7_6 [2] */ + FN_VI0_DATA4_VI0_B4, FN_ATAG0_N, FN_AVB_RXD6, 0, + /* IP8_5_4 [2] */ + FN_VI0_DATA3_VI0_B3, FN_ATADIR0_N, FN_AVB_RXD5, 0, + /* IP8_3_2 [2] */ + FN_VI0_DATA2_VI0_B2, FN_ATAWR0_N, FN_AVB_RXD4, 0, + /* IP8_1_0 [2] */ + FN_VI0_DATA1_VI0_B1, FN_ATARD0_N, FN_AVB_RXD3, FN_MII_RXD3, } + }, + { PINMUX_CFG_REG_VAR("IPSR9", 0xE6060044, 32, + 4, 2, 2, 2, 2, 2, 2, 4, 4, 2, 2, 2, 2) { + /* IP9_31_28 [4] */ + FN_SD1_CD, FN_MMC1_D6, FN_TS_SDEN1, FN_USB1_EXTP, + FN_GLO_SS, FN_VI0_CLK_B, FN_SCL2_D, FN_SCL2_CIS_D, + FN_SIM0_CLK_B, FN_VI3_CLK_B, 0, 0, 0, 0, 0, 0, + /* IP9_27_26 [2] */ + FN_SD1_DAT3, FN_AVB_RXD0, FN_MII_RXD0, FN_SCIFB0_RTS_N_B, + /* IP9_25_24 [2] */ + FN_SD1_DAT2, FN_AVB_COL, FN_MII_COL, FN_SCIFB0_CTS_N_B, + /* IP9_23_22 [2] */ + FN_SD1_DAT1, FN_AVB_LINK, FN_MII_LINK, FN_SCIFB0_TXD_B, + /* IP9_21_20 [2] */ + FN_SD1_DAT0, FN_AVB_TX_CLK, FN_MII_TX_CLK, FN_SCIFB0_RXD_B, + /* IP9_19_18 [2] */ + FN_SD1_CMD, FN_AVB_TX_ER, FN_MII_TX_ER, FN_SCIFB0_SCK_B, + /* IP9_17_16 [2] */ + FN_SD1_CLK, FN_AVB_TX_EN, FN_MII_TX_EN, 0, + /* IP9_15_12 [4] */ + FN_SD0_WP, FN_MMC0_D7, FN_TS_SPSYNC0_B, FN_USB0_IDIN, + FN_GLO_SDATA, FN_VI1_DATA7_VI1_B7_B, FN_SDA1_B, + FN_SDA1_CIS_B, FN_VI2_DATA7_VI2_B7_B, 0, 0, 0, 0, 0, 0, 0, + /* IP9_11_8 [4] */ + FN_SD0_CD, FN_MMC0_D6, FN_TS_SDEN0_B, FN_USB0_EXTP, + FN_GLO_SCLK, FN_VI1_DATA6_VI1_B6_B, FN_SCL1_B, + FN_SCL1_CIS_B, FN_VI2_DATA6_VI2_B6_B, 0, 0, 0, 0, 0, 0, 0, + /* IP9_7_6 [2] */ + FN_SD0_DAT3, FN_SCIFB1_RTS_N_B, FN_VI1_DATA5_VI1_B5_B, 0, + /* IP9_5_4 [2] */ + FN_SD0_DAT2, FN_SCIFB1_CTS_N_B, FN_VI1_DATA4_VI1_B4_B, 0, + /* IP9_3_2 [2] */ + FN_SD0_DAT1, FN_SCIFB1_TXD_B, FN_VI1_DATA3_VI1_B3_B, 0, + /* IP9_1_0 [2] */ + FN_SD0_DAT0, FN_SCIFB1_RXD_B, FN_VI1_DATA2_VI1_B2_B, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR10", 0xE6060048, 32, + 2, 4, 3, 4, 4, 4, 4, 3, 4) { + /* IP10_31_30 [2] */ + 0, 0, 0, 0, + /* IP10_29_26 [4] */ + FN_SD2_CD, FN_MMC0_D4, FN_TS_SDAT0_B, FN_USB2_EXTP, FN_GLO_I0, + FN_VI0_DATA6_VI0_B6_B, FN_HCTS0_N_D, FN_TS_SDAT1_B, + FN_GLO_I0_B, FN_VI3_DATA6_B, 0, 0, 0, 0, 0, 0, + /* IP10_25_23 [3] */ + FN_SD2_DAT3, FN_MMC0_D3, FN_SIM0_RST, FN_VI0_DATA5_VI0_B5_B, + FN_HTX0_D, FN_TS_SPSYNC1_B, FN_GLO_Q1_B, FN_VI3_DATA5_B, + /* IP10_22_19 [4] */ + FN_SD2_DAT2, FN_MMC0_D2, FN_BPFCLK_B, FN_RDS_CLK, + FN_VI0_DATA4_VI0_B4_B, FN_HRX0_D, FN_TS_SDEN1_B, + FN_GLO_Q0_B, FN_VI3_DATA4_B, 0, 0, 0, 0, 0, 0, 0, + /* IP10_18_15 [4] */ + FN_SD2_DAT1, FN_MMC0_D1, FN_FMIN_B, FN_RDS_DATA, + FN_VI0_DATA3_VI0_B3_B, FN_SCIFB1_TXD_E, FN_TX1_D, + FN_TS_SCK0_C, FN_GLO_RFON_B, FN_VI3_DATA3_B, + 0, 0, 0, 0, 0, 0, + /* IP10_14_11 [4] */ + FN_SD2_DAT0, FN_MMC0_D0, FN_FMCLK_B, + FN_VI0_DATA2_VI0_B2_B, FN_SCIFB1_RXD_E, FN_RX1_D, + FN_TS_SDAT0_C, FN_GLO_SS_B, FN_VI3_DATA2_B, + 0, 0, 0, 0, 0, 0, 0, + /* IP10_10_7 [4] */ + FN_SD2_CMD, FN_MMC0_CMD, FN_SIM0_D, + FN_VI0_DATA1_VI0_B1_B, FN_SCIFB1_SCK_E, FN_SCK1_D, + FN_TS_SPSYNC0_C, FN_GLO_SDATA_B, FN_VI3_DATA1_B, + 0, 0, 0, 0, 0, 0, 0, + /* IP10_6_4 [3] */ + FN_SD2_CLK, FN_MMC0_CLK, FN_SIM0_CLK, + FN_VI0_DATA0_VI0_B0_B, FN_TS_SDEN0_C, FN_GLO_SCLK_B, + FN_VI3_DATA0_B, 0, + /* IP10_3_0 [4] */ + FN_SD1_WP, FN_MMC1_D7, FN_TS_SPSYNC1, FN_USB1_IDIN, + FN_GLO_RFON, FN_VI1_CLK_B, FN_SDA2_D, FN_SDA2_CIS_D, + FN_SIM0_D_B, 0, 0, 0, 0, 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32, + 2, 3, 3, 2, 4, 3, 2, 2, 2, 2, 2, 1, 4) { + /* IP11_31_30 [2] */ + FN_SSI_SCK0129, FN_CAN_CLK_B, FN_MOUT0, 0, + /* IP11_29_27 [3] */ + FN_MLB_DAT, FN_SPV_EVEN, FN_SCIFB1_TXD_D, FN_TX1_C, FN_BPFCLK_C, + FN_RDS_CLK_B, 0, 0, + /* IP11_26_24 [3] */ + FN_MLB_SIG, FN_SCIFB1_RXD_D, FN_RX1_C, FN_SDA2_B, FN_SDA2_CIS_B, + 0, 0, 0, + /* IP11_23_22 [2] */ + FN_MLB_CLK, FN_SCL2_B, FN_SCL2_CIS_B, 0, + /* IP11_21_18 [4] */ + FN_SD3_WP, FN_MMC1_D5, FN_TS_SCK1, FN_GLO_Q1, FN_FMIN_C, + FN_RDS_DATA_B, FN_FMIN_E, FN_RDS_DATA_D, FN_FMIN_F, + FN_RDS_DATA_E, 0, 0, 0, 0, 0, 0, + /* IP11_17_15 [3] */ + FN_SD3_CD, FN_MMC1_D4, FN_TS_SDAT1, + FN_VSP, FN_GLO_Q0, FN_SIM0_RST_B, 0, 0, + /* IP11_14_13 [2] */ + FN_SD3_DAT3, FN_MMC1_D3, FN_SCKZ, 0, + /* IP11_12_11 [2] */ + FN_SD3_DAT2, FN_MMC1_D2, FN_SDATA, 0, + /* IP11_10_9 [2] */ + FN_SD3_DAT1, FN_MMC1_D1, FN_MDATA, 0, + /* IP11_8_7 [2] */ + FN_SD3_DAT0, FN_MMC1_D0, FN_STM_N, 0, + /* IP11_6_5 [2] */ + FN_SD3_CMD, FN_MMC1_CMD, FN_MTS_N, 0, + /* IP11_4 [1] */ + FN_SD3_CLK, FN_MMC1_CLK, + /* IP11_3_0 [4] */ + FN_SD2_WP, FN_MMC0_D5, FN_TS_SCK0_B, FN_USB2_IDIN, + FN_GLO_I1, FN_VI0_DATA7_VI0_B7_B, FN_HRTS0_N_D, + FN_TS_SCK1_B, FN_GLO_I1_B, FN_VI3_DATA7_B, 0, 0, 0, 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32, + 3, 2, 2, 3, 2, 1, 1, 1, 2, 1, + 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1) { + /* SEL_SCIF1 [3] */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + FN_SEL_SCIF1_4, 0, 0, 0, + /* SEL_SCIFB [2] */ + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, 0, + /* SEL_SCIFB2 [2] */ + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, 0, + /* SEL_SCIFB1 [3] */ + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, + FN_SEL_SCIFB1_3, FN_SEL_SCIFB1_4, FN_SEL_SCIFB1_5, + FN_SEL_SCIFB1_6, 0, + /* SEL_SCIFA1 [2] */ + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, + FN_SEL_SCIFA1_3, + /* SEL_SCIF0 [1] */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, + /* SEL_SCIFA [1] */ + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + /* SEL_SOF1 [1] */ + FN_SEL_SOF1_0, FN_SEL_SOF1_1, + /* SEL_SSI7 [2] */ + FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2, 0, + /* SEL_SSI6 [1] */ + FN_SEL_SSI6_0, FN_SEL_SSI6_1, + /* SEL_SSI5 [2] */ + FN_SEL_SSI5_0, FN_SEL_SSI5_1, FN_SEL_SSI5_2, 0, + /* SEL_VI3 [1] */ + FN_SEL_VI3_0, FN_SEL_VI3_1, + /* SEL_VI2 [1] */ + FN_SEL_VI2_0, FN_SEL_VI2_1, + /* SEL_VI1 [1] */ + FN_SEL_VI1_0, FN_SEL_VI1_1, + /* SEL_VI0 [1] */ + FN_SEL_VI0_0, FN_SEL_VI0_1, + /* SEL_TSIF1 [2] */ + FN_SEL_TSIF1_0, FN_SEL_TSIF1_1, FN_SEL_TSIF1_2, 0, + /* RESERVED [1] */ + 0, 0, + /* SEL_LBS [1] */ + FN_SEL_LBS_0, FN_SEL_LBS_1, + /* SEL_TSIF0 [2] */ + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + /* SEL_SOF3 [1] */ + FN_SEL_SOF3_0, FN_SEL_SOF3_1, + /* SEL_SOF0 [1] */ + FN_SEL_SOF0_0, FN_SEL_SOF0_1, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32, + 2, 1, 1, 1, 1, 2, 1, 2, 1, + 2, 1, 1, 1, 3, 3, 2, 3, 2, 2) { + /* RESEVED [2] */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_TMU1 [1] */ + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + /* SEL_HSCIF1 [1] */ + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, + /* SEL_SCIFCLK [1] */ + FN_SEL_SCIFCLK_0, FN_SEL_SCIFCLK_1, + /* SEL_CAN0 [2] */ + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + /* SEL_CANCLK [1] */ + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, + /* SEL_SCIFA2 [2] */ + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, FN_SEL_SCIFA2_2, 0, + /* SEL_CAN1 [1] */ + FN_SEL_CAN1_0, FN_SEL_CAN1_1, + /* RESEVED [2] */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_ADI [1] */ + FN_SEL_ADI_0, FN_SEL_ADI_1, + /* SEL_SSP [1] */ + FN_SEL_SSP_0, FN_SEL_SSP_1, + /* SEL_FM [3] */ + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3, + FN_SEL_FM_4, FN_SEL_FM_5, FN_SEL_FM_6, 0, + /* SEL_HSCIF0 [3] */ + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, + FN_SEL_HSCIF0_3, FN_SEL_HSCIF0_4, FN_SEL_HSCIF0_5, 0, 0, + /* SEL_GPS [2] */ + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, 0, + /* SEL_RDS [3] */ + FN_SEL_RDS_0, FN_SEL_RDS_1, FN_SEL_RDS_2, + FN_SEL_RDS_3, FN_SEL_RDS_4, FN_SEL_RDS_5, 0, 0, + /* SEL_SIM [2] */ + FN_SEL_SIM_0, FN_SEL_SIM_1, FN_SEL_SIM_2, 0, + /* SEL_SSI8 [2] */ + FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32, + 1, 1, 2, 4, 4, 2, 2, + 4, 2, 3, 2, 3, 2) { + /* SEL_IICDVFS [1] */ + FN_SEL_IICDVFS_0, FN_SEL_IICDVFS_1, + /* SEL_IIC0 [1] */ + FN_SEL_IIC0_0, FN_SEL_IIC0_1, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* RESEVED [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_IEB [2] */ + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0, + /* RESEVED [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_IIC2 [3] */ + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + FN_SEL_IIC2_4, 0, 0, 0, + /* SEL_IIC1 [2] */ + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, 0, + /* SEL_I2C2 [3] */ + FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3, + FN_SEL_I2C2_4, 0, 0, 0, + /* SEL_I2C1 [2] */ + FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2, 0, } + }, + { PINMUX_CFG_REG("INOUTSEL0", 0xE6050004, 32, 1) { GP_INOUTSEL(0) } }, + { PINMUX_CFG_REG("INOUTSEL1", 0xE6051004, 32, 1) { + 0, 0, + 0, 0, + GP_1_29_IN, GP_1_29_OUT, + GP_1_28_IN, GP_1_28_OUT, + GP_1_27_IN, GP_1_27_OUT, + GP_1_26_IN, GP_1_26_OUT, + GP_1_25_IN, GP_1_25_OUT, + GP_1_24_IN, GP_1_24_OUT, + GP_1_23_IN, GP_1_23_OUT, + GP_1_22_IN, GP_1_22_OUT, + GP_1_21_IN, GP_1_21_OUT, + GP_1_20_IN, GP_1_20_OUT, + GP_1_19_IN, GP_1_19_OUT, + GP_1_18_IN, GP_1_18_OUT, + GP_1_17_IN, GP_1_17_OUT, + GP_1_16_IN, GP_1_16_OUT, + GP_1_15_IN, GP_1_15_OUT, + GP_1_14_IN, GP_1_14_OUT, + GP_1_13_IN, GP_1_13_OUT, + GP_1_12_IN, GP_1_12_OUT, + GP_1_11_IN, GP_1_11_OUT, + GP_1_10_IN, GP_1_10_OUT, + GP_1_9_IN, GP_1_9_OUT, + GP_1_8_IN, GP_1_8_OUT, + GP_1_7_IN, GP_1_7_OUT, + GP_1_6_IN, GP_1_6_OUT, + GP_1_5_IN, GP_1_5_OUT, + GP_1_4_IN, GP_1_4_OUT, + GP_1_3_IN, GP_1_3_OUT, + GP_1_2_IN, GP_1_2_OUT, + GP_1_1_IN, GP_1_1_OUT, + GP_1_0_IN, GP_1_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL2", 0xE6052004, 32, 1) { + 0, 0, + 0, 0, + GP_2_29_IN, GP_2_29_OUT, + GP_2_28_IN, GP_2_28_OUT, + GP_2_27_IN, GP_2_27_OUT, + GP_2_26_IN, GP_2_26_OUT, + GP_2_25_IN, GP_2_25_OUT, + GP_2_24_IN, GP_2_24_OUT, + GP_2_23_IN, GP_2_23_OUT, + GP_2_22_IN, GP_2_22_OUT, + GP_2_21_IN, GP_2_21_OUT, + GP_2_20_IN, GP_2_20_OUT, + GP_2_19_IN, GP_2_19_OUT, + GP_2_18_IN, GP_2_18_OUT, + GP_2_17_IN, GP_2_17_OUT, + GP_2_16_IN, GP_2_16_OUT, + GP_2_15_IN, GP_2_15_OUT, + GP_2_14_IN, GP_2_14_OUT, + GP_2_13_IN, GP_2_13_OUT, + GP_2_12_IN, GP_2_12_OUT, + GP_2_11_IN, GP_2_11_OUT, + GP_2_10_IN, GP_2_10_OUT, + GP_2_9_IN, GP_2_9_OUT, + GP_2_8_IN, GP_2_8_OUT, + GP_2_7_IN, GP_2_7_OUT, + GP_2_6_IN, GP_2_6_OUT, + GP_2_5_IN, GP_2_5_OUT, + GP_2_4_IN, GP_2_4_OUT, + GP_2_3_IN, GP_2_3_OUT, + GP_2_2_IN, GP_2_2_OUT, + GP_2_1_IN, GP_2_1_OUT, + GP_2_0_IN, GP_2_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL3", 0xE6053004, 32, 1) { GP_INOUTSEL(3) } }, + { PINMUX_CFG_REG("INOUTSEL4", 0xE6054004, 32, 1) { GP_INOUTSEL(4) } }, + { PINMUX_CFG_REG("INOUTSEL5", 0xE6055004, 32, 1) { GP_INOUTSEL(5) } }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("INDT0", 0xE6050008, 32) { GP_INDT(0) } }, + { PINMUX_DATA_REG("INDT1", 0xE6051008, 32) { + 0, 0, GP_1_29_DATA, GP_1_28_DATA, + GP_1_27_DATA, GP_1_26_DATA, GP_1_25_DATA, GP_1_24_DATA, + GP_1_23_DATA, GP_1_22_DATA, GP_1_21_DATA, GP_1_20_DATA, + GP_1_19_DATA, GP_1_18_DATA, GP_1_17_DATA, GP_1_16_DATA, + GP_1_15_DATA, GP_1_14_DATA, GP_1_13_DATA, GP_1_12_DATA, + GP_1_11_DATA, GP_1_10_DATA, GP_1_9_DATA, GP_1_8_DATA, + GP_1_7_DATA, GP_1_6_DATA, GP_1_5_DATA, GP_1_4_DATA, + GP_1_3_DATA, GP_1_2_DATA, GP_1_1_DATA, GP_1_0_DATA } + }, + { PINMUX_DATA_REG("INDT2", 0xE6052008, 32) { + 0, 0, GP_2_29_DATA, GP_2_28_DATA, + GP_2_27_DATA, GP_2_26_DATA, GP_2_25_DATA, GP_2_24_DATA, + GP_2_23_DATA, GP_2_22_DATA, GP_2_21_DATA, GP_2_20_DATA, + GP_2_19_DATA, GP_2_18_DATA, GP_2_17_DATA, GP_2_16_DATA, + GP_2_15_DATA, GP_2_14_DATA, GP_2_13_DATA, GP_2_12_DATA, + GP_2_11_DATA, GP_2_10_DATA, GP_2_9_DATA, GP_2_8_DATA, + GP_2_7_DATA, GP_2_6_DATA, GP_2_5_DATA, GP_2_4_DATA, + GP_2_3_DATA, GP_2_2_DATA, GP_2_1_DATA, GP_2_0_DATA } + }, + { PINMUX_DATA_REG("INDT3", 0xE6053008, 32) { GP_INDT(3) } }, + { PINMUX_DATA_REG("INDT4", 0xE6054008, 32) { GP_INDT(4) } }, + { PINMUX_DATA_REG("INDT5", 0xE6055008, 32) { GP_INDT(5) } }, + { }, +}; + +static struct pinmux_info r8a7790_pinmux_info = { + .name = "r8a7790_pfc", + + .unlock_reg = 0xe6060000, /* PMMR */ + + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_GP_0_0, + .last_gpio = GPIO_FN_MOUT0, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), +}; + +void r8a7790_pinmux_init(void) +{ + register_pinmux(&r8a7790_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.h b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.h new file mode 100644 index 0000000..a13317b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7790.h
@@ -0,0 +1,92 @@ +/* + * arch/arm/cpu/armv7/rmobile/pfc-r8a7790.h + * + * Copyright (C) 2013 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __PFC_R8A7790_H__ +#define __PFC_R8A7790_H__ + +#include <sh_pfc.h> +#include <asm/gpio.h> + +#define CPU_32_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_1(fn, pfx##31, sfx) + +#define CPU_32_PORT2(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx) + +#if defined(CONFIG_R8A7790) +#define CPU_32_PORT1(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx) \ +/* GP_0_0_DATA -> GP_5_31_DATA (except for GP1[30],GP1[31],GP2[30],GP2[31]) */ +#define CPU_ALL_PORT(fn, pfx, sfx) \ + CPU_32_PORT(fn, pfx##_0_, sfx), \ + CPU_32_PORT1(fn, pfx##_1_, sfx), \ + CPU_32_PORT2(fn, pfx##_2_, sfx), \ + CPU_32_PORT(fn, pfx##_3_, sfx), \ + CPU_32_PORT(fn, pfx##_4_, sfx), \ + CPU_32_PORT(fn, pfx##_5_, sfx) + +#elif defined(CONFIG_R8A7791) +#define CPU_32_PORT1(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##20, sfx), PORT_1(fn, pfx##21, sfx), \ + PORT_1(fn, pfx##22, sfx), PORT_1(fn, pfx##23, sfx), \ + PORT_1(fn, pfx##24, sfx), PORT_1(fn, pfx##25, sfx) + +/* + * GP_0_0_DATA -> GP_7_25_DATA + * (except for GP1[26],GP1[27],GP1[28],GP1[29]),GP1[30]),GP1[31] + * GP7[26],GP7[27],GP7[28],GP7[29]),GP7[30]),GP7[31]) + */ +#define CPU_ALL_PORT(fn, pfx, sfx) \ + CPU_32_PORT(fn, pfx##_0_, sfx), \ + CPU_32_PORT1(fn, pfx##_1_, sfx), \ + CPU_32_PORT(fn, pfx##_2_, sfx), \ + CPU_32_PORT(fn, pfx##_3_, sfx), \ + CPU_32_PORT(fn, pfx##_4_, sfx), \ + CPU_32_PORT(fn, pfx##_5_, sfx), \ + CPU_32_PORT(fn, pfx##_6_, sfx), \ + CPU_32_PORT1(fn, pfx##_7_, sfx) +#else +#error "NO support" +#endif + +#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA) +#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN, \ + GP##pfx##_IN, GP##pfx##_OUT) + +#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT +#define _GP_INDT(pfx, sfx) GP##pfx##_DATA + +#define GP_ALL(str) CPU_ALL_PORT(_PORT_ALL, GP, str) +#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused) +#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused) + +#define PORT_10_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ + PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ + PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ + PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ + PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) + +#define CPU_32_PORT_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ + PORT_10_REV(fn, pfx, sfx) + +#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused) +#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused) + +#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn) +#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \ + FN_##ipsr, FN_##fn) + +#endif /* __PFC_R8A7790_H__ */
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7791.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7791.c new file mode 100644 index 0000000..46d6e60 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7791.c
@@ -0,0 +1,1117 @@ +/* + * arch/arm/cpu/armv7/rmobile/pfc-r8a7791.c + * + * Copyright (C) 2013 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <sh_pfc.h> +#include <asm/gpio.h> +#include "pfc-r8a7790.h" + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + GP_ALL(IN), + PINMUX_INPUT_END, + + PINMUX_OUTPUT_BEGIN, + GP_ALL(OUT), + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + + /* GPSR0 */ + FN_IP0_0, FN_IP0_1, FN_IP0_2, FN_IP0_3, FN_IP0_4, FN_IP0_5, + FN_IP0_6, FN_IP0_7, FN_IP0_8, FN_IP0_9, FN_IP0_10, FN_IP0_11, + FN_IP0_12, FN_IP0_13, FN_IP0_14, FN_IP0_15, FN_IP0_18_16, FN_IP0_20_19, + FN_IP0_22_21, FN_IP0_24_23, FN_IP0_26_25, FN_IP0_28_27, FN_IP0_30_29, + FN_IP1_1_0, FN_IP1_3_2, FN_IP1_5_4, FN_IP1_7_6, FN_IP1_10_8, + FN_IP1_13_11, FN_IP1_16_14, FN_IP1_19_17, FN_IP1_22_20, + + /* GPSR1 */ + FN_IP1_25_23, FN_IP1_28_26, FN_IP1_31_29, FN_IP2_2_0, FN_IP2_4_3, + FN_IP2_6_5, FN_IP2_9_7, FN_IP2_12_10, FN_IP2_15_13, FN_IP2_18_16, + FN_IP2_20_19, FN_IP2_22_21, FN_EX_CS0_N, FN_IP2_24_23, FN_IP2_26_25, + FN_IP2_29_27, FN_IP3_2_0, FN_IP3_5_3, FN_IP3_8_6, FN_RD_N, + FN_IP3_11_9, FN_IP3_13_12, FN_IP3_15_14 , FN_IP3_17_16 , FN_IP3_19_18, + FN_IP3_21_20, + + /* GPSR2 */ + FN_IP3_27_25, FN_IP3_30_28, FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, + FN_IP4_9_8, FN_IP4_12_10, FN_IP4_15_13, FN_IP4_18_16, FN_IP4_19, + FN_IP4_20, FN_IP4_21, FN_IP4_23_22, FN_IP4_25_24, FN_IP4_27_26, + FN_IP4_30_28, FN_IP5_2_0, FN_IP5_5_3, FN_IP5_8_6, FN_IP5_11_9, + FN_IP5_14_12, FN_IP5_16_15, FN_IP5_19_17, FN_IP5_21_20, FN_IP5_23_22, + FN_IP5_25_24, FN_IP5_28_26, FN_IP5_31_29, FN_AUDIO_CLKA, FN_IP6_2_0, + FN_IP6_5_3, FN_IP6_7_6, + + /* GPSR3 */ + FN_IP7_5_3, FN_IP7_8_6, FN_IP7_10_9, FN_IP7_12_11, FN_IP7_14_13, + FN_IP7_16_15, FN_IP7_18_17, FN_IP7_20_19, FN_IP7_23_21, FN_IP7_26_24, + FN_IP7_29_27, FN_IP8_2_0, FN_IP8_5_3, FN_IP8_8_6, FN_IP8_11_9, + FN_IP8_14_12, FN_IP8_17_15, FN_IP8_20_18, FN_IP8_23_21, FN_IP8_25_24, + FN_IP8_27_26, FN_IP8_30_28, FN_IP9_2_0, FN_IP9_5_3, FN_IP9_6, FN_IP9_7, + FN_IP9_10_8, FN_IP9_11, FN_IP9_12, FN_IP9_15_13, FN_IP9_16, + FN_IP9_18_17, + + /* GPSR4 */ + FN_VI0_CLK, FN_IP9_20_19, FN_IP9_22_21, FN_IP9_24_23, FN_IP9_26_25, + FN_VI0_DATA0_VI0_B0, FN_VI0_DATA0_VI0_B1, FN_VI0_DATA0_VI0_B2, + FN_IP9_28_27, FN_VI0_DATA0_VI0_B4, FN_VI0_DATA0_VI0_B5, + FN_VI0_DATA0_VI0_B6, FN_VI0_DATA0_VI0_B7, FN_IP9_31_29, FN_IP10_2_0, + FN_IP10_5_3, FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_16_15, + FN_IP10_18_17, FN_IP10_21_19, FN_IP10_24_22, FN_IP10_26_25, + FN_IP10_28_27, FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6, + FN_IP15_1_0, FN_IP15_3_2, FN_IP15_5_4, + + /* GPSR5 */ + FN_IP11_11_9, FN_IP11_14_12, FN_IP11_16_15, FN_IP11_18_17, FN_IP11_19, + FN_IP11_20, FN_IP11_21, FN_IP11_22, FN_IP11_23, FN_IP11_24, + FN_IP11_25, FN_IP11_26, FN_IP11_27, FN_IP11_29_28, FN_IP11_31_30, + FN_IP12_1_0, FN_IP12_3_2, FN_IP12_6_4, FN_IP12_9_7, FN_IP12_12_10, + FN_IP12_15_13, FN_IP12_17_16, FN_IP12_19_18, FN_IP12_21_20, + FN_IP12_23_22, FN_IP12_26_24, FN_IP12_29_27, FN_IP13_2_0, FN_IP13_4_3, + FN_IP13_6_5, FN_IP13_9_7, FN_IP3_24_22, + + /* GPSR6 */ + FN_IP13_10, FN_IP13_11, FN_IP13_12, FN_IP13_13, FN_IP13_14, + FN_IP13_15, FN_IP13_18_16, FN_IP13_21_19, FN_IP13_22, FN_IP13_24_23, + FN_IP13_25, FN_IP13_26, FN_IP13_27, FN_IP13_30_28, FN_IP14_1_0, + FN_IP14_2, FN_IP14_3, FN_IP14_4, FN_IP14_5, FN_IP14_6, FN_IP14_7, + FN_IP14_10_8, FN_IP14_13_11, FN_IP14_16_14, FN_IP14_19_17, + FN_IP14_22_20, FN_IP14_25_23, FN_IP14_28_26, FN_IP14_31_29, + + /* GPSR7 */ + FN_IP15_17_15, FN_IP15_20_18, FN_IP15_23_21, FN_IP15_26_24, + FN_IP15_29_27, FN_IP16_2_0, FN_IP16_5_3, FN_IP16_7_6, FN_IP16_9_8, + FN_IP16_11_10, FN_IP6_9_8, FN_IP6_11_10, FN_IP6_13_12, FN_IP6_15_14, + FN_IP6_18_16, FN_IP6_20_19, FN_IP6_23_21, FN_IP6_26_24, FN_IP6_29_27, + FN_IP7_2_0, FN_IP15_8_6, FN_IP15_11_9, FN_IP15_14_12, + FN_USB0_PWEN, FN_USB0_OVC, FN_USB1_PWEN, + + /* IPSR0 - IPSR10 */ + + /* IPSR11 */ + FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, + FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, + FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, + FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, + FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, FN_TX4_B, FN_SCIFA4_TXD_B, + FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, FN_RX4_B, FN_SCIFA4_RXD_B, + FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, + FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, + FN_VI1_CLK, FN_AVB_RXD4, FN_VI1_DATA0, FN_AVB_RXD5, + FN_VI1_DATA1, FN_AVB_RXD6, FN_VI1_DATA2, FN_AVB_RXD7, + FN_VI1_DATA3, FN_AVB_RX_ER, FN_VI1_DATA4, FN_AVB_MDIO, + FN_VI1_DATA5, FN_AVB_RX_DV, FN_VI1_DATA6, FN_AVB_MAGIC, + FN_VI1_DATA7, FN_AVB_MDC, + FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, + FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, + + /* IPSR12 */ + FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, + FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, + FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, + FN_SCL2_D, FN_MSIOF1_RXD_E, + FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, FN_SDA2_D, FN_MSIOF1_SCK_E, + FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, + FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, + FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, + FN_CAN1_TX_C, FN_MSIOF1_TXD_E, + FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, + FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, + FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, + FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, + FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, + FN_ADIDATA_B, FN_MSIOF0_SYNC_C, + FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, + FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, + + /* IPSR13 */ + /* MOD_SEL */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, + FN_SEL_SSI9_0, FN_SEL_SSI9_1, + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + FN_SEL_QSP_0, FN_SEL_QSP_1, + FN_SEL_SSI7_0, FN_SEL_SSI7_1, + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, FN_SEL_HSCIF1_3, + FN_SEL_HSCIF1_4, + FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, + + /* MOD_SEL2 */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3, + FN_SEL_SCIF0_4, + FN_SEL_SCIF_0, FN_SEL_SCIF_1, + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + FN_SEL_CAN0_4, FN_SEL_CAN0_5, + FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, + FN_SEL_ADG_0, FN_SEL_ADG_1, + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3, FN_SEL_FM_4, + FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, + FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, + FN_SEL_SIM_0, FN_SEL_SIM_1, + FN_SEL_SSI8_0, FN_SEL_SSI8_1, + + /* MOD_SEL3 */ + FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, + FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, + FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, + FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, + FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, + FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, + FN_SEL_MMC_0, FN_SEL_MMC_1, + FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, + FN_SEL_IIC1_4, + FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, + + /* MOD_SEL4 */ + FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, + FN_SEL_SOF1_4, + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, + FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, + FN_SEL_RAD_0, FN_SEL_RAD_1, + FN_SEL_RCN_0, FN_SEL_RCN_1, + FN_SEL_RSP_0, FN_SEL_RSP_1, + FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, FN_SEL_SCIF2_3, + FN_SEL_SCIF2_4, + FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, FN_SEL_SOF2_3, + FN_SEL_SOF2_4, + FN_SEL_SSI1_0, FN_SEL_SSI1_1, + FN_SEL_SSI0_0, FN_SEL_SSI0_1, + FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + + EX_CS0_N_MARK, RD_N_MARK, + + AUDIO_CLKA_MARK, + + VI0_CLK_MARK, VI0_DATA0_VI0_B0_MARK, VI0_DATA0_VI0_B1_MARK, + VI0_DATA0_VI0_B2_MARK, VI0_DATA0_VI0_B4_MARK, VI0_DATA0_VI0_B5_MARK, + VI0_DATA0_VI0_B6_MARK, VI0_DATA0_VI0_B7_MARK, + + USB0_PWEN_MARK, USB0_OVC_MARK, USB1_PWEN_MARK, + + /* IPSR0 IPSR10 */ + /* IPSR11 */ + VI0_R5_MARK, VI2_DATA6_MARK, GLO_SDATA_B_MARK, RX0_C_MARK, SDA1_D_MARK, + VI0_R6_MARK, VI2_DATA7_MARK, GLO_SS_B_MARK, TX1_C_MARK, SCL4_B_MARK, + VI0_R7_MARK, GLO_RFON_B_MARK, RX1_C_MARK, CAN0_RX_E_MARK, + SDA4_B_MARK, _MARK, HRX1_D_MARK, SCIFB0_RXD_D_MARK, + VI1_HSYNC_N_MARK, AVB_RXD0_MARK, TS_SDATA0_B_MARK, + TX4_B_MARK, SCIFA4_TXD_B_MARK, + VI1_VSYNC_N_MARK, AVB_RXD1_MARK, TS_SCK0_B_MARK, + RX4_B_MARK, SCIFA4_RXD_B_MARK, + VI1_CLKENB_MARK, AVB_RXD2_MARK, TS_SDEN0_B_MARK, + VI1_FIELD_MARK, AVB_RXD3_MARK, TS_SPSYNC0_B_MARK, + VI1_CLK_MARK, AVB_RXD4_MARK, VI1_DATA0_MARK, AVB_RXD5_MARK, + VI1_DATA1_MARK, AVB_RXD6_MARK, VI1_DATA2_MARK, AVB_RXD7_MARK, + VI1_DATA3_MARK, AVB_RX_ER_MARK, VI1_DATA4_MARK, AVB_MDIO_MARK, + VI1_DATA5_MARK, AVB_RX_DV_MARK, VI1_DATA6_MARK, AVB_MAGIC_MARK, + VI1_DATA7_MARK, AVB_MDC_MARK, + ETH_MDIO_MARK, AVB_RX_CLK_MARK, SCL2_C_MARK, + ETH_CRS_DV_MARK, AVB_LINK_MARK, SDA2_C_MARK, + + /* IPSR12 */ + ETH_RX_ER_MARK, AVB_CRS_MARK, SCL3_MARK, SCL7_MARK, + ETH_RXD0_MARK, AVB_PHY_INT_MARK, SDA3_MARK, SDA7_MARK, + ETH_RXD1_MARK, AVB_GTXREFCLK_MARK, CAN0_TX_C_MARK, + SCL2_D_MARK, MSIOF1_RXD_E_MARK, + ETH_LINK_MARK, AVB_TXD0_MARK, CAN0_RX_C_MARK, + SDA2_D_MARK, MSIOF1_SCK_E_MARK, + ETH_REFCLK_MARK, AVB_TXD1_MARK, SCIFA3_RXD_B_MARK, + CAN1_RX_C_MARK, MSIOF1_SYNC_E_MARK, + ETH_TXD1_MARK, AVB_TXD2_MARK, SCIFA3_TXD_B_MARK, + CAN1_TX_C_MARK, MSIOF1_TXD_E_MARK, + ETH_TX_EN_MARK, AVB_TXD3_MARK, TCLK1_B_MARK, CAN_CLK_B_MARK, + ETH_MAGIC_MARK, AVB_TXD4_MARK, IETX_C_MARK, + ETH_TXD0_MARK, AVB_TXD5_MARK, IECLK_C_MARK, + ETH_MDC_MARK, AVB_TXD6_MARK, IERX_C_MARK, + STP_IVCXO27_0_MARK, AVB_TXD7_MARK, SCIFB2_TXD_D_MARK, + ADIDATA_B_MARK, MSIOF0_SYNC_C_MARK, + STP_ISCLK_0_MARK, AVB_TX_EN_MARK, SCIFB2_RXD_D_MARK, + ADICS_SAMP_B_MARK, MSIOF0_SCK_C_MARK, + + /* IPSR13 */ + PINMUX_MARK_END, +}; + +static pinmux_enum_t pinmux_data[] = { + PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ + + /* OTHER IPSR0 - IPSR10 */ + /* IPSR11 */ + PINMUX_IPSR_DATA(IP11_2_0, VI0_R5), + PINMUX_IPSR_DATA(IP11_2_0, VI2_DATA6), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, GLO_SDATA_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, RX0_C, SEL_SCIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SDA1_D, SEL_IIC1_3), + PINMUX_IPSR_DATA(IP11_5_3, VI0_R6), + PINMUX_IPSR_DATA(IP11_5_3, VI2_DATA7), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, GLO_SS_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, TX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SCL4_B, SEL_IIC4_1), + PINMUX_IPSR_DATA(IP11_8_6, VI0_R7), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, GLO_RFON_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, RX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, CAN0_RX_E, SEL_CAN0_4), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SDA4_B, SEL_IIC4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, HRX1_D, SEL_HSCIF1_3), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SCIFB0_RXD_D, SEL_SCIFB_3), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, VI1_HSYNC_N, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_11_9, AVB_RXD0), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TS_SDATA0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TX4_B, SEL_SCIF4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, SCIFA4_TXD_B, SEL_SCIFA4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, VI1_VSYNC_N, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_14_12, AVB_RXD1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, TS_SCK0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, RX4_B, SEL_SCIF4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, SCIFA4_RXD_B, SEL_SCIFA4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_16_15, VI1_CLKENB, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_16_15, AVB_RXD2), + PINMUX_IPSR_MODSEL_DATA(IP11_16_15, TS_SDEN0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_18_17, VI1_FIELD, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_18_17, AVB_RXD3), + PINMUX_IPSR_MODSEL_DATA(IP11_18_17, TS_SPSYNC0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_19, VI1_CLK, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_19, AVB_RXD4), + PINMUX_IPSR_MODSEL_DATA(IP11_20, VI1_DATA0, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_20, AVB_RXD5), + PINMUX_IPSR_MODSEL_DATA(IP11_21, VI1_DATA1, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_21, AVB_RXD6), + PINMUX_IPSR_MODSEL_DATA(IP11_22, VI1_DATA2, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_22, AVB_RXD7), + PINMUX_IPSR_MODSEL_DATA(IP11_23, VI1_DATA3, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_23, AVB_RX_ER), + PINMUX_IPSR_MODSEL_DATA(IP11_24, VI1_DATA4, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_24, AVB_MDIO), + PINMUX_IPSR_MODSEL_DATA(IP11_25, VI1_DATA5, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_25, AVB_RX_DV), + PINMUX_IPSR_MODSEL_DATA(IP11_26, VI1_DATA6, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_26, AVB_MAGIC), + PINMUX_IPSR_MODSEL_DATA(IP11_27, VI1_DATA7, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_27, AVB_MDC), + PINMUX_IPSR_DATA(IP11_29_28, ETH_MDIO), + PINMUX_IPSR_DATA(IP11_29_28, AVB_RX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP11_29_28, SCL2_C, SEL_IIC2_2), + PINMUX_IPSR_DATA(IP11_31_30, ETH_CRS_DV), + PINMUX_IPSR_DATA(IP11_31_30, AVB_LINK), + PINMUX_IPSR_MODSEL_DATA(IP11_31_30, SDA2_C, SEL_IIC2_2), + + /* IPSR12 */ + PINMUX_IPSR_DATA(IP12_1_0, ETH_RX_ER), + PINMUX_IPSR_DATA(IP12_1_0, AVB_CRS), + PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL3, SEL_IIC3_0), + PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL7, SEL_IIC7_0), + PINMUX_IPSR_DATA(IP12_3_2, ETH_RXD0), + PINMUX_IPSR_DATA(IP12_3_2, AVB_PHY_INT), + PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA3, SEL_IIC3_0), + PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA7, SEL_IIC7_0), + PINMUX_IPSR_DATA(IP12_6_4, ETH_RXD1), + PINMUX_IPSR_DATA(IP12_6_4, AVB_GTXREFCLK), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, CAN0_TX_C, SEL_CAN0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, SCL2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, MSIOF1_RXD_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_9_7, ETH_LINK), + PINMUX_IPSR_DATA(IP12_9_7, AVB_TXD0), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, CAN0_RX_C, SEL_CAN0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, SDA2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, MSIOF1_SCK_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_12_10, ETH_REFCLK), + PINMUX_IPSR_DATA(IP12_12_10, AVB_TXD1), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, SCIFA3_RXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, CAN1_RX_C, SEL_CAN1_2), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, MSIOF1_SYNC_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_15_13, ETH_TXD1), + PINMUX_IPSR_DATA(IP12_15_13, AVB_TXD2), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, SCIFA3_TXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, CAN1_TX_C, SEL_CAN1_2), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, MSIOF1_TXD_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_17_16, ETH_TX_EN), + PINMUX_IPSR_DATA(IP12_17_16, AVB_TXD3), + PINMUX_IPSR_MODSEL_DATA(IP12_17_16, TCLK1_B, SEL_TMU1_0), + PINMUX_IPSR_MODSEL_DATA(IP12_17_16, CAN_CLK_B, SEL_CANCLK_1), + PINMUX_IPSR_DATA(IP12_19_18, ETH_MAGIC), + PINMUX_IPSR_DATA(IP12_19_18, AVB_TXD4), + PINMUX_IPSR_MODSEL_DATA(IP12_19_18, IETX_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP12_21_20, ETH_TXD0), + PINMUX_IPSR_DATA(IP12_21_20, AVB_TXD5), + PINMUX_IPSR_MODSEL_DATA(IP12_21_20, IECLK_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP12_23_22, ETH_MDC), + PINMUX_IPSR_DATA(IP12_23_22, AVB_TXD6), + PINMUX_IPSR_MODSEL_DATA(IP12_23_22, IERX_C, SEL_IEB_2), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, STP_IVCXO27_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP12_26_24, AVB_TXD7), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, SCIFB2_TXD_D, SEL_SCIFB2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, ADIDATA_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, MSIOF0_SYNC_C, SEL_SOF0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, STP_ISCLK_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP12_29_27, AVB_TX_EN), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, SCIFB2_RXD_D, SEL_SCIFB2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, ADICS_SAMP_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, MSIOF0_SCK_C, SEL_SOF0_2), + + /* IPSR13 - IPSR16 */ +}; + +static struct pinmux_gpio pinmux_gpios[] = { + PINMUX_GPIO_GP_ALL(), + + /* OTHER, IPSR0 - IPSR10 */ + /* IPSR11 */ + GPIO_FN(VI0_R5), GPIO_FN(VI2_DATA6), GPIO_FN(GLO_SDATA_B), + GPIO_FN(RX0_C), GPIO_FN(SDA1_D), + GPIO_FN(VI0_R6), GPIO_FN(VI2_DATA7), + GPIO_FN(GLO_SS_B), GPIO_FN(TX1_C), GPIO_FN(SCL4_B), + GPIO_FN(VI0_R7), GPIO_FN(GLO_RFON_B), + GPIO_FN(RX1_C), GPIO_FN(CAN0_RX_E), + GPIO_FN(SDA4_B), GPIO_FN(HRX1_D), GPIO_FN(SCIFB0_RXD_D), + GPIO_FN(VI1_HSYNC_N), GPIO_FN(AVB_RXD0), GPIO_FN(TS_SDATA0_B), + GPIO_FN(TX4_B), GPIO_FN(SCIFA4_TXD_B), + GPIO_FN(VI1_VSYNC_N), GPIO_FN(AVB_RXD1), GPIO_FN(TS_SCK0_B), + GPIO_FN(RX4_B), GPIO_FN(SCIFA4_RXD_B), + GPIO_FN(VI1_CLKENB), GPIO_FN(AVB_RXD2), GPIO_FN(TS_SDEN0_B), + GPIO_FN(VI1_FIELD), GPIO_FN(AVB_RXD3), GPIO_FN(TS_SPSYNC0_B), + GPIO_FN(VI1_CLK), GPIO_FN(AVB_RXD4), + GPIO_FN(VI1_DATA0), GPIO_FN(AVB_RXD5), + GPIO_FN(VI1_DATA1), GPIO_FN(AVB_RXD6), + GPIO_FN(VI1_DATA2), GPIO_FN(AVB_RXD7), + GPIO_FN(VI1_DATA3), GPIO_FN(AVB_RX_ER), + GPIO_FN(VI1_DATA4), GPIO_FN(AVB_MDIO), + GPIO_FN(VI1_DATA5), GPIO_FN(AVB_RX_DV), + GPIO_FN(VI1_DATA6), GPIO_FN(AVB_MAGIC), + GPIO_FN(VI1_DATA7), GPIO_FN(AVB_MDC), + GPIO_FN(ETH_MDIO), GPIO_FN(AVB_RX_CLK), GPIO_FN(SCL2_C), + GPIO_FN(ETH_CRS_DV), GPIO_FN(AVB_LINK), GPIO_FN(SDA2_C), + + /* IPSR12 */ + GPIO_FN(ETH_RX_ER), GPIO_FN(AVB_CRS), GPIO_FN(SCL3), GPIO_FN(SCL7), + GPIO_FN(ETH_RXD0), GPIO_FN(AVB_PHY_INT), GPIO_FN(SDA3), GPIO_FN(SDA7), + GPIO_FN(ETH_RXD1), GPIO_FN(AVB_GTXREFCLK), GPIO_FN(CAN0_TX_C), + GPIO_FN(SCL2_D), GPIO_FN(MSIOF1_RXD_E), + GPIO_FN(ETH_LINK), GPIO_FN(AVB_TXD0), GPIO_FN(CAN0_RX_C), + GPIO_FN(SDA2_D), GPIO_FN(MSIOF1_SCK_E), + GPIO_FN(ETH_REFCLK), GPIO_FN(AVB_TXD1), GPIO_FN(SCIFA3_RXD_B), + GPIO_FN(CAN1_RX_C), GPIO_FN(MSIOF1_SYNC_E), + GPIO_FN(ETH_TXD1), GPIO_FN(AVB_TXD2), GPIO_FN(SCIFA3_TXD_B), + GPIO_FN(CAN1_TX_C), GPIO_FN(MSIOF1_TXD_E), + GPIO_FN(ETH_TX_EN), GPIO_FN(AVB_TXD3), + GPIO_FN(TCLK1_B), GPIO_FN(CAN_CLK_B), + GPIO_FN(ETH_MAGIC), GPIO_FN(AVB_TXD4), GPIO_FN(IETX_C), + GPIO_FN(ETH_TXD0), GPIO_FN(AVB_TXD5), GPIO_FN(IECLK_C), + GPIO_FN(ETH_MDC), GPIO_FN(AVB_TXD6), GPIO_FN(IERX_C), + GPIO_FN(STP_IVCXO27_0), GPIO_FN(AVB_TXD7), GPIO_FN(SCIFB2_TXD_D), + GPIO_FN(ADIDATA_B), GPIO_FN(MSIOF0_SYNC_C), + GPIO_FN(STP_ISCLK_0), GPIO_FN(AVB_TX_EN), GPIO_FN(SCIFB2_RXD_D), + GPIO_FN(ADICS_SAMP_B), GPIO_FN(MSIOF0_SCK_C), + + /* IPSR13 - IPSR16 */ +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + { PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) { + GP_0_31_FN, FN_IP1_22_20, + GP_0_30_FN, FN_IP1_19_17, + GP_0_29_FN, FN_IP1_16_14, + GP_0_28_FN, FN_IP1_13_11, + GP_0_27_FN, FN_IP1_10_8, + GP_0_26_FN, FN_IP1_7_6, + GP_0_25_FN, FN_IP1_5_4, + GP_0_24_FN, FN_IP1_3_2, + GP_0_23_FN, FN_IP1_1_0, + GP_0_22_FN, FN_IP0_30_29, + GP_0_21_FN, FN_IP0_28_27, + GP_0_20_FN, FN_IP0_26_25, + GP_0_19_FN, FN_IP0_24_23, + GP_0_18_FN, FN_IP0_22_21, + GP_0_17_FN, FN_IP0_20_19, + GP_0_16_FN, FN_IP0_18_16, + GP_0_15_FN, FN_IP0_15, + GP_0_14_FN, FN_IP0_14, + GP_0_13_FN, FN_IP0_13, + GP_0_12_FN, FN_IP0_12, + GP_0_11_FN, FN_IP0_11, + GP_0_10_FN, FN_IP0_10, + GP_0_9_FN, FN_IP0_9, + GP_0_8_FN, FN_IP0_8, + GP_0_7_FN, FN_IP0_7, + GP_0_6_FN, FN_IP0_6, + GP_0_5_FN, FN_IP0_5, + GP_0_4_FN, FN_IP0_4, + GP_0_3_FN, FN_IP0_3, + GP_0_2_FN, FN_IP0_2, + GP_0_1_FN, FN_IP0_1, + GP_0_0_FN, FN_IP0_0, } + }, + { PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_FN, FN_IP3_21_20, + GP_1_24_FN, FN_IP3_19_18, + GP_1_23_FN, FN_IP3_17_16, + GP_1_22_FN, FN_IP3_15_14, + GP_1_21_FN, FN_IP3_13_12, + GP_1_20_FN, FN_IP3_11_9, + GP_1_19_FN, FN_RD_N, + GP_1_18_FN, FN_IP3_8_6, + GP_1_17_FN, FN_IP3_5_3, + GP_1_16_FN, FN_IP3_2_0, + GP_1_15_FN, FN_IP2_29_27, + GP_1_14_FN, FN_IP2_26_25, + GP_1_13_FN, FN_IP2_24_23, + GP_1_12_FN, FN_EX_CS0_N, + GP_1_11_FN, FN_IP2_22_21, + GP_1_10_FN, FN_IP2_20_19, + GP_1_9_FN, FN_IP2_18_16, + GP_1_8_FN, FN_IP2_15_13, + GP_1_7_FN, FN_IP2_12_10, + GP_1_6_FN, FN_IP2_9_7, + GP_1_5_FN, FN_IP2_6_5, + GP_1_4_FN, FN_IP2_4_3, + GP_1_3_FN, FN_IP2_2_0, + GP_1_2_FN, FN_IP1_31_29, + GP_1_1_FN, FN_IP1_28_26, + GP_1_0_FN, FN_IP1_25_23, } + }, + { PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) { + GP_2_31_FN, FN_IP6_7_6, + GP_2_30_FN, FN_IP6_5_3, + GP_2_29_FN, FN_IP6_2_0, + GP_2_28_FN, FN_AUDIO_CLKA, + GP_2_27_FN, FN_IP5_31_29, + GP_2_26_FN, FN_IP5_28_26, + GP_2_25_FN, FN_IP5_25_24, + GP_2_24_FN, FN_IP5_23_22, + GP_2_23_FN, FN_IP5_21_20, + GP_2_22_FN, FN_IP5_19_17, + GP_2_21_FN, FN_IP5_16_15, + GP_2_20_FN, FN_IP5_14_12, + GP_2_19_FN, FN_IP5_11_9, + GP_2_18_FN, FN_IP5_8_6, + GP_2_17_FN, FN_IP5_5_3, + GP_2_16_FN, FN_IP5_2_0, + GP_2_15_FN, FN_IP4_30_28, + GP_2_14_FN, FN_IP4_27_26, + GP_2_13_FN, FN_IP4_25_24, + GP_2_12_FN, FN_IP4_23_22, + GP_2_11_FN, FN_IP4_21, + GP_2_10_FN, FN_IP4_20, + GP_2_9_FN, FN_IP4_19, + GP_2_8_FN, FN_IP4_18_16, + GP_2_7_FN, FN_IP4_15_13, + GP_2_6_FN, FN_IP4_12_10, + GP_2_5_FN, FN_IP4_9_8, + GP_2_4_FN, FN_IP4_7_5, + GP_2_3_FN, FN_IP4_4_2, + GP_2_2_FN, FN_IP4_1_0, + GP_2_1_FN, FN_IP3_30_28, + GP_2_0_FN, FN_IP3_27_25 } + }, + { PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) { + GP_3_31_FN, FN_IP9_18_17, + GP_3_30_FN, FN_IP9_16, + GP_3_29_FN, FN_IP9_15_13, + GP_3_28_FN, FN_IP9_12, + GP_3_27_FN, FN_IP9_11, + GP_3_26_FN, FN_IP9_10_8, + GP_3_25_FN, FN_IP9_7, + GP_3_24_FN, FN_IP9_6, + GP_3_23_FN, FN_IP9_5_3, + GP_3_22_FN, FN_IP9_2_0, + GP_3_21_FN, FN_IP8_30_28, + GP_3_20_FN, FN_IP8_27_26, + GP_3_19_FN, FN_IP8_25_24, + GP_3_18_FN, FN_IP8_23_21, + GP_3_17_FN, FN_IP8_20_18, + GP_3_16_FN, FN_IP8_17_15, + GP_3_15_FN, FN_IP8_14_12, + GP_3_14_FN, FN_IP8_11_9, + GP_3_13_FN, FN_IP8_8_6, + GP_3_12_FN, FN_IP8_5_3, + GP_3_11_FN, FN_IP8_2_0, + GP_3_10_FN, FN_IP7_29_27, + GP_3_9_FN, FN_IP7_26_24, + GP_3_8_FN, FN_IP7_23_21, + GP_3_7_FN, FN_IP7_20_19, + GP_3_6_FN, FN_IP7_18_17, + GP_3_5_FN, FN_IP7_16_15, + GP_3_4_FN, FN_IP7_14_13, + GP_3_3_FN, FN_IP7_12_11, + GP_3_2_FN, FN_IP7_10_9, + GP_3_1_FN, FN_IP7_8_6, + GP_3_0_FN, FN_IP7_5_3 } + }, + { PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) { + GP_4_31_FN, FN_IP15_5_4, + GP_4_30_FN, FN_IP15_3_2, + GP_4_29_FN, FN_IP15_1_0, + GP_4_28_FN, FN_IP11_8_6, + GP_4_27_FN, FN_IP11_5_3, + GP_4_26_FN, FN_IP11_2_0, + GP_4_25_FN, FN_IP10_31_29, + GP_4_24_FN, FN_IP10_28_27, + GP_4_23_FN, FN_IP10_26_25, + GP_4_22_FN, FN_IP10_24_22, + GP_4_21_FN, FN_IP10_21_19, + GP_4_20_FN, FN_IP10_18_17, + GP_4_19_FN, FN_IP10_16_15, + GP_4_18_FN, FN_IP10_14_12, + GP_4_17_FN, FN_IP10_11_9, + GP_4_16_FN, FN_IP10_8_6, + GP_4_15_FN, FN_IP10_5_3, + GP_4_14_FN, FN_IP10_2_0, + GP_4_13_FN, FN_IP9_31_29, + GP_4_12_FN, FN_VI0_DATA0_VI0_B7, + GP_4_11_FN, FN_VI0_DATA0_VI0_B6, + GP_4_10_FN, FN_VI0_DATA0_VI0_B5, + GP_4_9_FN, FN_VI0_DATA0_VI0_B4, + GP_4_8_FN, FN_IP9_28_27, + GP_4_7_FN, FN_VI0_DATA0_VI0_B2, + GP_4_6_FN, FN_VI0_DATA0_VI0_B1, + GP_4_5_FN, FN_VI0_DATA0_VI0_B0, + GP_4_4_FN, FN_IP9_26_25, + GP_4_3_FN, FN_IP9_24_23, + GP_4_2_FN, FN_IP9_22_21, + GP_4_1_FN, FN_IP9_20_19, + GP_4_0_FN, FN_VI0_CLK } + }, + { PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) { + GP_5_31_FN, FN_IP3_24_22, + GP_5_30_FN, FN_IP13_9_7, + GP_5_29_FN, FN_IP13_6_5, + GP_5_28_FN, FN_IP13_4_3, + GP_5_27_FN, FN_IP13_2_0, + GP_5_26_FN, FN_IP12_29_27, + GP_5_25_FN, FN_IP12_26_24, + GP_5_24_FN, FN_IP12_23_22, + GP_5_23_FN, FN_IP12_21_20, + GP_5_22_FN, FN_IP12_19_18, + GP_5_21_FN, FN_IP12_17_16, + GP_5_20_FN, FN_IP12_15_13, + GP_5_19_FN, FN_IP12_12_10, + GP_5_18_FN, FN_IP12_9_7, + GP_5_17_FN, FN_IP12_6_4, + GP_5_16_FN, FN_IP12_3_2, + GP_5_15_FN, FN_IP12_1_0, + GP_5_14_FN, FN_IP11_31_30, + GP_5_13_FN, FN_IP11_29_28, + GP_5_12_FN, FN_IP11_27, + GP_5_11_FN, FN_IP11_26, + GP_5_10_FN, FN_IP11_25, + GP_5_9_FN, FN_IP11_24, + GP_5_8_FN, FN_IP11_23, + GP_5_7_FN, FN_IP11_22, + GP_5_6_FN, FN_IP11_21, + GP_5_5_FN, FN_IP11_20, + GP_5_4_FN, FN_IP11_19, + GP_5_3_FN, FN_IP11_18_17, + GP_5_2_FN, FN_IP11_16_15, + GP_5_1_FN, FN_IP11_14_12, + GP_5_0_FN, FN_IP11_11_9 } + }, + { PINMUX_CFG_REG("GPSR6", 0xE606001C, 32, 1) { + 0, 0, + 0, 0, + GP_6_29_FN, FN_IP14_31_29, + GP_6_28_FN, FN_IP14_28_26, + GP_6_27_FN, FN_IP14_25_23, + GP_6_26_FN, FN_IP14_22_20, + GP_6_25_FN, FN_IP14_19_17, + GP_6_24_FN, FN_IP14_16_14, + GP_6_23_FN, FN_IP14_13_11, + GP_6_22_FN, FN_IP14_10_8, + GP_6_21_FN, FN_IP14_7, + GP_6_20_FN, FN_IP14_6, + GP_6_19_FN, FN_IP14_5, + GP_6_18_FN, FN_IP14_4, + GP_6_17_FN, FN_IP14_3, + GP_6_16_FN, FN_IP14_2, + GP_6_15_FN, FN_IP14_1_0, + GP_6_14_FN, FN_IP13_30_28, + GP_6_13_FN, FN_IP13_27, + GP_6_12_FN, FN_IP13_26, + GP_6_11_FN, FN_IP13_25, + GP_6_10_FN, FN_IP13_24_23, + GP_6_9_FN, FN_IP13_22, + 0, 0, + GP_6_7_FN, FN_IP13_21_19, + GP_6_6_FN, FN_IP13_18_16, + GP_6_5_FN, FN_IP13_15, + GP_6_4_FN, FN_IP13_14, + GP_6_3_FN, FN_IP13_13, + GP_6_2_FN, FN_IP13_12, + GP_6_1_FN, FN_IP13_11, + GP_6_0_FN, FN_IP13_10 } + }, + { PINMUX_CFG_REG("GPSR7", 0xE6060074, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_7_25_FN, FN_USB1_PWEN, + GP_7_24_FN, FN_USB0_OVC, + GP_7_23_FN, FN_USB0_PWEN, + GP_7_22_FN, FN_IP15_14_12, + GP_7_21_FN, FN_IP15_11_9, + GP_7_20_FN, FN_IP15_8_6, + GP_7_19_FN, FN_IP7_2_0, + GP_7_18_FN, FN_IP6_29_27, + GP_7_17_FN, FN_IP6_26_24, + GP_7_16_FN, FN_IP6_23_21, + GP_7_15_FN, FN_IP6_20_19, + GP_7_14_FN, FN_IP6_18_16, + GP_7_13_FN, FN_IP6_15_14, + GP_7_12_FN, FN_IP6_13_12, + GP_7_11_FN, FN_IP6_11_10, + GP_7_10_FN, FN_IP6_9_8, + GP_7_9_FN, FN_IP16_11_10, + GP_7_8_FN, FN_IP16_9_8, + GP_7_7_FN, FN_IP16_7_6, + GP_7_6_FN, FN_IP16_5_3, + GP_7_5_FN, FN_IP16_2_0, + GP_7_4_FN, FN_IP15_29_27, + GP_7_3_FN, FN_IP15_26_24, + GP_7_2_FN, FN_IP15_23_21, + GP_7_1_FN, FN_IP15_20_18, + GP_7_0_FN, FN_IP15_17_15 } + }, + /* IPSR0 - IPSR10 */ + { PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 3, 3, 3, 3, 3) { + /* IP11_31_30 [2] */ + FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, 0, + /* IP11_29_28 [2] */ + FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, 0, + /* IP11_27 [1] */ + FN_VI1_DATA7, FN_AVB_MDC, + /* IP11_26 [1] */ + FN_VI1_DATA6, FN_AVB_MAGIC, + /* IP11_25 [1] */ + FN_VI1_DATA5, FN_AVB_RX_DV, + /* IP11_24 [1] */ + FN_VI1_DATA4, FN_AVB_MDIO, + /* IP11_23 [1] */ + FN_VI1_DATA3, FN_AVB_RX_ER, + /* IP11_22 [1] */ + FN_VI1_DATA2, FN_AVB_RXD7, + /* IP11_21 [1] */ + FN_VI1_DATA1, FN_AVB_RXD6, + /* IP11_20 [1] */ + FN_VI1_DATA0, FN_AVB_RXD5, + /* IP11_19 [1] */ + FN_VI1_CLK, FN_AVB_RXD4, + /* IP11_18_17 [2] */ + FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, 0, + /* IP11_16_15 [2] */ + FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, 0, + /* IP11_14_12 [3] */ + FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, + FN_RX4_B, FN_SCIFA4_RXD_B, + 0, 0, 0, + /* IP11_11_9 [3] */ + FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, + FN_TX4_B, FN_SCIFA4_TXD_B, + 0, 0, 0, + /* IP11_8_6 [3] */ + FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, + FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, 0, + /* IP11_5_3 [3] */ + FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, + 0, 0, 0, + /* IP11_2_0 [3] */ + FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, + 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR12", 0xE6060050, 32, + 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2) { + /* IP12_31_30 [2] */ + 0, 0, 0, 0, + /* IP12_29_27 [3] */ + FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, + FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, + 0, 0, 0, + /* IP12_26_24 [3] */ + FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, + FN_ADIDATA_B, FN_MSIOF0_SYNC_C, + 0, 0, 0, + /* IP12_23_22 [2] */ + FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, 0, + /* IP12_21_20 [2] */ + FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, 0, + /* IP12_19_18 [2] */ + FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, 0, + /* IP12_17_16 [2] */ + FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, + /* IP12_15_13 [3] */ + FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, + FN_CAN1_TX_C, FN_MSIOF1_TXD_E, + 0, 0, 0, + /* IP12_12_10 [3] */ + FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, + FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, + 0, 0, 0, + /* IP12_9_7 [3] */ + FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, + FN_SDA2_D, FN_MSIOF1_SCK_E, + 0, 0, 0, + /* IP12_6_4 [3] */ + FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, + FN_SCL2_D, FN_MSIOF1_RXD_E, + 0, 0, 0, + /* IP12_3_2 [2] */ + FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, + /* IP12_1_0 [2] */ + FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, } + }, + + /* IPSR13 - IPSR16 */ + + { PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32, + 1, 2, 2, 2, 3, 2, 1, 1, 1, 1, + 3, 2, 2, 2, 1, 2, 2, 2) { + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIF1 [2] */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + /* SEL_SCIFB [2] */ + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, + /* SEL_SCIFB2 [2] */ + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, + FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, + /* SEL_SCIFB1 [3] */ + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, + FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, + 0, 0, 0, 0, + /* SEL_SCIFA1 [2] */ + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, 0, + /* SEL_SSI9 [1] */ + FN_SEL_SSI9_0, FN_SEL_SSI9_1, + /* SEL_SCFA [1] */ + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + /* SEL_QSP [1] */ + FN_SEL_QSP_0, FN_SEL_QSP_1, + /* SEL_SSI7 [1] */ + FN_SEL_SSI7_0, FN_SEL_SSI7_1, + /* SEL_HSCIF1 [3] */ + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, + FN_SEL_HSCIF1_3, FN_SEL_HSCIF1_4, + 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_VI1 [2] */ + FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_TMU [1] */ + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + /* SEL_LBS [2] */ + FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, + /* SEL_TSIF0 [2] */ + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + /* SEL_SOF0 [2] */ + FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32, + 3, 1, 1, 3, 2, 1, 1, 2, 2, + 1, 3, 2, 1, 2, 2, 2, 1, 1, 1) { + /* SEL_SCIF0 [3] */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, + FN_SEL_SCIF0_3, FN_SEL_SCIF0_4, + 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIF [1] */ + FN_SEL_SCIF_0, FN_SEL_SCIF_1, + /* SEL_CAN0 [3] */ + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + FN_SEL_CAN0_4, FN_SEL_CAN0_5, + 0, 0, + /* SEL_CAN1 [2] */ + FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIFA2 [1] */ + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + /* SEL_SCIF4 [2] */ + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_ADG [1] */ + FN_SEL_ADG_0, FN_SEL_ADG_1, + /* SEL_FM [3] */ + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, + FN_SEL_FM_3, FN_SEL_FM_4, + 0, 0, 0, + /* SEL_SCIFA5 [2] */ + FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_GPS [2] */ + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, + /* SEL_SCIFA4 [2] */ + FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, 0, + /* SEL_SCIFA3 [2] */ + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, 0, + /* SEL_SIM [1] */ + FN_SEL_SIM_0, FN_SEL_SIM_1, + /* RESEVED [1] */ + 0, 0, + /* SEL_SSI8 [1] */ + FN_SEL_SSI8_0, FN_SEL_SSI8_1, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 2, 2, 3, 2, 2, 2, 1) { + /* SEL_HSCIF2 [2] */ + FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, + FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, + /* SEL_CANCLK [2] */ + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, + FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, + /* SEL_IIC8 [2] */ + FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, 0, + /* SEL_IIC7 [2] */ + FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, 0, + /* SEL_IIC4 [2] */ + FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, 0, + /* SEL_IIC3 [2] */ + FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, + /* SEL_SCIF3 [2] */ + FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, + /* SEL_IEB [2] */ + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0, + /* SEL_MMC [1] */ + FN_SEL_MMC_0, FN_SEL_MMC_1, + /* SEL_SCIF5 [1] */ + FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_IIC2 [2] */ + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + /* SEL_IIC1 [3] */ + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, + FN_SEL_IIC1_4, + 0, 0, 0, + /* SEL_IIC0 [2] */ + FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [1] */ + 0, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL4", 0xE606009C, 32, + 3, 2, 2, 1, 1, 1, 1, 3, 2, + 2, 3, 1, 1, 1, 2, 2, 2, 2) { + /* SEL_SOF1 [3] */ + FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, + FN_SEL_SOF1_4, + 0, 0, 0, + /* SEL_HSCIF0 [2] */ + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, 0, + /* SEL_DIS [2] */ + FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_RAD [1] */ + FN_SEL_RAD_0, FN_SEL_RAD_1, + /* SEL_RCN [1] */ + FN_SEL_RCN_0, FN_SEL_RCN_1, + /* SEL_RSP [1] */ + FN_SEL_RSP_0, FN_SEL_RSP_1, + /* SEL_SCIF2 [3] */ + FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, + FN_SEL_SCIF2_3, FN_SEL_SCIF2_4, + 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_SOF2 [3] */ + FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, + FN_SEL_SOF2_3, FN_SEL_SOF2_4, + 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_SSI1 [1] */ + FN_SEL_SSI1_0, FN_SEL_SSI1_1, + /* SEL_SSI0 [1] */ + FN_SEL_SSI0_0, FN_SEL_SSI0_1, + /* SEL_SSP [2] */ + FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, } + }, + { PINMUX_CFG_REG("INOUTSEL0", 0xE6050004, 32, 1) { GP_INOUTSEL(0) } }, + { PINMUX_CFG_REG("INOUTSEL1", 0xE6051004, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_IN, GP_1_25_OUT, + GP_1_24_IN, GP_1_24_OUT, + GP_1_23_IN, GP_1_23_OUT, + GP_1_22_IN, GP_1_22_OUT, + GP_1_21_IN, GP_1_21_OUT, + GP_1_20_IN, GP_1_20_OUT, + GP_1_19_IN, GP_1_19_OUT, + GP_1_18_IN, GP_1_18_OUT, + GP_1_17_IN, GP_1_17_OUT, + GP_1_16_IN, GP_1_16_OUT, + GP_1_15_IN, GP_1_15_OUT, + GP_1_14_IN, GP_1_14_OUT, + GP_1_13_IN, GP_1_13_OUT, + GP_1_12_IN, GP_1_12_OUT, + GP_1_11_IN, GP_1_11_OUT, + GP_1_10_IN, GP_1_10_OUT, + GP_1_9_IN, GP_1_9_OUT, + GP_1_8_IN, GP_1_8_OUT, + GP_1_7_IN, GP_1_7_OUT, + GP_1_6_IN, GP_1_6_OUT, + GP_1_5_IN, GP_1_5_OUT, + GP_1_4_IN, GP_1_4_OUT, + GP_1_3_IN, GP_1_3_OUT, + GP_1_2_IN, GP_1_2_OUT, + GP_1_1_IN, GP_1_1_OUT, + GP_1_0_IN, GP_1_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL2", 0xE6052004, 32, 1) { GP_INOUTSEL(2) } }, + { PINMUX_CFG_REG("INOUTSEL3", 0xE6053004, 32, 1) { GP_INOUTSEL(3) } }, + { PINMUX_CFG_REG("INOUTSEL4", 0xE6054004, 32, 1) { GP_INOUTSEL(4) } }, + { PINMUX_CFG_REG("INOUTSEL5", 0xE6055004, 32, 1) { GP_INOUTSEL(5) } }, + { PINMUX_CFG_REG("INOUTSEL6", 0xE6055404, 32, 1) { GP_INOUTSEL(6) } }, + { PINMUX_CFG_REG("INOUTSEL7", 0xE6055804, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_7_25_IN, GP_7_25_OUT, + GP_7_24_IN, GP_7_24_OUT, + GP_7_23_IN, GP_7_23_OUT, + GP_7_22_IN, GP_7_22_OUT, + GP_7_21_IN, GP_7_21_OUT, + GP_7_20_IN, GP_7_20_OUT, + GP_7_19_IN, GP_7_19_OUT, + GP_7_18_IN, GP_7_18_OUT, + GP_7_17_IN, GP_7_17_OUT, + GP_7_16_IN, GP_7_16_OUT, + GP_7_15_IN, GP_7_15_OUT, + GP_7_14_IN, GP_7_14_OUT, + GP_7_13_IN, GP_7_13_OUT, + GP_7_12_IN, GP_7_12_OUT, + GP_7_11_IN, GP_7_11_OUT, + GP_7_10_IN, GP_7_10_OUT, + GP_7_9_IN, GP_7_9_OUT, + GP_7_8_IN, GP_7_8_OUT, + GP_7_7_IN, GP_7_7_OUT, + GP_7_6_IN, GP_7_6_OUT, + GP_7_5_IN, GP_7_5_OUT, + GP_7_4_IN, GP_7_4_OUT, + GP_7_3_IN, GP_7_3_OUT, + GP_7_2_IN, GP_7_2_OUT, + GP_7_1_IN, GP_7_1_OUT, + GP_7_0_IN, GP_7_0_OUT, } + }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("INDT0", 0xE6050008, 32) { GP_INDT(0) } }, + { PINMUX_DATA_REG("INDT1", 0xE6051008, 32) { + 0, 0, 0, 0, + 0, 0, GP_1_25_DATA, GP_1_24_DATA, + GP_1_23_DATA, GP_1_22_DATA, GP_1_21_DATA, GP_1_20_DATA, + GP_1_19_DATA, GP_1_18_DATA, GP_1_17_DATA, GP_1_16_DATA, + GP_1_15_DATA, GP_1_14_DATA, GP_1_13_DATA, GP_1_12_DATA, + GP_1_11_DATA, GP_1_10_DATA, GP_1_9_DATA, GP_1_8_DATA, + GP_1_7_DATA, GP_1_6_DATA, GP_1_5_DATA, GP_1_4_DATA, + GP_1_3_DATA, GP_1_2_DATA, GP_1_1_DATA, GP_1_0_DATA } + }, + { PINMUX_DATA_REG("INDT2", 0xE6052008, 32) { GP_INDT(2) } }, + { PINMUX_DATA_REG("INDT3", 0xE6053008, 32) { GP_INDT(3) } }, + { PINMUX_DATA_REG("INDT4", 0xE6054008, 32) { GP_INDT(4) } }, + { PINMUX_DATA_REG("INDT5", 0xE6055008, 32) { GP_INDT(5) } }, + { PINMUX_DATA_REG("INDT6", 0xE6055408, 32) { GP_INDT(6) } }, + { PINMUX_DATA_REG("INDT7", 0xE6055808, 32) { + 0, 0, 0, 0, + 0, 0, GP_7_25_DATA, GP_7_24_DATA, + GP_7_23_DATA, GP_7_22_DATA, GP_7_21_DATA, GP_7_20_DATA, + GP_7_19_DATA, GP_7_18_DATA, GP_7_17_DATA, GP_7_16_DATA, + GP_7_15_DATA, GP_7_14_DATA, GP_7_13_DATA, GP_7_12_DATA, + GP_7_11_DATA, GP_7_10_DATA, GP_7_9_DATA, GP_7_8_DATA, + GP_7_7_DATA, GP_7_6_DATA, GP_7_5_DATA, GP_7_4_DATA, + GP_7_3_DATA, GP_7_2_DATA, GP_7_1_DATA, GP_7_0_DATA } + }, + { }, +}; + +static struct pinmux_info r8a7791_pinmux_info = { + .name = "r8a7791_pfc", + + .unlock_reg = 0xe6060000, /* PMMR */ + + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_GP_0_0, + .last_gpio = GPIO_FN_MSIOF0_SCK_C /* GPIO_FN_CAN1_RX_B */, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), +}; + +void r8a7791_pinmux_init(void) +{ + register_pinmux(&r8a7791_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7793.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7793.c new file mode 100644 index 0000000..03c27ad --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7793.c
@@ -0,0 +1,1926 @@ +/* + * arch/arm/cpu/armv7/rmobile/pfc-r8a7793.c + * + * Copyright (C) 2013 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <sh_pfc.h> +#include <asm/gpio.h> + +#define CPU_32_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_1(fn, pfx##31, sfx) + +#define CPU_32_PORT1(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##20, sfx), PORT_1(fn, pfx##21, sfx), \ + PORT_1(fn, pfx##22, sfx), PORT_1(fn, pfx##23, sfx), \ + PORT_1(fn, pfx##24, sfx), PORT_1(fn, pfx##25, sfx) + +/* + * GP_0_0_DATA -> GP_7_25_DATA + * (except for GP1[26],GP1[27],GP1[28],GP1[29]),GP1[30]),GP1[31] + * GP7[26],GP7[27],GP7[28],GP7[29]),GP7[30]),GP7[31]) + */ +#define CPU_ALL_PORT(fn, pfx, sfx) \ + CPU_32_PORT(fn, pfx##_0_, sfx), \ + CPU_32_PORT1(fn, pfx##_1_, sfx), \ + CPU_32_PORT(fn, pfx##_2_, sfx), \ + CPU_32_PORT(fn, pfx##_3_, sfx), \ + CPU_32_PORT(fn, pfx##_4_, sfx), \ + CPU_32_PORT(fn, pfx##_5_, sfx), \ + CPU_32_PORT(fn, pfx##_6_, sfx), \ + CPU_32_PORT1(fn, pfx##_7_, sfx) + +#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA) +#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN, \ + GP##pfx##_IN, GP##pfx##_OUT) + +#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT +#define _GP_INDT(pfx, sfx) GP##pfx##_DATA + +#define GP_ALL(str) CPU_ALL_PORT(_PORT_ALL, GP, str) +#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused) +#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused) + + +#define PORT_10_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ + PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ + PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ + PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ + PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) + +#define CPU_32_PORT_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ + PORT_10_REV(fn, pfx, sfx) + +#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused) +#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused) + +#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn) +#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \ + FN_##ipsr, FN_##fn) + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + GP_ALL(IN), + PINMUX_INPUT_END, + + PINMUX_OUTPUT_BEGIN, + GP_ALL(OUT), + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + + /* GPSR0 */ + FN_IP0_0, FN_IP0_1, FN_IP0_2, FN_IP0_3, FN_IP0_4, FN_IP0_5, + FN_IP0_6, FN_IP0_7, FN_IP0_8, FN_IP0_9, FN_IP0_10, FN_IP0_11, + FN_IP0_12, FN_IP0_13, FN_IP0_14, FN_IP0_15, FN_IP0_18_16, FN_IP0_20_19, + FN_IP0_22_21, FN_IP0_24_23, FN_IP0_26_25, FN_IP0_28_27, FN_IP0_30_29, + FN_IP1_1_0, FN_IP1_3_2, FN_IP1_5_4, FN_IP1_7_6, FN_IP1_10_8, + FN_IP1_13_11, FN_IP1_16_14, FN_IP1_19_17, FN_IP1_22_20, + + /* GPSR1 */ + FN_IP1_25_23, FN_IP1_28_26, FN_IP1_31_29, FN_IP2_2_0, FN_IP2_4_3, + FN_IP2_6_5, FN_IP2_9_7, FN_IP2_12_10, FN_IP2_15_13, FN_IP2_18_16, + FN_IP2_20_19, FN_IP2_22_21, FN_EX_CS0_N, FN_IP2_24_23, FN_IP2_26_25, + FN_IP2_29_27, FN_IP3_2_0, FN_IP3_5_3, FN_IP3_8_6, FN_RD_N, + FN_IP3_11_9, FN_IP3_13_12, FN_IP3_15_14 , FN_IP3_17_16 , FN_IP3_19_18, + FN_IP3_21_20, + + /* GPSR2 */ + FN_IP3_27_25, FN_IP3_30_28, FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, + FN_IP4_9_8, FN_IP4_12_10, FN_IP4_15_13, FN_IP4_18_16, FN_IP4_19, + FN_IP4_20, FN_IP4_21, FN_IP4_23_22, FN_IP4_25_24, FN_IP4_27_26, + FN_IP4_30_28, FN_IP5_2_0, FN_IP5_5_3, FN_IP5_8_6, FN_IP5_11_9, + FN_IP5_14_12, FN_IP5_16_15, FN_IP5_19_17, FN_IP5_21_20, FN_IP5_23_22, + FN_IP5_25_24, FN_IP5_28_26, FN_IP5_31_29, FN_AUDIO_CLKA, FN_IP6_2_0, + FN_IP6_5_3, FN_IP6_7_6, + + /* GPSR3 */ + FN_IP7_5_3, FN_IP7_8_6, FN_IP7_10_9, FN_IP7_12_11, FN_IP7_14_13, + FN_IP7_16_15, FN_IP7_18_17, FN_IP7_20_19, FN_IP7_23_21, FN_IP7_26_24, + FN_IP7_29_27, FN_IP8_2_0, FN_IP8_5_3, FN_IP8_8_6, FN_IP8_11_9, + FN_IP8_14_12, FN_IP8_17_15, FN_IP8_20_18, FN_IP8_23_21, FN_IP8_25_24, + FN_IP8_27_26, FN_IP8_30_28, FN_IP9_2_0, FN_IP9_5_3, FN_IP9_6, FN_IP9_7, + FN_IP9_10_8, FN_IP9_11, FN_IP9_12, FN_IP9_15_13, FN_IP9_16, + FN_IP9_18_17, + + /* GPSR4 */ + FN_VI0_CLK, FN_IP9_20_19, FN_IP9_22_21, FN_IP9_24_23, FN_IP9_26_25, + FN_VI0_DATA0_VI0_B0, FN_VI0_DATA0_VI0_B1, FN_VI0_DATA0_VI0_B2, + FN_IP9_28_27, FN_VI0_DATA0_VI0_B4, FN_VI0_DATA0_VI0_B5, + FN_VI0_DATA0_VI0_B6, FN_VI0_DATA0_VI0_B7, FN_IP9_31_29, FN_IP10_2_0, + FN_IP10_5_3, FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_16_15, + FN_IP10_18_17, FN_IP10_21_19, FN_IP10_24_22, FN_IP10_26_25, + FN_IP10_28_27, FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6, + FN_IP15_1_0, FN_IP15_3_2, FN_IP15_5_4, + + /* GPSR5 */ + FN_IP11_11_9, FN_IP11_14_12, FN_IP11_16_15, FN_IP11_18_17, FN_IP11_19, + FN_IP11_20, FN_IP11_21, FN_IP11_22, FN_IP11_23, FN_IP11_24, + FN_IP11_25, FN_IP11_26, FN_IP11_27, FN_IP11_29_28, FN_IP11_31_30, + FN_IP12_1_0, FN_IP12_3_2, FN_IP12_6_4, FN_IP12_9_7, FN_IP12_12_10, + FN_IP12_15_13, FN_IP12_17_16, FN_IP12_19_18, FN_IP12_21_20, + FN_IP12_23_22, FN_IP12_26_24, FN_IP12_29_27, FN_IP13_2_0, FN_IP13_4_3, + FN_IP13_6_5, FN_IP13_9_7, FN_IP3_24_22, + + /* GPSR6 */ + FN_IP13_10, FN_IP13_11, FN_IP13_12, FN_IP13_13, FN_IP13_14, + FN_IP13_15, FN_IP13_18_16, FN_IP13_21_19, FN_IP13_22, FN_IP13_24_23, + FN_IP13_25, FN_IP13_26, FN_IP13_27, FN_IP13_30_28, FN_IP14_1_0, + FN_IP14_2, FN_IP14_3, FN_IP14_4, FN_IP14_5, FN_IP14_6, FN_IP14_7, + FN_IP14_10_8, FN_IP14_13_11, FN_IP14_16_14, FN_IP14_19_17, + FN_IP14_22_20, FN_IP14_25_23, FN_IP14_28_26, FN_IP14_31_29, + + /* GPSR7 */ + FN_IP15_17_15, FN_IP15_20_18, FN_IP15_23_21, FN_IP15_26_24, + FN_IP15_29_27, FN_IP16_2_0, FN_IP16_5_3, FN_IP16_7_6, FN_IP16_9_8, + FN_IP16_11_10, FN_IP6_9_8, FN_IP6_11_10, FN_IP6_13_12, FN_IP6_15_14, + FN_IP6_18_16, FN_IP6_20_19, FN_IP6_23_21, FN_IP6_26_24, FN_IP6_29_27, + FN_IP7_2_0, FN_IP15_8_6, FN_IP15_11_9, FN_IP15_14_12, + FN_USB0_PWEN, FN_USB0_OVC, FN_USB1_PWEN, + + /* IPSR 0 -5 */ + + /* IPSR6 */ + FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B, + FN_SCIF_CLK, FN_BPFCLK_E, + FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2, + FN_SCIFA2_RXD, FN_FMIN_E, + FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD, + FN_IRQ0, FN_SCIFB1_RXD_D, FN_INTC_IRQ0_N, + FN_IRQ1, FN_SCIFB1_SCK_C, FN_INTC_IRQ1_N, + FN_IRQ2, FN_SCIFB1_TXD_D, FN_INTC_IRQ2_N, + FN_IRQ3, FN_SCL4_C, FN_MSIOF2_TXD_E, FN_INTC_IRQ3_N, + FN_IRQ4, FN_HRX1_C, FN_SDA4_C, FN_MSIOF2_RXD_E, FN_INTC_IRQ4_N, + FN_IRQ5, FN_HTX1_C, FN_SCL1_E, FN_MSIOF2_SCK_E, + FN_IRQ6, FN_HSCK1_C, FN_MSIOF1_SS2_B, FN_SDA1_E, FN_MSIOF2_SYNC_E, + FN_IRQ7, FN_HCTS1_N_C, FN_MSIOF1_TXD_B, FN_GPS_CLK_C, FN_GPS_CLK_D, + FN_IRQ8, FN_HRTS1_N_C, FN_MSIOF1_RXD_B, FN_GPS_SIGN_C, FN_GPS_SIGN_D, + + /* IPSR7 - IPSR10 */ + + /* IPSR11 */ + FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, + FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, + FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, + FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, + FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, FN_TX4_B, FN_SCIFA4_TXD_B, + FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, FN_RX4_B, FN_SCIFA4_RXD_B, + FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, + FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, + FN_VI1_CLK, FN_AVB_RXD4, FN_VI1_DATA0, FN_AVB_RXD5, + FN_VI1_DATA1, FN_AVB_RXD6, FN_VI1_DATA2, FN_AVB_RXD7, + FN_VI1_DATA3, FN_AVB_RX_ER, FN_VI1_DATA4, FN_AVB_MDIO, + FN_VI1_DATA5, FN_AVB_RX_DV, FN_VI1_DATA6, FN_AVB_MAGIC, + FN_VI1_DATA7, FN_AVB_MDC, + FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, + FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, + + /* IPSR12 */ + FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, + FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, + FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, + FN_SCL2_D, FN_MSIOF1_RXD_E, + FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, FN_SDA2_D, FN_MSIOF1_SCK_E, + FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, + FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, + FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, + FN_CAN1_TX_C, FN_MSIOF1_TXD_E, + FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, + FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, + FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, + FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, + FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, + FN_ADIDATA_B, FN_MSIOF0_SYNC_C, + FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, + FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, + + /* IPSR13 */ + FN_STP_ISD_0, FN_AVB_TX_ER, FN_SCIFB2_SCK_C, + FN_ADICLK_B, FN_MSIOF0_SS1_C, + FN_STP_ISEN_0, FN_AVB_TX_CLK, FN_ADICHS0_B, FN_MSIOF0_SS2_C, + FN_STP_ISSYNC_0, FN_AVB_COL, FN_ADICHS1_B, FN_MSIOF0_RXD_C, + FN_STP_OPWM_0, FN_AVB_GTX_CLK, FN_PWM0_B, + FN_ADICHS2_B, FN_MSIOF0_TXD_C, + FN_SD0_CLK, FN_SPCLK_B, FN_SD0_CMD, FN_MOSI_IO0_B, + FN_SD0_DATA0, FN_MISO_IO1_B, FN_SD0_DATA1, FN_IO2_B, + FN_SD0_DATA2, FN_IO3_B, FN_SD0_DATA3, FN_SSL_B, + FN_SD0_CD, FN_MMC_D6_B, FN_SIM0_RST_B, FN_CAN0_RX_F, + FN_SCIFA5_TXD_B, FN_TX3_C, + FN_SD0_WP, FN_MMC_D7_B, FN_SIM0_D_B, FN_CAN0_TX_F, + FN_SCIFA5_RXD_B, FN_RX3_C, + FN_SD1_CMD, FN_REMOCON_B, FN_SD1_DATA0, FN_SPEEDIN_B, + FN_SD1_DATA1, FN_IETX_B, FN_SD1_DATA2, FN_IECLK_B, + FN_SD1_DATA3, FN_IERX_B, + FN_SD1_CD, FN_PWM0, FN_TPU_TO0, FN_SCL1_C, + + /* IPSR14 */ + FN_SD1_WP, FN_PWM1_B, FN_SDA1_C, + FN_SD2_CLK, FN_MMC_CLK, FN_SD2_CMD, FN_MMC_CMD, + FN_SD2_DATA0, FN_MMC_D0, FN_SD2_DATA1, FN_MMC_D1, + FN_SD2_DATA2, FN_MMC_D2, FN_SD2_DATA3, FN_MMC_D3, + FN_SD2_CD, FN_MMC_D4, FN_SCL8_C, FN_TX5_B, FN_SCIFA5_TXD_C, + FN_SD2_WP, FN_MMC_D5, FN_SDA8_C, FN_RX5_B, FN_SCIFA5_RXD_C, + FN_MSIOF0_SCK, FN_RX2_C, FN_ADIDATA, FN_VI1_CLK_C, FN_VI1_G0_B, + FN_MSIOF0_SYNC, FN_TX2_C, FN_ADICS_SAMP, FN_VI1_CLKENB_C, FN_VI1_G1_B, + FN_MSIOF0_TXD, FN_ADICLK, FN_VI1_FIELD_C, FN_VI1_G2_B, + FN_MSIOF0_RXD, FN_ADICHS0, FN_VI1_DATA0_C, FN_VI1_G3_B, + FN_MSIOF0_SS1, FN_MMC_D6, FN_ADICHS1, FN_TX0_E, + FN_VI1_HSYNC_N_C, FN_SCL7_C, FN_VI1_G4_B, + FN_MSIOF0_SS2, FN_MMC_D7, FN_ADICHS2, FN_RX0_E, + FN_VI1_VSYNC_N_C, FN_SDA7_C, FN_VI1_G5_B, + + /* IPSR15 */ + FN_SIM0_RST, FN_IETX, FN_CAN1_TX_D, + FN_SIM0_CLK, FN_IECLK, FN_CAN_CLK_C, + FN_SIM0_D, FN_IERX, FN_CAN1_RX_D, + FN_GPS_CLK, FN_DU1_DOTCLKIN_C, FN_AUDIO_CLKB_B, + FN_PWM5_B, FN_SCIFA3_TXD_C, + FN_GPS_SIGN, FN_TX4_C, FN_SCIFA4_TXD_C, FN_PWM5, + FN_VI1_G6_B, FN_SCIFA3_RXD_C, + FN_GPS_MAG, FN_RX4_C, FN_SCIFA4_RXD_C, FN_PWM6, + FN_VI1_G7_B, FN_SCIFA3_SCK_C, + FN_HCTS0_N, FN_SCIFB0_CTS_N, FN_GLO_I0_C, FN_TCLK1, FN_VI1_DATA1_C, + FN_HRTS0_N, FN_SCIFB0_RTS_N, FN_GLO_I1_C, FN_VI1_DATA2_C, + FN_HSCK0, FN_SCIFB0_SCK, FN_GLO_Q0_C, FN_CAN_CLK, + FN_TCLK2, FN_VI1_DATA3_C, + FN_HRX0, FN_SCIFB0_RXD, FN_GLO_Q1_C, FN_CAN0_RX_B, FN_VI1_DATA4_C, + FN_HTX0, FN_SCIFB0_TXD, FN_GLO_SCLK_C, FN_CAN0_TX_B, FN_VI1_DATA5_C, + + /* IPSR16 */ + FN_HRX1, FN_SCIFB1_RXD, FN_VI1_R0_B, FN_GLO_SDATA_C, FN_VI1_DATA6_C, + FN_HTX1, FN_SCIFB1_TXD, FN_VI1_R1_B, FN_GLO_SS_C, FN_VI1_DATA7_C, + FN_HSCK1, FN_SCIFB1_SCK, FN_MLB_CK, FN_GLO_RFON_C, + FN_HCTS1_N, FN_SCIFB1_CTS_N, FN_MLB_SIG, FN_CAN1_TX_B, + FN_HRTS1_N, FN_SCIFB1_RTS_N, FN_MLB_DAT, FN_CAN1_RX_B, + + /* MOD_SEL */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, + FN_SEL_SSI9_0, FN_SEL_SSI9_1, + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + FN_SEL_QSP_0, FN_SEL_QSP_1, + FN_SEL_SSI7_0, FN_SEL_SSI7_1, + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, FN_SEL_HSCIF1_3, + FN_SEL_HSCIF1_4, + FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, + + /* MOD_SEL2 */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3, + FN_SEL_SCIF0_4, + FN_SEL_SCIF_0, FN_SEL_SCIF_1, + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + FN_SEL_CAN0_4, FN_SEL_CAN0_5, + FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, + FN_SEL_ADG_0, FN_SEL_ADG_1, + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3, FN_SEL_FM_4, + FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, + FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, + FN_SEL_SIM_0, FN_SEL_SIM_1, + FN_SEL_SSI8_0, FN_SEL_SSI8_1, + + /* MOD_SEL3 */ + FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, + FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, + FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, + FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, + FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, + FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, + FN_SEL_MMC_0, FN_SEL_MMC_1, + FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, + FN_SEL_IIC1_4, + FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, + + /* MOD_SEL4 */ + FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, + FN_SEL_SOF1_4, + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, + FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, + FN_SEL_RAD_0, FN_SEL_RAD_1, + FN_SEL_RCN_0, FN_SEL_RCN_1, + FN_SEL_RSP_0, FN_SEL_RSP_1, + FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, FN_SEL_SCIF2_3, + FN_SEL_SCIF2_4, + FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, FN_SEL_SOF2_3, + FN_SEL_SOF2_4, + FN_SEL_SSI1_0, FN_SEL_SSI1_1, + FN_SEL_SSI0_0, FN_SEL_SSI0_1, + FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + + EX_CS0_N_MARK, RD_N_MARK, + + AUDIO_CLKA_MARK, + + VI0_CLK_MARK, VI0_DATA0_VI0_B0_MARK, VI0_DATA0_VI0_B1_MARK, + VI0_DATA0_VI0_B2_MARK, VI0_DATA0_VI0_B4_MARK, VI0_DATA0_VI0_B5_MARK, + VI0_DATA0_VI0_B6_MARK, VI0_DATA0_VI0_B7_MARK, + + USB0_PWEN_MARK, USB0_OVC_MARK, USB1_PWEN_MARK, + + /* IPSR0 - 5 */ + + /* IPSR6 */ + AUDIO_CLKB_MARK, STP_OPWM_0_B_MARK, MSIOF1_SCK_B_MARK, + SCIF_CLK_MARK, BPFCLK_E_MARK, + AUDIO_CLKC_MARK, SCIFB0_SCK_C_MARK, MSIOF1_SYNC_B_MARK, RX2_MARK, + SCIFA2_RXD_MARK, FMIN_E_MARK, + AUDIO_CLKOUT_MARK, MSIOF1_SS1_B_MARK, TX2_MARK, SCIFA2_TXD_MARK, + IRQ0_MARK, SCIFB1_RXD_D_MARK, INTC_IRQ0_N_MARK, + IRQ1_MARK, SCIFB1_SCK_C_MARK, INTC_IRQ1_N_MARK, + IRQ2_MARK, SCIFB1_TXD_D_MARK, INTC_IRQ2_N_MARK, + IRQ3_MARK, SCL4_C_MARK, MSIOF2_TXD_E_MARK, INTC_IRQ3_N_MARK, + IRQ4_MARK, HRX1_C_MARK, SDA4_C_MARK, + MSIOF2_RXD_E_MARK, INTC_IRQ4_N_MARK, + IRQ5_MARK, HTX1_C_MARK, SCL1_E_MARK, MSIOF2_SCK_E_MARK, + IRQ6_MARK, HSCK1_C_MARK, MSIOF1_SS2_B_MARK, + SDA1_E_MARK, MSIOF2_SYNC_E_MARK, + IRQ7_MARK, HCTS1_N_C_MARK, MSIOF1_TXD_B_MARK, + GPS_CLK_C_MARK, GPS_CLK_D_MARK, + IRQ8_MARK, HRTS1_N_C_MARK, MSIOF1_RXD_B_MARK, + GPS_SIGN_C_MARK, GPS_SIGN_D_MARK, + + /* IPSR7 - 10 */ + + /* IPSR11 */ + VI0_R5_MARK, VI2_DATA6_MARK, GLO_SDATA_B_MARK, RX0_C_MARK, SDA1_D_MARK, + VI0_R6_MARK, VI2_DATA7_MARK, GLO_SS_B_MARK, TX1_C_MARK, SCL4_B_MARK, + VI0_R7_MARK, GLO_RFON_B_MARK, RX1_C_MARK, CAN0_RX_E_MARK, + SDA4_B_MARK, HRX1_D_MARK, SCIFB0_RXD_D_MARK, + VI1_HSYNC_N_MARK, AVB_RXD0_MARK, TS_SDATA0_B_MARK, + TX4_B_MARK, SCIFA4_TXD_B_MARK, + VI1_VSYNC_N_MARK, AVB_RXD1_MARK, TS_SCK0_B_MARK, + RX4_B_MARK, SCIFA4_RXD_B_MARK, + VI1_CLKENB_MARK, AVB_RXD2_MARK, TS_SDEN0_B_MARK, + VI1_FIELD_MARK, AVB_RXD3_MARK, TS_SPSYNC0_B_MARK, + VI1_CLK_MARK, AVB_RXD4_MARK, VI1_DATA0_MARK, AVB_RXD5_MARK, + VI1_DATA1_MARK, AVB_RXD6_MARK, VI1_DATA2_MARK, AVB_RXD7_MARK, + VI1_DATA3_MARK, AVB_RX_ER_MARK, VI1_DATA4_MARK, AVB_MDIO_MARK, + VI1_DATA5_MARK, AVB_RX_DV_MARK, VI1_DATA6_MARK, AVB_MAGIC_MARK, + VI1_DATA7_MARK, AVB_MDC_MARK, + ETH_MDIO_MARK, AVB_RX_CLK_MARK, SCL2_C_MARK, + ETH_CRS_DV_MARK, AVB_LINK_MARK, SDA2_C_MARK, + + /* IPSR12 */ + ETH_RX_ER_MARK, AVB_CRS_MARK, SCL3_MARK, SCL7_MARK, + ETH_RXD0_MARK, AVB_PHY_INT_MARK, SDA3_MARK, SDA7_MARK, + ETH_RXD1_MARK, AVB_GTXREFCLK_MARK, CAN0_TX_C_MARK, + SCL2_D_MARK, MSIOF1_RXD_E_MARK, + ETH_LINK_MARK, AVB_TXD0_MARK, CAN0_RX_C_MARK, + SDA2_D_MARK, MSIOF1_SCK_E_MARK, + ETH_REFCLK_MARK, AVB_TXD1_MARK, SCIFA3_RXD_B_MARK, + CAN1_RX_C_MARK, MSIOF1_SYNC_E_MARK, + ETH_TXD1_MARK, AVB_TXD2_MARK, SCIFA3_TXD_B_MARK, + CAN1_TX_C_MARK, MSIOF1_TXD_E_MARK, + ETH_TX_EN_MARK, AVB_TXD3_MARK, TCLK1_B_MARK, CAN_CLK_B_MARK, + ETH_MAGIC_MARK, AVB_TXD4_MARK, IETX_C_MARK, + ETH_TXD0_MARK, AVB_TXD5_MARK, IECLK_C_MARK, + ETH_MDC_MARK, AVB_TXD6_MARK, IERX_C_MARK, + STP_IVCXO27_0_MARK, AVB_TXD7_MARK, SCIFB2_TXD_D_MARK, + ADIDATA_B_MARK, MSIOF0_SYNC_C_MARK, + STP_ISCLK_0_MARK, AVB_TX_EN_MARK, SCIFB2_RXD_D_MARK, + ADICS_SAMP_B_MARK, MSIOF0_SCK_C_MARK, + + /* IPSR13 */ + STP_ISD_0_MARK, AVB_TX_ER_MARK, SCIFB2_SCK_C_MARK, + ADICLK_B_MARK, MSIOF0_SS1_C_MARK, + STP_ISEN_0_MARK, AVB_TX_CLK_MARK, ADICHS0_B_MARK, MSIOF0_SS2_C_MARK, + STP_ISSYNC_0_MARK, AVB_COL_MARK, ADICHS1_B_MARK, MSIOF0_RXD_C_MARK, + STP_OPWM_0_MARK, AVB_GTX_CLK_MARK, PWM0_B_MARK, + ADICHS2_B_MARK, MSIOF0_TXD_C_MARK, + SD0_CLK_MARK, SPCLK_B_MARK, SD0_CMD_MARK, MOSI_IO0_B_MARK, + SD0_DATA0_MARK, MISO_IO1_B_MARK, SD0_DATA1_MARK, IO2_B_MARK, + SD0_DATA2_MARK, IO3_B_MARK, SD0_DATA3_MARK, SSL_B_MARK, + SD0_CD_MARK, MMC_D6_B_MARK, SIM0_RST_B_MARK, CAN0_RX_F_MARK, + SCIFA5_TXD_B_MARK, TX3_C_MARK, + SD0_WP_MARK, MMC_D7_B_MARK, SIM0_D_B_MARK, CAN0_TX_F_MARK, + SCIFA5_RXD_B_MARK, RX3_C_MARK, + SD1_CMD_MARK, REMOCON_B_MARK, SD1_DATA0_MARK, SPEEDIN_B_MARK, + SD1_DATA1_MARK, IETX_B_MARK, SD1_DATA2_MARK, IECLK_B_MARK, + SD1_DATA3_MARK, IERX_B_MARK, + SD1_CD_MARK, PWM0_MARK, TPU_TO0_MARK, SCL1_C_MARK, + + /* IPSR14 */ + SD1_WP_MARK, PWM1_B_MARK, SDA1_C_MARK, + SD2_CLK_MARK, MMC_CLK_MARK, SD2_CMD_MARK, MMC_CMD_MARK, + SD2_DATA0_MARK, MMC_D0_MARK, SD2_DATA1_MARK, MMC_D1_MARK, + SD2_DATA2_MARK, MMC_D2_MARK, SD2_DATA3_MARK, MMC_D3_MARK, + SD2_CD_MARK, MMC_D4_MARK, SCL8_C_MARK, TX5_B_MARK, SCIFA5_TXD_C_MARK, + SD2_WP_MARK, MMC_D5_MARK, SDA8_C_MARK, RX5_B_MARK, SCIFA5_RXD_C_MARK, + MSIOF0_SCK_MARK, RX2_C_MARK, ADIDATA_MARK, + VI1_CLK_C_MARK, VI1_G0_B_MARK, + MSIOF0_SYNC_MARK, TX2_C_MARK, ADICS_SAMP_MARK, + VI1_CLKENB_C_MARK, VI1_G1_B_MARK, + MSIOF0_TXD_MARK, ADICLK_MARK, VI1_FIELD_C_MARK, VI1_G2_B_MARK, + MSIOF0_RXD_MARK, ADICHS0_MARK, VI1_DATA0_C_MARK, VI1_G3_B_MARK, + MSIOF0_SS1_MARK, MMC_D6_MARK, ADICHS1_MARK, TX0_E_MARK, + VI1_HSYNC_N_C_MARK, SCL7_C_MARK, VI1_G4_B_MARK, + MSIOF0_SS2_MARK, MMC_D7_MARK, ADICHS2_MARK, RX0_E_MARK, + VI1_VSYNC_N_C_MARK, SDA7_C_MARK, VI1_G5_B_MARK, + + /* IPSR15 */ + SIM0_RST_MARK, IETX_MARK, CAN1_TX_D_MARK, + SIM0_CLK_MARK, IECLK_MARK, CAN_CLK_C_MARK, + SIM0_D_MARK, IERX_MARK, CAN1_RX_D_MARK, + GPS_CLK_MARK, DU1_DOTCLKIN_C_MARK, AUDIO_CLKB_B_MARK, + PWM5_B_MARK, SCIFA3_TXD_C_MARK, + GPS_SIGN_MARK, TX4_C_MARK, SCIFA4_TXD_C_MARK, PWM5_MARK, + VI1_G6_B_MARK, SCIFA3_RXD_C_MARK, + GPS_MAG_MARK, RX4_C_MARK, SCIFA4_RXD_C_MARK, PWM6_MARK, + VI1_G7_B_MARK, SCIFA3_SCK_C_MARK, + HCTS0_N_MARK, SCIFB0_CTS_N_MARK, GLO_I0_C_MARK, + TCLK1_MARK, VI1_DATA1_C_MARK, + HRTS0_N_MARK, SCIFB0_RTS_N_MARK, GLO_I1_C_MARK, VI1_DATA2_C_MARK, + HSCK0_MARK, SCIFB0_SCK_MARK, GLO_Q0_C_MARK, CAN_CLK_MARK, + TCLK2_MARK, VI1_DATA3_C_MARK, + HRX0_MARK, SCIFB0_RXD_MARK, GLO_Q1_C_MARK, + CAN0_RX_B_MARK, VI1_DATA4_C_MARK, + HTX0_MARK, SCIFB0_TXD_MARK, GLO_SCLK_C_MARK, + CAN0_TX_B_MARK, VI1_DATA5_C_MARK, + + /* IPSR16 */ + HRX1_MARK, SCIFB1_RXD_MARK, VI1_R0_B_MARK, + GLO_SDATA_C_MARK, VI1_DATA6_C_MARK, + HTX1_MARK, SCIFB1_TXD_MARK, VI1_R1_B_MARK, + GLO_SS_C_MARK, VI1_DATA7_C_MARK, + HSCK1_MARK, SCIFB1_SCK_MARK, MLB_CK_MARK, GLO_RFON_C_MARK, + HCTS1_N_MARK, SCIFB1_CTS_N_MARK, MLB_SIG_MARK, CAN1_TX_B_MARK, + HRTS1_N_MARK, SCIFB1_RTS_N_MARK, MLB_DAT_MARK, CAN1_RX_B_MARK, + PINMUX_MARK_END, +}; + +static pinmux_enum_t pinmux_data[] = { + PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ + + PINMUX_DATA(EX_CS0_N_MARK, FN_EX_CS0_N), + PINMUX_DATA(RD_N_MARK, FN_RD_N), + PINMUX_DATA(AUDIO_CLKA_MARK, FN_AUDIO_CLKA), + PINMUX_DATA(VI0_CLK_MARK, FN_VI0_CLK), + PINMUX_DATA(VI0_DATA0_VI0_B0_MARK, FN_VI0_DATA0_VI0_B0), + PINMUX_DATA(VI0_DATA0_VI0_B1_MARK, FN_VI0_DATA0_VI0_B1), + PINMUX_DATA(VI0_DATA0_VI0_B2_MARK, FN_VI0_DATA0_VI0_B2), + PINMUX_DATA(VI0_DATA0_VI0_B4_MARK, FN_VI0_DATA0_VI0_B4), + PINMUX_DATA(VI0_DATA0_VI0_B5_MARK, FN_VI0_DATA0_VI0_B5), + PINMUX_DATA(VI0_DATA0_VI0_B6_MARK, FN_VI0_DATA0_VI0_B6), + PINMUX_DATA(VI0_DATA0_VI0_B7_MARK, FN_VI0_DATA0_VI0_B7), + PINMUX_DATA(USB0_PWEN_MARK, FN_USB0_PWEN), + PINMUX_DATA(USB0_OVC_MARK, FN_USB0_OVC), + PINMUX_DATA(USB1_PWEN_MARK, FN_USB1_PWEN), + + /* IPSR0 - 5 */ + + /* IPSR6 */ + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, AUDIO_CLKB, SEL_ADG_0), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, STP_OPWM_0_B, SEL_SSP_1), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, MSIOF1_SCK_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SCIF_CLK, SEL_SCIF_0), + PINMUX_IPSR_MODSEL_DATA(IP6_2_0, BPFCLK_E, SEL_FM_4), + PINMUX_IPSR_DATA(IP6_5_3, AUDIO_CLKC), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SCIFB0_SCK_C, SEL_SCIFB_2), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, MSIOF1_SYNC_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, RX2, SEL_SCIF2_0), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SCIFA2_RXD, SEL_SCIFA2_0), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, FMIN_E, SEL_FM_4), + PINMUX_IPSR_DATA(IP6_7_6, AUDIO_CLKOUT), + PINMUX_IPSR_MODSEL_DATA(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_5_3, TX2, SEL_SCIF2_0), + PINMUX_IPSR_MODSEL_DATA(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0), + PINMUX_IPSR_DATA(IP6_9_8, IRQ0), + PINMUX_IPSR_MODSEL_DATA(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3), + PINMUX_IPSR_DATA(IP6_9_8, INTC_IRQ0_N), + PINMUX_IPSR_DATA(IP6_11_10, IRQ1), + PINMUX_IPSR_MODSEL_DATA(IP6_11_10, SCIFB1_SCK_C, SEL_SCIFB1_2), + PINMUX_IPSR_DATA(IP6_11_10, INTC_IRQ1_N), + PINMUX_IPSR_DATA(IP6_13_12, IRQ2), + PINMUX_IPSR_MODSEL_DATA(IP6_13_12, SCIFB1_TXD_D, SEL_SCIFB1_3), + PINMUX_IPSR_DATA(IP6_13_12, INTC_IRQ2_N), + PINMUX_IPSR_DATA(IP6_15_14, IRQ3), + PINMUX_IPSR_MODSEL_DATA(IP6_15_14, SCL4_C, SEL_IIC4_2), + PINMUX_IPSR_MODSEL_DATA(IP6_15_14, MSIOF2_TXD_E, SEL_SOF2_4), + PINMUX_IPSR_DATA(IP6_15_14, INTC_IRQ4_N), + PINMUX_IPSR_DATA(IP6_18_16, IRQ4), + PINMUX_IPSR_MODSEL_DATA(IP6_18_16, HRX1_C, SEL_HSCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP6_18_16, SDA4_C, SEL_IIC4_2), + PINMUX_IPSR_MODSEL_DATA(IP6_18_16, MSIOF2_RXD_E, SEL_SOF2_4), + PINMUX_IPSR_DATA(IP6_18_16, INTC_IRQ4_N), + PINMUX_IPSR_DATA(IP6_20_19, IRQ5), + PINMUX_IPSR_MODSEL_DATA(IP6_20_19, HTX1_C, SEL_HSCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP6_20_19, SCL1_E, SEL_IIC1_4), + PINMUX_IPSR_MODSEL_DATA(IP6_20_19, MSIOF2_SCK_E, SEL_SOF2_4), + PINMUX_IPSR_DATA(IP6_23_21, IRQ6), + PINMUX_IPSR_MODSEL_DATA(IP6_23_21, HSCK1_C, SEL_HSCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP6_23_21, MSIOF1_SS2_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_23_21, SDA1_E, SEL_IIC1_4), + PINMUX_IPSR_MODSEL_DATA(IP6_23_21, MSIOF2_SYNC_E, SEL_SOF2_4), + PINMUX_IPSR_DATA(IP6_26_24, IRQ7), + PINMUX_IPSR_MODSEL_DATA(IP6_26_24, HCTS1_N_C, SEL_HSCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP6_26_24, MSIOF1_TXD_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_26_24, GPS_CLK_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_26_24, GPS_CLK_D, SEL_GPS_3), + PINMUX_IPSR_DATA(IP6_29_27, IRQ8), + PINMUX_IPSR_MODSEL_DATA(IP6_29_27, HRTS1_N_C, SEL_HSCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP6_29_27, MSIOF1_RXD_B, SEL_SOF1_1), + PINMUX_IPSR_MODSEL_DATA(IP6_29_27, GPS_SIGN_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP6_29_27, GPS_SIGN_D, SEL_GPS_3), + + /* IPSR7 - 10 */ + + /* IPSR11 */ + PINMUX_IPSR_DATA(IP11_2_0, VI0_R5), + PINMUX_IPSR_DATA(IP11_2_0, VI2_DATA6), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, GLO_SDATA_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, RX0_C, SEL_SCIF0_2), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SDA1_D, SEL_IIC1_3), + PINMUX_IPSR_DATA(IP11_5_3, VI0_R6), + PINMUX_IPSR_DATA(IP11_5_3, VI2_DATA7), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, GLO_SS_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, TX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SCL4_B, SEL_IIC4_1), + PINMUX_IPSR_DATA(IP11_8_6, VI0_R7), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, GLO_RFON_B, SEL_GPS_1), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, RX1_C, SEL_SCIF1_2), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, CAN0_RX_E, SEL_CAN0_4), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SDA4_B, SEL_IIC4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, HRX1_D, SEL_HSCIF1_3), + PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SCIFB0_RXD_D, SEL_SCIFB_3), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, VI1_HSYNC_N, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_11_9, AVB_RXD0), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TS_SDATA0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TX4_B, SEL_SCIF4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_11_9, SCIFA4_TXD_B, SEL_SCIFA4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, VI1_VSYNC_N, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_14_12, AVB_RXD1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, TS_SCK0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, RX4_B, SEL_SCIF4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_14_12, SCIFA4_RXD_B, SEL_SCIFA4_1), + PINMUX_IPSR_MODSEL_DATA(IP11_16_15, VI1_CLKENB, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_16_15, AVB_RXD2), + PINMUX_IPSR_MODSEL_DATA(IP11_16_15, TS_SDEN0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_18_17, VI1_FIELD, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_18_17, AVB_RXD3), + PINMUX_IPSR_MODSEL_DATA(IP11_18_17, TS_SPSYNC0_B, SEL_TSIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP11_19, VI1_CLK, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_19, AVB_RXD4), + PINMUX_IPSR_MODSEL_DATA(IP11_20, VI1_DATA0, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_20, AVB_RXD5), + PINMUX_IPSR_MODSEL_DATA(IP11_21, VI1_DATA1, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_21, AVB_RXD6), + PINMUX_IPSR_MODSEL_DATA(IP11_22, VI1_DATA2, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_22, AVB_RXD7), + PINMUX_IPSR_MODSEL_DATA(IP11_23, VI1_DATA3, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_23, AVB_RX_ER), + PINMUX_IPSR_MODSEL_DATA(IP11_24, VI1_DATA4, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_24, AVB_MDIO), + PINMUX_IPSR_MODSEL_DATA(IP11_25, VI1_DATA5, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_25, AVB_RX_DV), + PINMUX_IPSR_MODSEL_DATA(IP11_26, VI1_DATA6, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_26, AVB_MAGIC), + PINMUX_IPSR_MODSEL_DATA(IP11_27, VI1_DATA7, SEL_VI1_0), + PINMUX_IPSR_DATA(IP11_27, AVB_MDC), + PINMUX_IPSR_DATA(IP11_29_28, ETH_MDIO), + PINMUX_IPSR_DATA(IP11_29_28, AVB_RX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP11_29_28, SCL2_C, SEL_IIC2_2), + PINMUX_IPSR_DATA(IP11_31_30, ETH_CRS_DV), + PINMUX_IPSR_DATA(IP11_31_30, AVB_LINK), + PINMUX_IPSR_MODSEL_DATA(IP11_31_30, SDA2_C, SEL_IIC2_2), + + /* IPSR12 */ + PINMUX_IPSR_DATA(IP12_1_0, ETH_RX_ER), + PINMUX_IPSR_DATA(IP12_1_0, AVB_CRS), + PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL3, SEL_IIC3_0), + PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL7, SEL_IIC7_0), + PINMUX_IPSR_DATA(IP12_3_2, ETH_RXD0), + PINMUX_IPSR_DATA(IP12_3_2, AVB_PHY_INT), + PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA3, SEL_IIC3_0), + PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA7, SEL_IIC7_0), + PINMUX_IPSR_DATA(IP12_6_4, ETH_RXD1), + PINMUX_IPSR_DATA(IP12_6_4, AVB_GTXREFCLK), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, CAN0_TX_C, SEL_CAN0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, SCL2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_6_4, MSIOF1_RXD_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_9_7, ETH_LINK), + PINMUX_IPSR_DATA(IP12_9_7, AVB_TXD0), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, CAN0_RX_C, SEL_CAN0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, SDA2_D, SEL_IIC2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_9_7, MSIOF1_SCK_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_12_10, ETH_REFCLK), + PINMUX_IPSR_DATA(IP12_12_10, AVB_TXD1), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, SCIFA3_RXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, CAN1_RX_C, SEL_CAN1_2), + PINMUX_IPSR_MODSEL_DATA(IP12_12_10, MSIOF1_SYNC_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_15_13, ETH_TXD1), + PINMUX_IPSR_DATA(IP12_15_13, AVB_TXD2), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, SCIFA3_TXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, CAN1_TX_C, SEL_CAN1_2), + PINMUX_IPSR_MODSEL_DATA(IP12_15_13, MSIOF1_TXD_E, SEL_SOF1_4), + PINMUX_IPSR_DATA(IP12_17_16, ETH_TX_EN), + PINMUX_IPSR_DATA(IP12_17_16, AVB_TXD3), + PINMUX_IPSR_MODSEL_DATA(IP12_17_16, TCLK1_B, SEL_TMU1_0), + PINMUX_IPSR_MODSEL_DATA(IP12_17_16, CAN_CLK_B, SEL_CANCLK_1), + PINMUX_IPSR_DATA(IP12_19_18, ETH_MAGIC), + PINMUX_IPSR_DATA(IP12_19_18, AVB_TXD4), + PINMUX_IPSR_MODSEL_DATA(IP12_19_18, IETX_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP12_21_20, ETH_TXD0), + PINMUX_IPSR_DATA(IP12_21_20, AVB_TXD5), + PINMUX_IPSR_MODSEL_DATA(IP12_21_20, IECLK_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP12_23_22, ETH_MDC), + PINMUX_IPSR_DATA(IP12_23_22, AVB_TXD6), + PINMUX_IPSR_MODSEL_DATA(IP12_23_22, IERX_C, SEL_IEB_2), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, STP_IVCXO27_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP12_26_24, AVB_TXD7), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, SCIFB2_TXD_D, SEL_SCIFB2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, ADIDATA_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP12_26_24, MSIOF0_SYNC_C, SEL_SOF0_2), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, STP_ISCLK_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP12_29_27, AVB_TX_EN), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, SCIFB2_RXD_D, SEL_SCIFB2_3), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, ADICS_SAMP_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP12_29_27, MSIOF0_SCK_C, SEL_SOF0_2), + + /* IPSR13 */ + PINMUX_IPSR_MODSEL_DATA(IP13_2_0, STP_ISD_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP13_2_0, AVB_TX_ER), + PINMUX_IPSR_MODSEL_DATA(IP13_2_0, SCIFB2_SCK_C, SEL_SCIFB2_2), + PINMUX_IPSR_MODSEL_DATA(IP13_2_0, ADICLK_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP13_2_0, MSIOF0_SS1_C, SEL_SOF0_2), + PINMUX_IPSR_MODSEL_DATA(IP13_4_3, STP_ISEN_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP13_4_3, AVB_TX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP13_4_3, ADICHS0_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP13_4_3, MSIOF0_SS2_C, SEL_SOF0_2), + PINMUX_IPSR_MODSEL_DATA(IP13_6_5, STP_ISSYNC_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP13_6_5, AVB_COL), + PINMUX_IPSR_MODSEL_DATA(IP13_6_5, ADICHS1_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP13_6_5, MSIOF0_RXD_C, SEL_SOF0_2), + PINMUX_IPSR_MODSEL_DATA(IP13_9_7, STP_OPWM_0, SEL_SSP_0), + PINMUX_IPSR_DATA(IP13_9_7, AVB_GTX_CLK), + PINMUX_IPSR_DATA(IP13_9_7, PWM0_B), + PINMUX_IPSR_MODSEL_DATA(IP13_9_7, ADICHS2_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP13_9_7, MSIOF0_TXD_C, SEL_SOF0_2), + PINMUX_IPSR_DATA(IP13_10, SD0_CLK), + PINMUX_IPSR_MODSEL_DATA(IP13_10, SPCLK_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_11, SD0_CMD), + PINMUX_IPSR_MODSEL_DATA(IP13_11, MOSI_IO0_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_12, SD0_DATA0), + PINMUX_IPSR_MODSEL_DATA(IP13_12, MISO_IO1_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_13, SD0_DATA1), + PINMUX_IPSR_MODSEL_DATA(IP13_13, IO2_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_14, SD0_DATA2), + PINMUX_IPSR_MODSEL_DATA(IP13_14, IO3_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_15, SD0_DATA3), + PINMUX_IPSR_MODSEL_DATA(IP13_15, SSL_B, SEL_QSP_1), + PINMUX_IPSR_DATA(IP13_18_16, SD0_CD), + PINMUX_IPSR_MODSEL_DATA(IP13_18_16, MMC_D6_B, SEL_MMC_1), + PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SIM0_RST_B, SEL_SIM_1), + PINMUX_IPSR_MODSEL_DATA(IP13_18_16, CAN0_RX_F, SEL_CAN0_5), + PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SCIFA5_TXD_B, SEL_SCIFA5_1), + PINMUX_IPSR_MODSEL_DATA(IP13_18_16, TX3_C, SEL_SCIF3_2), + PINMUX_IPSR_DATA(IP13_21_19, SD0_WP), + PINMUX_IPSR_MODSEL_DATA(IP13_21_19, MMC_D7_B, SEL_MMC_1), + PINMUX_IPSR_MODSEL_DATA(IP13_21_19, SIM0_D_B, SEL_SIM_1), + PINMUX_IPSR_MODSEL_DATA(IP13_21_19, CAN0_TX_F, SEL_CAN0_5), + PINMUX_IPSR_MODSEL_DATA(IP13_21_19, SCIFA5_RXD_B, SEL_SCIFA5_1), + PINMUX_IPSR_MODSEL_DATA(IP13_21_19, RX3_C, SEL_SCIF3_2), + PINMUX_IPSR_DATA(IP13_22, SD1_CMD), + PINMUX_IPSR_MODSEL_DATA(IP13_22, REMOCON_B, SEL_RCN_1), + PINMUX_IPSR_DATA(IP13_24_23, SD1_DATA0), + PINMUX_IPSR_MODSEL_DATA(IP13_24_23, SPEEDIN_B, SEL_RSP_1), + PINMUX_IPSR_DATA(IP13_25, SD1_DATA1), + PINMUX_IPSR_MODSEL_DATA(IP13_25, IETX_B, SEL_IEB_1), + PINMUX_IPSR_DATA(IP13_26, SD1_DATA2), + PINMUX_IPSR_MODSEL_DATA(IP13_26, IECLK_B, SEL_IEB_1), + PINMUX_IPSR_DATA(IP13_27, SD1_DATA3), + PINMUX_IPSR_MODSEL_DATA(IP13_27, IERX_B, SEL_IEB_1), + PINMUX_IPSR_DATA(IP13_30_28, SD1_CD), + PINMUX_IPSR_DATA(IP13_30_28, PWM0), + PINMUX_IPSR_DATA(IP13_30_28, TPU_TO0), + PINMUX_IPSR_MODSEL_DATA(IP13_30_28, SCL1_C, SEL_IIC1_2), + + /* IPSR14 */ + PINMUX_IPSR_DATA(IP14_1_0, SD1_WP), + PINMUX_IPSR_DATA(IP14_1_0, PWM1_B), + PINMUX_IPSR_MODSEL_DATA(IP14_1_0, SDA1_C, SEL_IIC1_2), + PINMUX_IPSR_DATA(IP14_2, SD2_CLK), + PINMUX_IPSR_DATA(IP14_2, MMC_CLK), + PINMUX_IPSR_DATA(IP14_3, SD2_CMD), + PINMUX_IPSR_DATA(IP14_3, MMC_CMD), + PINMUX_IPSR_DATA(IP14_4, SD2_DATA0), + PINMUX_IPSR_DATA(IP14_4, MMC_D0), + PINMUX_IPSR_DATA(IP14_5, SD2_DATA1), + PINMUX_IPSR_DATA(IP14_5, MMC_D1), + PINMUX_IPSR_DATA(IP14_6, SD2_DATA2), + PINMUX_IPSR_DATA(IP14_6, MMC_D2), + PINMUX_IPSR_DATA(IP14_7, SD2_DATA3), + PINMUX_IPSR_DATA(IP14_7, MMC_D3), + PINMUX_IPSR_DATA(IP14_10_8, SD2_CD), + PINMUX_IPSR_DATA(IP14_10_8, MMC_D4), + PINMUX_IPSR_MODSEL_DATA(IP14_10_8, SCL8_C, SEL_IIC8_2), + PINMUX_IPSR_MODSEL_DATA(IP14_10_8, TX5_B, SEL_SCIF5_1), + PINMUX_IPSR_MODSEL_DATA(IP14_10_8, SCIFA5_TXD_C, SEL_SCIFA5_2), + PINMUX_IPSR_DATA(IP14_13_11, SD2_WP), + PINMUX_IPSR_DATA(IP14_13_11, MMC_D5), + PINMUX_IPSR_MODSEL_DATA(IP14_13_11, SDA8_C, SEL_IIC8_2), + PINMUX_IPSR_MODSEL_DATA(IP14_13_11, RX5_B, SEL_SCIF5_1), + PINMUX_IPSR_MODSEL_DATA(IP14_13_11, SCIFA5_RXD_C, SEL_SCIFA5_2), + PINMUX_IPSR_MODSEL_DATA(IP14_16_14, MSIOF0_SCK, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_16_14, RX2_C, SEL_SCIF2_2), + PINMUX_IPSR_MODSEL_DATA(IP14_16_14, ADIDATA, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_16_14, VI1_CLK_C, SEL_VI1_2), + PINMUX_IPSR_DATA(IP14_16_14, VI1_G0_B), + PINMUX_IPSR_MODSEL_DATA(IP14_19_17, MSIOF0_SYNC, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_19_17, TX2_C, SEL_SCIF2_2), + PINMUX_IPSR_MODSEL_DATA(IP14_19_17, ADICS_SAMP, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_19_17, VI1_CLKENB_C, SEL_VI1_2), + PINMUX_IPSR_DATA(IP14_19_17, VI1_G1_B), + PINMUX_IPSR_MODSEL_DATA(IP14_22_20, MSIOF0_TXD, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_22_20, ADICLK, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_22_20, VI1_FIELD_C, SEL_VI1_2), + PINMUX_IPSR_DATA(IP14_22_20, VI1_G2_B), + PINMUX_IPSR_MODSEL_DATA(IP14_25_23, MSIOF0_RXD, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_25_23, ADICHS0, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_25_23, VI1_DATA0_C, SEL_VI1_2), + PINMUX_IPSR_DATA(IP14_25_23, VI1_G3_B), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, MSIOF0_SS1, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, MMC_D6, SEL_MMC_0), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, ADICHS1, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, TX0_E, SEL_SCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, VI1_HSYNC_N_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP14_28_26, SCL7_C, SEL_IIC7_2), + PINMUX_IPSR_DATA(IP14_28_26, VI1_G4_B), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, MSIOF0_SS2, SEL_SOF0_0), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, MMC_D7, SEL_MMC_0), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, ADICHS2, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, RX0_E, SEL_SCIF0_4), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, VI1_VSYNC_N_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP14_31_29, SDA7_C, SEL_IIC7_2), + PINMUX_IPSR_DATA(IP14_31_29, VI1_G5_B), + + /* IPSR15 */ + PINMUX_IPSR_MODSEL_DATA(IP15_1_0, SIM0_RST, SEL_SIM_0), + PINMUX_IPSR_MODSEL_DATA(IP15_1_0, IETX, SEL_IEB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_1_0, CAN1_TX_D, SEL_CAN1_3), + PINMUX_IPSR_DATA(IP15_3_2, SIM0_CLK), + PINMUX_IPSR_MODSEL_DATA(IP15_3_2, IECLK, SEL_IEB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_3_2, CAN_CLK_C, SEL_CANCLK_2), + PINMUX_IPSR_MODSEL_DATA(IP15_5_4, SIM0_D, SEL_SIM_0), + PINMUX_IPSR_MODSEL_DATA(IP15_5_4, IERX, SEL_IEB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_5_4, CAN1_RX_D, SEL_CAN1_3), + PINMUX_IPSR_MODSEL_DATA(IP15_8_6, GPS_CLK, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP15_8_6, DU1_DOTCLKIN_C, SEL_DIS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_8_6, AUDIO_CLKB_B, SEL_ADG_1), + PINMUX_IPSR_DATA(IP15_8_6, PWM5_B), + PINMUX_IPSR_MODSEL_DATA(IP15_8_6, SCIFA3_TXD_C, SEL_SCIFA3_2), + PINMUX_IPSR_MODSEL_DATA(IP15_11_9, GPS_SIGN, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP15_11_9, TX4_C, SEL_SCIF4_2), + PINMUX_IPSR_MODSEL_DATA(IP15_11_9, SCIFA4_TXD_C, SEL_SCIFA4_2), + PINMUX_IPSR_DATA(IP15_11_9, PWM5), + PINMUX_IPSR_DATA(IP15_11_9, VI1_G6_B), + PINMUX_IPSR_MODSEL_DATA(IP15_11_9, SCIFA3_RXD_C, SEL_SCIFA3_2), + PINMUX_IPSR_MODSEL_DATA(IP15_14_12, GPS_MAG, SEL_GPS_0), + PINMUX_IPSR_MODSEL_DATA(IP15_14_12, RX4_C, SEL_SCIF4_2), + PINMUX_IPSR_MODSEL_DATA(IP15_14_12, SCIFA4_RXD_C, SEL_SCIFA4_2), + PINMUX_IPSR_DATA(IP15_14_12, PWM6), + PINMUX_IPSR_DATA(IP15_14_12, VI1_G7_B), + PINMUX_IPSR_MODSEL_DATA(IP15_14_12, SCIFA3_SCK_C, SEL_SCIFA3_2), + PINMUX_IPSR_MODSEL_DATA(IP15_17_15, HCTS0_N, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP15_17_15, SCIFB0_CTS_N, SEL_SCIFB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_17_15, GLO_I0_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_17_15, TCLK1, SEL_TMU1_0), + PINMUX_IPSR_MODSEL_DATA(IP15_17_15, VI1_DATA1_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP15_20_18, HRTS0_N, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP15_20_18, SCIFB0_RTS_N, SEL_SCIFB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_20_18, GLO_I1_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_20_18, VI1_DATA2_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP15_23_21, HSCK0, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP15_23_21, SCIFB0_SCK, SEL_SCIFB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_23_21, GLO_Q0_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_23_21, CAN_CLK, SEL_CANCLK_0), + PINMUX_IPSR_DATA(IP15_23_21, TCLK2), + PINMUX_IPSR_MODSEL_DATA(IP15_23_21, VI1_DATA3_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP15_26_24, HRX0, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP15_26_24, SCIFB0_RXD, SEL_SCIFB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_26_24, GLO_Q1_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_26_24, CAN0_RX_B, SEL_CAN0_1), + PINMUX_IPSR_MODSEL_DATA(IP15_26_24, VI1_DATA4_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP15_29_27, HTX0, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP15_29_27, SCIFB0_TXD, SEL_SCIFB_0), + PINMUX_IPSR_MODSEL_DATA(IP15_29_27, GLO_SCLK_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP15_29_27, CAN0_TX_B, SEL_CAN0_1), + PINMUX_IPSR_MODSEL_DATA(IP15_29_27, VI1_DATA5_C, SEL_VI1_2), + + /* IPSR16 */ + PINMUX_IPSR_MODSEL_DATA(IP16_2_0, HRX1, SEL_HSCIF1_0), + PINMUX_IPSR_MODSEL_DATA(IP16_2_0, SCIFB1_RXD, SEL_SCIFB1_0), + PINMUX_IPSR_DATA(IP16_2_0, VI1_R0_B), + PINMUX_IPSR_MODSEL_DATA(IP16_2_0, GLO_SDATA_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP16_2_0, VI1_DATA6_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP16_5_3, HTX1, SEL_HSCIF1_0), + PINMUX_IPSR_MODSEL_DATA(IP16_5_3, SCIFB1_TXD, SEL_SCIFB1_0), + PINMUX_IPSR_DATA(IP16_5_3, VI1_R1_B), + PINMUX_IPSR_MODSEL_DATA(IP16_5_3, GLO_SS_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP16_5_3, VI1_DATA7_C, SEL_VI1_2), + PINMUX_IPSR_MODSEL_DATA(IP16_7_6, HSCK1, SEL_HSCIF1_0), + PINMUX_IPSR_MODSEL_DATA(IP16_7_6, SCIFB1_SCK, SEL_SCIFB1_0), + PINMUX_IPSR_DATA(IP16_7_6, MLB_CK), + PINMUX_IPSR_MODSEL_DATA(IP16_7_6, GLO_RFON_C, SEL_GPS_2), + PINMUX_IPSR_MODSEL_DATA(IP16_9_8, HCTS1_N, SEL_HSCIF1_0), + PINMUX_IPSR_DATA(IP16_9_8, SCIFB1_CTS_N), + PINMUX_IPSR_DATA(IP16_9_8, MLB_SIG), + PINMUX_IPSR_MODSEL_DATA(IP16_9_8, CAN1_TX_B, SEL_CAN1_1), + PINMUX_IPSR_MODSEL_DATA(IP16_11_10, HRTS1_N, SEL_HSCIF1_0), + PINMUX_IPSR_DATA(IP16_11_10, SCIFB1_RTS_N), + PINMUX_IPSR_DATA(IP16_11_10, MLB_DAT), + PINMUX_IPSR_MODSEL_DATA(IP16_11_10, CAN1_RX_B, SEL_CAN1_1), +}; + +static struct pinmux_gpio pinmux_gpios[] = { + PINMUX_GPIO_GP_ALL(), + + GPIO_FN(EX_CS0_N), GPIO_FN(RD_N), GPIO_FN(AUDIO_CLKA), + GPIO_FN(VI0_CLK), GPIO_FN(VI0_DATA0_VI0_B0), + GPIO_FN(VI0_DATA0_VI0_B1), GPIO_FN(VI0_DATA0_VI0_B2), + GPIO_FN(VI0_DATA0_VI0_B4), GPIO_FN(VI0_DATA0_VI0_B5), + GPIO_FN(VI0_DATA0_VI0_B6), GPIO_FN(VI0_DATA0_VI0_B7), + GPIO_FN(USB0_PWEN), GPIO_FN(USB0_OVC), GPIO_FN(USB1_PWEN), + + /* IPSR0 - 5 */ + + /* IPSR6 */ + GPIO_FN(AUDIO_CLKB), GPIO_FN(STP_OPWM_0_B), GPIO_FN(MSIOF1_SCK_B), + GPIO_FN(SCIF_CLK), GPIO_FN(BPFCLK_E), + GPIO_FN(AUDIO_CLKC), GPIO_FN(SCIFB0_SCK_C), + GPIO_FN(MSIOF1_SYNC_B), GPIO_FN(RX2), + GPIO_FN(SCIFA2_RXD), GPIO_FN(FMIN_E), + GPIO_FN(AUDIO_CLKOUT), GPIO_FN(MSIOF1_SS1_B), + GPIO_FN(TX2), GPIO_FN(SCIFA2_TXD), + GPIO_FN(IRQ0), GPIO_FN(SCIFB1_RXD_D), GPIO_FN(INTC_IRQ0_N), + GPIO_FN(IRQ1), GPIO_FN(SCIFB1_SCK_C), GPIO_FN(INTC_IRQ1_N), + GPIO_FN(IRQ2), GPIO_FN(SCIFB1_TXD_D), GPIO_FN(INTC_IRQ2_N), + GPIO_FN(IRQ3), GPIO_FN(SCL4_C), + GPIO_FN(MSIOF2_TXD_E), GPIO_FN(INTC_IRQ3_N), + GPIO_FN(IRQ4), GPIO_FN(HRX1_C), GPIO_FN(SDA4_C), + GPIO_FN(MSIOF2_RXD_E), GPIO_FN(INTC_IRQ4_N), + GPIO_FN(IRQ5), GPIO_FN(HTX1_C), GPIO_FN(SCL1_E), GPIO_FN(MSIOF2_SCK_E), + GPIO_FN(IRQ6), GPIO_FN(HSCK1_C), GPIO_FN(MSIOF1_SS2_B), + GPIO_FN(SDA1_E), GPIO_FN(MSIOF2_SYNC_E), + GPIO_FN(IRQ7), GPIO_FN(HCTS1_N_C), GPIO_FN(MSIOF1_TXD_B), + GPIO_FN(GPS_CLK_C), GPIO_FN(GPS_CLK_D), + GPIO_FN(IRQ8), GPIO_FN(HRTS1_N_C), GPIO_FN(MSIOF1_RXD_B), + GPIO_FN(GPS_SIGN_C), GPIO_FN(GPS_SIGN_D), + + /* IPSR7 - 10 */ + + /* IPSR11 */ + GPIO_FN(VI0_R5), GPIO_FN(VI2_DATA6), GPIO_FN(GLO_SDATA_B), + GPIO_FN(RX0_C), GPIO_FN(SDA1_D), + GPIO_FN(VI0_R6), GPIO_FN(VI2_DATA7), + GPIO_FN(GLO_SS_B), GPIO_FN(TX1_C), GPIO_FN(SCL4_B), + GPIO_FN(VI0_R7), GPIO_FN(GLO_RFON_B), + GPIO_FN(RX1_C), GPIO_FN(CAN0_RX_E), + GPIO_FN(SDA4_B), GPIO_FN(HRX1_D), GPIO_FN(SCIFB0_RXD_D), + GPIO_FN(VI1_HSYNC_N), GPIO_FN(AVB_RXD0), GPIO_FN(TS_SDATA0_B), + GPIO_FN(TX4_B), GPIO_FN(SCIFA4_TXD_B), + GPIO_FN(VI1_VSYNC_N), GPIO_FN(AVB_RXD1), GPIO_FN(TS_SCK0_B), + GPIO_FN(RX4_B), GPIO_FN(SCIFA4_RXD_B), + GPIO_FN(VI1_CLKENB), GPIO_FN(AVB_RXD2), GPIO_FN(TS_SDEN0_B), + GPIO_FN(VI1_FIELD), GPIO_FN(AVB_RXD3), GPIO_FN(TS_SPSYNC0_B), + GPIO_FN(VI1_CLK), GPIO_FN(AVB_RXD4), + GPIO_FN(VI1_DATA0), GPIO_FN(AVB_RXD5), + GPIO_FN(VI1_DATA1), GPIO_FN(AVB_RXD6), + GPIO_FN(VI1_DATA2), GPIO_FN(AVB_RXD7), + GPIO_FN(VI1_DATA3), GPIO_FN(AVB_RX_ER), + GPIO_FN(VI1_DATA4), GPIO_FN(AVB_MDIO), + GPIO_FN(VI1_DATA5), GPIO_FN(AVB_RX_DV), + GPIO_FN(VI1_DATA6), GPIO_FN(AVB_MAGIC), + GPIO_FN(VI1_DATA7), GPIO_FN(AVB_MDC), + GPIO_FN(ETH_MDIO), GPIO_FN(AVB_RX_CLK), GPIO_FN(SCL2_C), + GPIO_FN(ETH_CRS_DV), GPIO_FN(AVB_LINK), GPIO_FN(SDA2_C), + + /* IPSR12 */ + GPIO_FN(ETH_RX_ER), GPIO_FN(AVB_CRS), GPIO_FN(SCL3), GPIO_FN(SCL7), + GPIO_FN(ETH_RXD0), GPIO_FN(AVB_PHY_INT), GPIO_FN(SDA3), GPIO_FN(SDA7), + GPIO_FN(ETH_RXD1), GPIO_FN(AVB_GTXREFCLK), GPIO_FN(CAN0_TX_C), + GPIO_FN(SCL2_D), GPIO_FN(MSIOF1_RXD_E), + GPIO_FN(ETH_LINK), GPIO_FN(AVB_TXD0), GPIO_FN(CAN0_RX_C), + GPIO_FN(SDA2_D), GPIO_FN(MSIOF1_SCK_E), + GPIO_FN(ETH_REFCLK), GPIO_FN(AVB_TXD1), GPIO_FN(SCIFA3_RXD_B), + GPIO_FN(CAN1_RX_C), GPIO_FN(MSIOF1_SYNC_E), + GPIO_FN(ETH_TXD1), GPIO_FN(AVB_TXD2), GPIO_FN(SCIFA3_TXD_B), + GPIO_FN(CAN1_TX_C), GPIO_FN(MSIOF1_TXD_E), + GPIO_FN(ETH_TX_EN), GPIO_FN(AVB_TXD3), + GPIO_FN(TCLK1_B), GPIO_FN(CAN_CLK_B), + GPIO_FN(ETH_MAGIC), GPIO_FN(AVB_TXD4), GPIO_FN(IETX_C), + GPIO_FN(ETH_TXD0), GPIO_FN(AVB_TXD5), GPIO_FN(IECLK_C), + GPIO_FN(ETH_MDC), GPIO_FN(AVB_TXD6), GPIO_FN(IERX_C), + GPIO_FN(STP_IVCXO27_0), GPIO_FN(AVB_TXD7), GPIO_FN(SCIFB2_TXD_D), + GPIO_FN(ADIDATA_B), GPIO_FN(MSIOF0_SYNC_C), + GPIO_FN(STP_ISCLK_0), GPIO_FN(AVB_TX_EN), GPIO_FN(SCIFB2_RXD_D), + GPIO_FN(ADICS_SAMP_B), GPIO_FN(MSIOF0_SCK_C), + + /* IPSR13 */ + GPIO_FN(STP_ISD_0), GPIO_FN(AVB_TX_ER), GPIO_FN(SCIFB2_SCK_C), + GPIO_FN(ADICLK_B), GPIO_FN(MSIOF0_SS1_C), + GPIO_FN(STP_ISEN_0), GPIO_FN(AVB_TX_CLK), + GPIO_FN(ADICHS0_B), GPIO_FN(MSIOF0_SS2_C), + GPIO_FN(STP_ISSYNC_0), GPIO_FN(AVB_COL), + GPIO_FN(ADICHS1_B), GPIO_FN(MSIOF0_RXD_C), + GPIO_FN(STP_OPWM_0), GPIO_FN(AVB_GTX_CLK), GPIO_FN(PWM0_B), + GPIO_FN(ADICHS2_B), GPIO_FN(MSIOF0_TXD_C), + GPIO_FN(SD0_CLK), GPIO_FN(SPCLK_B), + GPIO_FN(SD0_CMD), GPIO_FN(MOSI_IO0_B), + GPIO_FN(SD0_DATA0), GPIO_FN(MISO_IO1_B), + GPIO_FN(SD0_DATA1), GPIO_FN(IO2_B), + GPIO_FN(SD0_DATA2), GPIO_FN(IO3_B), GPIO_FN(SD0_DATA3), GPIO_FN(SSL_B), + GPIO_FN(SD0_CD), GPIO_FN(MMC_D6_B), + GPIO_FN(SIM0_RST_B), GPIO_FN(CAN0_RX_F), + GPIO_FN(SCIFA5_TXD_B), GPIO_FN(TX3_C), + GPIO_FN(SD0_WP), GPIO_FN(MMC_D7_B), + GPIO_FN(SIM0_D_B), GPIO_FN(CAN0_TX_F), + GPIO_FN(SCIFA5_RXD_B), GPIO_FN(RX3_C), + GPIO_FN(SD1_CMD), GPIO_FN(REMOCON_B), + GPIO_FN(SD1_DATA0), GPIO_FN(SPEEDIN_B), + GPIO_FN(SD1_DATA1), GPIO_FN(IETX_B), + GPIO_FN(SD1_DATA2), GPIO_FN(IECLK_B), + GPIO_FN(SD1_DATA3), GPIO_FN(IERX_B), + GPIO_FN(SD1_CD), GPIO_FN(PWM0), GPIO_FN(TPU_TO0), GPIO_FN(SCL1_C), + + /* IPSR14 */ + GPIO_FN(SD1_WP), GPIO_FN(PWM1_B), GPIO_FN(SDA1_C), + GPIO_FN(SD2_CLK), GPIO_FN(MMC_CLK), GPIO_FN(SD2_CMD), GPIO_FN(MMC_CMD), + GPIO_FN(SD2_DATA0), GPIO_FN(MMC_D0), + GPIO_FN(SD2_DATA1), GPIO_FN(MMC_D1), + GPIO_FN(SD2_DATA2), GPIO_FN(MMC_D2), + GPIO_FN(SD2_DATA3), GPIO_FN(MMC_D3), + GPIO_FN(SD2_CD), GPIO_FN(MMC_D4), GPIO_FN(SCL8_C), + GPIO_FN(TX5_B), GPIO_FN(SCIFA5_TXD_C), + GPIO_FN(SD2_WP), GPIO_FN(MMC_D5), GPIO_FN(SDA8_C), + GPIO_FN(RX5_B), GPIO_FN(SCIFA5_RXD_C), + GPIO_FN(MSIOF0_SCK), GPIO_FN(RX2_C), GPIO_FN(ADIDATA), + GPIO_FN(VI1_CLK_C), GPIO_FN(VI1_G0_B), + GPIO_FN(MSIOF0_SYNC), GPIO_FN(TX2_C), GPIO_FN(ADICS_SAMP), + GPIO_FN(VI1_CLKENB_C), GPIO_FN(VI1_G1_B), + GPIO_FN(MSIOF0_TXD), GPIO_FN(ADICLK), + GPIO_FN(VI1_FIELD_C), GPIO_FN(VI1_G2_B), + GPIO_FN(MSIOF0_RXD), GPIO_FN(ADICHS0), + GPIO_FN(VI1_DATA0_C), GPIO_FN(VI1_G3_B), + GPIO_FN(MSIOF0_SS1), GPIO_FN(MMC_D6), GPIO_FN(ADICHS1), GPIO_FN(TX0_E), + GPIO_FN(VI1_HSYNC_N_C), GPIO_FN(SCL7_C), GPIO_FN(VI1_G4_B), + GPIO_FN(MSIOF0_SS2), GPIO_FN(MMC_D7), GPIO_FN(ADICHS2), GPIO_FN(RX0_E), + GPIO_FN(VI1_VSYNC_N_C), GPIO_FN(SDA7_C), GPIO_FN(VI1_G5_B), + + /* IPSR15 */ + GPIO_FN(SIM0_RST), GPIO_FN(IETX), GPIO_FN(CAN1_TX_D), + GPIO_FN(SIM0_CLK), GPIO_FN(IECLK), GPIO_FN(CAN_CLK_C), + GPIO_FN(SIM0_D), GPIO_FN(IERX), GPIO_FN(CAN1_RX_D), + GPIO_FN(GPS_CLK), GPIO_FN(DU1_DOTCLKIN_C), GPIO_FN(AUDIO_CLKB_B), + GPIO_FN(PWM5_B), GPIO_FN(SCIFA3_TXD_C), + GPIO_FN(GPS_SIGN), GPIO_FN(TX4_C), + GPIO_FN(SCIFA4_TXD_C), GPIO_FN(PWM5), + GPIO_FN(VI1_G6_B), GPIO_FN(SCIFA3_RXD_C), + GPIO_FN(GPS_MAG), GPIO_FN(RX4_C), GPIO_FN(SCIFA4_RXD_C), GPIO_FN(PWM6), + GPIO_FN(VI1_G7_B), GPIO_FN(SCIFA3_SCK_C), + GPIO_FN(HCTS0_N), GPIO_FN(SCIFB0_CTS_N), GPIO_FN(GLO_I0_C), + GPIO_FN(TCLK1), GPIO_FN(VI1_DATA1_C), + GPIO_FN(HRTS0_N), GPIO_FN(SCIFB0_RTS_N), + GPIO_FN(GLO_I1_C), GPIO_FN(VI1_DATA2_C), + GPIO_FN(HSCK0), GPIO_FN(SCIFB0_SCK), + GPIO_FN(GLO_Q0_C), GPIO_FN(CAN_CLK), + GPIO_FN(TCLK2), GPIO_FN(VI1_DATA3_C), + GPIO_FN(HRX0), GPIO_FN(SCIFB0_RXD), GPIO_FN(GLO_Q1_C), + GPIO_FN(CAN0_RX_B), GPIO_FN(VI1_DATA4_C), + GPIO_FN(HTX0), GPIO_FN(SCIFB0_TXD), GPIO_FN(GLO_SCLK_C), + GPIO_FN(CAN0_TX_B), GPIO_FN(VI1_DATA5_C), + + /* IPSR16 */ + GPIO_FN(HRX1), GPIO_FN(SCIFB1_RXD), GPIO_FN(VI1_R0_B), + GPIO_FN(GLO_SDATA_C), GPIO_FN(VI1_DATA6_C), + GPIO_FN(HTX1), GPIO_FN(SCIFB1_TXD), GPIO_FN(VI1_R1_B), + GPIO_FN(GLO_SS_C), GPIO_FN(VI1_DATA7_C), + GPIO_FN(HSCK1), GPIO_FN(SCIFB1_SCK), + GPIO_FN(MLB_CK), GPIO_FN(GLO_RFON_C), + GPIO_FN(HCTS1_N), GPIO_FN(SCIFB1_CTS_N), + GPIO_FN(MLB_SIG), GPIO_FN(CAN1_TX_B), + GPIO_FN(HRTS1_N), GPIO_FN(SCIFB1_RTS_N), + GPIO_FN(MLB_DAT), GPIO_FN(CAN1_RX_B), +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + { PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) { + GP_0_31_FN, FN_IP1_22_20, + GP_0_30_FN, FN_IP1_19_17, + GP_0_29_FN, FN_IP1_16_14, + GP_0_28_FN, FN_IP1_13_11, + GP_0_27_FN, FN_IP1_10_8, + GP_0_26_FN, FN_IP1_7_6, + GP_0_25_FN, FN_IP1_5_4, + GP_0_24_FN, FN_IP1_3_2, + GP_0_23_FN, FN_IP1_1_0, + GP_0_22_FN, FN_IP0_30_29, + GP_0_21_FN, FN_IP0_28_27, + GP_0_20_FN, FN_IP0_26_25, + GP_0_19_FN, FN_IP0_24_23, + GP_0_18_FN, FN_IP0_22_21, + GP_0_17_FN, FN_IP0_20_19, + GP_0_16_FN, FN_IP0_18_16, + GP_0_15_FN, FN_IP0_15, + GP_0_14_FN, FN_IP0_14, + GP_0_13_FN, FN_IP0_13, + GP_0_12_FN, FN_IP0_12, + GP_0_11_FN, FN_IP0_11, + GP_0_10_FN, FN_IP0_10, + GP_0_9_FN, FN_IP0_9, + GP_0_8_FN, FN_IP0_8, + GP_0_7_FN, FN_IP0_7, + GP_0_6_FN, FN_IP0_6, + GP_0_5_FN, FN_IP0_5, + GP_0_4_FN, FN_IP0_4, + GP_0_3_FN, FN_IP0_3, + GP_0_2_FN, FN_IP0_2, + GP_0_1_FN, FN_IP0_1, + GP_0_0_FN, FN_IP0_0, } + }, + { PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_FN, FN_IP3_21_20, + GP_1_24_FN, FN_IP3_19_18, + GP_1_23_FN, FN_IP3_17_16, + GP_1_22_FN, FN_IP3_15_14, + GP_1_21_FN, FN_IP3_13_12, + GP_1_20_FN, FN_IP3_11_9, + GP_1_19_FN, FN_RD_N, + GP_1_18_FN, FN_IP3_8_6, + GP_1_17_FN, FN_IP3_5_3, + GP_1_16_FN, FN_IP3_2_0, + GP_1_15_FN, FN_IP2_29_27, + GP_1_14_FN, FN_IP2_26_25, + GP_1_13_FN, FN_IP2_24_23, + GP_1_12_FN, FN_EX_CS0_N, + GP_1_11_FN, FN_IP2_22_21, + GP_1_10_FN, FN_IP2_20_19, + GP_1_9_FN, FN_IP2_18_16, + GP_1_8_FN, FN_IP2_15_13, + GP_1_7_FN, FN_IP2_12_10, + GP_1_6_FN, FN_IP2_9_7, + GP_1_5_FN, FN_IP2_6_5, + GP_1_4_FN, FN_IP2_4_3, + GP_1_3_FN, FN_IP2_2_0, + GP_1_2_FN, FN_IP1_31_29, + GP_1_1_FN, FN_IP1_28_26, + GP_1_0_FN, FN_IP1_25_23, } + }, + { PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) { + GP_2_31_FN, FN_IP6_7_6, + GP_2_30_FN, FN_IP6_5_3, + GP_2_29_FN, FN_IP6_2_0, + GP_2_28_FN, FN_AUDIO_CLKA, + GP_2_27_FN, FN_IP5_31_29, + GP_2_26_FN, FN_IP5_28_26, + GP_2_25_FN, FN_IP5_25_24, + GP_2_24_FN, FN_IP5_23_22, + GP_2_23_FN, FN_IP5_21_20, + GP_2_22_FN, FN_IP5_19_17, + GP_2_21_FN, FN_IP5_16_15, + GP_2_20_FN, FN_IP5_14_12, + GP_2_19_FN, FN_IP5_11_9, + GP_2_18_FN, FN_IP5_8_6, + GP_2_17_FN, FN_IP5_5_3, + GP_2_16_FN, FN_IP5_2_0, + GP_2_15_FN, FN_IP4_30_28, + GP_2_14_FN, FN_IP4_27_26, + GP_2_13_FN, FN_IP4_25_24, + GP_2_12_FN, FN_IP4_23_22, + GP_2_11_FN, FN_IP4_21, + GP_2_10_FN, FN_IP4_20, + GP_2_9_FN, FN_IP4_19, + GP_2_8_FN, FN_IP4_18_16, + GP_2_7_FN, FN_IP4_15_13, + GP_2_6_FN, FN_IP4_12_10, + GP_2_5_FN, FN_IP4_9_8, + GP_2_4_FN, FN_IP4_7_5, + GP_2_3_FN, FN_IP4_4_2, + GP_2_2_FN, FN_IP4_1_0, + GP_2_1_FN, FN_IP3_30_28, + GP_2_0_FN, FN_IP3_27_25 } + }, + { PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) { + GP_3_31_FN, FN_IP9_18_17, + GP_3_30_FN, FN_IP9_16, + GP_3_29_FN, FN_IP9_15_13, + GP_3_28_FN, FN_IP9_12, + GP_3_27_FN, FN_IP9_11, + GP_3_26_FN, FN_IP9_10_8, + GP_3_25_FN, FN_IP9_7, + GP_3_24_FN, FN_IP9_6, + GP_3_23_FN, FN_IP9_5_3, + GP_3_22_FN, FN_IP9_2_0, + GP_3_21_FN, FN_IP8_30_28, + GP_3_20_FN, FN_IP8_27_26, + GP_3_19_FN, FN_IP8_25_24, + GP_3_18_FN, FN_IP8_23_21, + GP_3_17_FN, FN_IP8_20_18, + GP_3_16_FN, FN_IP8_17_15, + GP_3_15_FN, FN_IP8_14_12, + GP_3_14_FN, FN_IP8_11_9, + GP_3_13_FN, FN_IP8_8_6, + GP_3_12_FN, FN_IP8_5_3, + GP_3_11_FN, FN_IP8_2_0, + GP_3_10_FN, FN_IP7_29_27, + GP_3_9_FN, FN_IP7_26_24, + GP_3_8_FN, FN_IP7_23_21, + GP_3_7_FN, FN_IP7_20_19, + GP_3_6_FN, FN_IP7_18_17, + GP_3_5_FN, FN_IP7_16_15, + GP_3_4_FN, FN_IP7_14_13, + GP_3_3_FN, FN_IP7_12_11, + GP_3_2_FN, FN_IP7_10_9, + GP_3_1_FN, FN_IP7_8_6, + GP_3_0_FN, FN_IP7_5_3 } + }, + { PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) { + GP_4_31_FN, FN_IP15_5_4, + GP_4_30_FN, FN_IP15_3_2, + GP_4_29_FN, FN_IP15_1_0, + GP_4_28_FN, FN_IP11_8_6, + GP_4_27_FN, FN_IP11_5_3, + GP_4_26_FN, FN_IP11_2_0, + GP_4_25_FN, FN_IP10_31_29, + GP_4_24_FN, FN_IP10_28_27, + GP_4_23_FN, FN_IP10_26_25, + GP_4_22_FN, FN_IP10_24_22, + GP_4_21_FN, FN_IP10_21_19, + GP_4_20_FN, FN_IP10_18_17, + GP_4_19_FN, FN_IP10_16_15, + GP_4_18_FN, FN_IP10_14_12, + GP_4_17_FN, FN_IP10_11_9, + GP_4_16_FN, FN_IP10_8_6, + GP_4_15_FN, FN_IP10_5_3, + GP_4_14_FN, FN_IP10_2_0, + GP_4_13_FN, FN_IP9_31_29, + GP_4_12_FN, FN_VI0_DATA0_VI0_B7, + GP_4_11_FN, FN_VI0_DATA0_VI0_B6, + GP_4_10_FN, FN_VI0_DATA0_VI0_B5, + GP_4_9_FN, FN_VI0_DATA0_VI0_B4, + GP_4_8_FN, FN_IP9_28_27, + GP_4_7_FN, FN_VI0_DATA0_VI0_B2, + GP_4_6_FN, FN_VI0_DATA0_VI0_B1, + GP_4_5_FN, FN_VI0_DATA0_VI0_B0, + GP_4_4_FN, FN_IP9_26_25, + GP_4_3_FN, FN_IP9_24_23, + GP_4_2_FN, FN_IP9_22_21, + GP_4_1_FN, FN_IP9_20_19, + GP_4_0_FN, FN_VI0_CLK } + }, + { PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) { + GP_5_31_FN, FN_IP3_24_22, + GP_5_30_FN, FN_IP13_9_7, + GP_5_29_FN, FN_IP13_6_5, + GP_5_28_FN, FN_IP13_4_3, + GP_5_27_FN, FN_IP13_2_0, + GP_5_26_FN, FN_IP12_29_27, + GP_5_25_FN, FN_IP12_26_24, + GP_5_24_FN, FN_IP12_23_22, + GP_5_23_FN, FN_IP12_21_20, + GP_5_22_FN, FN_IP12_19_18, + GP_5_21_FN, FN_IP12_17_16, + GP_5_20_FN, FN_IP12_15_13, + GP_5_19_FN, FN_IP12_12_10, + GP_5_18_FN, FN_IP12_9_7, + GP_5_17_FN, FN_IP12_6_4, + GP_5_16_FN, FN_IP12_3_2, + GP_5_15_FN, FN_IP12_1_0, + GP_5_14_FN, FN_IP11_31_30, + GP_5_13_FN, FN_IP11_29_28, + GP_5_12_FN, FN_IP11_27, + GP_5_11_FN, FN_IP11_26, + GP_5_10_FN, FN_IP11_25, + GP_5_9_FN, FN_IP11_24, + GP_5_8_FN, FN_IP11_23, + GP_5_7_FN, FN_IP11_22, + GP_5_6_FN, FN_IP11_21, + GP_5_5_FN, FN_IP11_20, + GP_5_4_FN, FN_IP11_19, + GP_5_3_FN, FN_IP11_18_17, + GP_5_2_FN, FN_IP11_16_15, + GP_5_1_FN, FN_IP11_14_12, + GP_5_0_FN, FN_IP11_11_9 } + }, + { PINMUX_CFG_REG("GPSR6", 0xE606001C, 32, 1) { + 0, 0, + 0, 0, + GP_6_29_FN, FN_IP14_31_29, + GP_6_28_FN, FN_IP14_28_26, + GP_6_27_FN, FN_IP14_25_23, + GP_6_26_FN, FN_IP14_22_20, + GP_6_25_FN, FN_IP14_19_17, + GP_6_24_FN, FN_IP14_16_14, + GP_6_23_FN, FN_IP14_13_11, + GP_6_22_FN, FN_IP14_10_8, + GP_6_21_FN, FN_IP14_7, + GP_6_20_FN, FN_IP14_6, + GP_6_19_FN, FN_IP14_5, + GP_6_18_FN, FN_IP14_4, + GP_6_17_FN, FN_IP14_3, + GP_6_16_FN, FN_IP14_2, + GP_6_15_FN, FN_IP14_1_0, + GP_6_14_FN, FN_IP13_30_28, + GP_6_13_FN, FN_IP13_27, + GP_6_12_FN, FN_IP13_26, + GP_6_11_FN, FN_IP13_25, + GP_6_10_FN, FN_IP13_24_23, + GP_6_9_FN, FN_IP13_22, + 0, 0, + GP_6_7_FN, FN_IP13_21_19, + GP_6_6_FN, FN_IP13_18_16, + GP_6_5_FN, FN_IP13_15, + GP_6_4_FN, FN_IP13_14, + GP_6_3_FN, FN_IP13_13, + GP_6_2_FN, FN_IP13_12, + GP_6_1_FN, FN_IP13_11, + GP_6_0_FN, FN_IP13_10 } + }, + { PINMUX_CFG_REG("GPSR7", 0xE6060074, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_7_25_FN, FN_USB1_PWEN, + GP_7_24_FN, FN_USB0_OVC, + GP_7_23_FN, FN_USB0_PWEN, + GP_7_22_FN, FN_IP15_14_12, + GP_7_21_FN, FN_IP15_11_9, + GP_7_20_FN, FN_IP15_8_6, + GP_7_19_FN, FN_IP7_2_0, + GP_7_18_FN, FN_IP6_29_27, + GP_7_17_FN, FN_IP6_26_24, + GP_7_16_FN, FN_IP6_23_21, + GP_7_15_FN, FN_IP6_20_19, + GP_7_14_FN, FN_IP6_18_16, + GP_7_13_FN, FN_IP6_15_14, + GP_7_12_FN, FN_IP6_13_12, + GP_7_11_FN, FN_IP6_11_10, + GP_7_10_FN, FN_IP6_9_8, + GP_7_9_FN, FN_IP16_11_10, + GP_7_8_FN, FN_IP16_9_8, + GP_7_7_FN, FN_IP16_7_6, + GP_7_6_FN, FN_IP16_5_3, + GP_7_5_FN, FN_IP16_2_0, + GP_7_4_FN, FN_IP15_29_27, + GP_7_3_FN, FN_IP15_26_24, + GP_7_2_FN, FN_IP15_23_21, + GP_7_1_FN, FN_IP15_20_18, + GP_7_0_FN, FN_IP15_17_15 } + }, + + /* IPSR0 - 5 */ + + { PINMUX_CFG_REG_VAR("IPSR6", 0xE6060038, 32, + 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 2, 3, 3) { + /* IP6_31_30 [2] */ + 0, 0, 0, 0, + /* IP6_29_27 [3] */ + FN_IRQ8, FN_HRTS1_N_C, FN_MSIOF1_RXD_B, + FN_GPS_SIGN_C, FN_GPS_SIGN_D, + 0, 0, 0, + /* IP6_26_24 [3] */ + FN_IRQ7, FN_HCTS1_N_C, FN_MSIOF1_TXD_B, + FN_GPS_CLK_C, FN_GPS_CLK_D, + 0, 0, 0, + /* IP6_23_21 [3] */ + FN_IRQ6, FN_HSCK1_C, FN_MSIOF1_SS2_B, + FN_SDA1_E, FN_MSIOF2_SYNC_E, + 0, 0, 0, + /* IP6_20_19 [2] */ + FN_IRQ5, FN_HTX1_C, FN_SCL1_E, FN_MSIOF2_SCK_E, + /* IP6_18_16 [3] */ + FN_IRQ4, FN_HRX1_C, FN_SDA4_C, FN_MSIOF2_RXD_E, FN_INTC_IRQ4_N, + 0, 0, 0, + /* IP6_15_14 [2] */ + FN_IRQ3, FN_SCL4_C, FN_MSIOF2_TXD_E, FN_INTC_IRQ3_N, + /* IP6_13_12 [2] */ + FN_IRQ2, FN_SCIFB1_TXD_D, FN_INTC_IRQ2_N, 0, + /* IP6_11_10 [2] */ + FN_IRQ1, FN_SCIFB1_SCK_C, FN_INTC_IRQ1_N, 0, + /* IP6_9_8 [2] */ + FN_IRQ0, FN_SCIFB1_RXD_D, FN_INTC_IRQ0_N, 0, + /* IP6_7_6 [2] */ + FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD, + /* IP6_5_3 [3] */ + FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2, + FN_SCIFA2_RXD, FN_FMIN_E, + 0, 0, + /* IP6_2_0 [3] */ + FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B, + FN_SCIF_CLK, 0, FN_BPFCLK_E, + 0, 0, } + }, + + /* IPSR7 - 10 */ + + { PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32, + 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 3, 3, 3, 3, 3) { + /* IP11_31_30 [2] */ + FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, 0, + /* IP11_29_28 [2] */ + FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, 0, + /* IP11_27 [1] */ + FN_VI1_DATA7, FN_AVB_MDC, + /* IP11_26 [1] */ + FN_VI1_DATA6, FN_AVB_MAGIC, + /* IP11_25 [1] */ + FN_VI1_DATA5, FN_AVB_RX_DV, + /* IP11_24 [1] */ + FN_VI1_DATA4, FN_AVB_MDIO, + /* IP11_23 [1] */ + FN_VI1_DATA3, FN_AVB_RX_ER, + /* IP11_22 [1] */ + FN_VI1_DATA2, FN_AVB_RXD7, + /* IP11_21 [1] */ + FN_VI1_DATA1, FN_AVB_RXD6, + /* IP11_20 [1] */ + FN_VI1_DATA0, FN_AVB_RXD5, + /* IP11_19 [1] */ + FN_VI1_CLK, FN_AVB_RXD4, + /* IP11_18_17 [2] */ + FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, 0, + /* IP11_16_15 [2] */ + FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, 0, + /* IP11_14_12 [3] */ + FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, + FN_RX4_B, FN_SCIFA4_RXD_B, + 0, 0, 0, + /* IP11_11_9 [3] */ + FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, + FN_TX4_B, FN_SCIFA4_TXD_B, + 0, 0, 0, + /* IP11_8_6 [3] */ + FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, + FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, 0, + /* IP11_5_3 [3] */ + FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, + 0, 0, 0, + /* IP11_2_0 [3] */ + FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, + 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR12", 0xE6060050, 32, + 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2) { + /* IP12_31_30 [2] */ + 0, 0, 0, 0, + /* IP12_29_27 [3] */ + FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, + FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, + 0, 0, 0, + /* IP12_26_24 [3] */ + FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, + FN_ADIDATA_B, FN_MSIOF0_SYNC_C, + 0, 0, 0, + /* IP12_23_22 [2] */ + FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, 0, + /* IP12_21_20 [2] */ + FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, 0, + /* IP12_19_18 [2] */ + FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, 0, + /* IP12_17_16 [2] */ + FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, + /* IP12_15_13 [3] */ + FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, + FN_CAN1_TX_C, FN_MSIOF1_TXD_E, + 0, 0, 0, + /* IP12_12_10 [3] */ + FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, + FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, + 0, 0, 0, + /* IP12_9_7 [3] */ + FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, + FN_SDA2_D, FN_MSIOF1_SCK_E, + 0, 0, 0, + /* IP12_6_4 [3] */ + FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, + FN_SCL2_D, FN_MSIOF1_RXD_E, + 0, 0, 0, + /* IP12_3_2 [2] */ + FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, + /* IP12_1_0 [2] */ + FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, } + }, + { PINMUX_CFG_REG_VAR("IPSR13", 0xE6060054, 32, + 1, 3, 1, 1, 1, 2, 1, 3, 3, 1, 1, 1, 1, 1, 1, + 3, 2, 2, 3) { + /* IP13_31 [1] */ + 0, 0, + /* IP13_30_28 [3] */ + FN_SD1_CD, FN_PWM0, FN_TPU_TO0, FN_SCL1_C, + 0, 0, 0, 0, + /* IP13_27 [1] */ + FN_SD1_DATA3, FN_IERX_B, + /* IP13_26 [1] */ + FN_SD1_DATA2, FN_IECLK_B, + /* IP13_25 [1] */ + FN_SD1_DATA1, FN_IETX_B, + /* IP13_24_23 [2] */ + FN_SD1_DATA0, FN_SPEEDIN_B, 0, 0, + /* IP13_22 [1] */ + FN_SD1_CMD, FN_REMOCON_B, + /* IP13_21_19 [3] */ + FN_SD0_WP, FN_MMC_D7_B, FN_SIM0_D_B, FN_CAN0_TX_F, + FN_SCIFA5_RXD_B, FN_RX3_C, + 0, 0, + /* IP13_18_16 [3] */ + FN_SD0_CD, FN_MMC_D6_B, FN_SIM0_RST_B, FN_CAN0_RX_F, + FN_SCIFA5_TXD_B, FN_TX3_C, + 0, 0, + /* IP13_15 [1] */ + FN_SD0_DATA3, FN_SSL_B, + /* IP13_14 [1] */ + FN_SD0_DATA2, FN_IO3_B, + /* IP13_13 [1] */ + FN_SD0_DATA1, FN_IO2_B, + /* IP13_12 [1] */ + FN_SD0_DATA0, FN_MISO_IO1_B, + /* IP13_11 [1] */ + FN_SD0_CMD, FN_MOSI_IO0_B, + /* IP13_10 [1] */ + FN_SD0_CLK, FN_SPCLK_B, + /* IP13_9_7 [3] */ + FN_STP_OPWM_0, FN_AVB_GTX_CLK, FN_PWM0_B, + FN_ADICHS2_B, FN_MSIOF0_TXD_C, + 0, 0, 0, + /* IP13_6_5 [2] */ + FN_STP_ISSYNC_0, FN_AVB_COL, FN_ADICHS1_B, FN_MSIOF0_RXD_C, + /* IP13_4_3 [2] */ + FN_STP_ISEN_0, FN_AVB_TX_CLK, FN_ADICHS0_B, FN_MSIOF0_SS2_C, + /* IP13_2_0 [3] */ + FN_STP_ISD_0, FN_AVB_TX_ER, FN_SCIFB2_SCK_C, + FN_ADICLK_B, FN_MSIOF0_SS1_C, + 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR14", 0xE6060058, 32, + 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2) { + /* IP14_31_29 [3] */ + FN_MSIOF0_SS2, FN_MMC_D7, FN_ADICHS2, FN_RX0_E, + FN_VI1_VSYNC_N_C, FN_SDA7_C, FN_VI1_G5_B, 0, + /* IP14_28_26 [3] */ + FN_MSIOF0_SS1, FN_MMC_D6, FN_ADICHS1, FN_TX0_E, + FN_VI1_HSYNC_N_C, FN_SCL7_C, FN_VI1_G4_B, 0, + /* IP14_25_23 [3] */ + FN_MSIOF0_RXD, FN_ADICHS0, 0, FN_VI1_DATA0_C, FN_VI1_G3_B, + 0, 0, 0, + /* IP14_22_20 [3] */ + FN_MSIOF0_TXD, FN_ADICLK, 0, FN_VI1_FIELD_C, FN_VI1_G2_B, + 0, 0, 0, + /* IP14_19_17 [3] */ + FN_MSIOF0_SYNC, FN_TX2_C, FN_ADICS_SAMP, 0, + FN_VI1_CLKENB_C, FN_VI1_G1_B, + 0, 0, + /* IP14_16_14 [3] */ + FN_MSIOF0_SCK, FN_RX2_C, FN_ADIDATA, 0, + FN_VI1_CLK_C, FN_VI1_G0_B, + 0, 0, + /* IP14_13_11 [3] */ + FN_SD2_WP, FN_MMC_D5, FN_SDA8_C, FN_RX5_B, FN_SCIFA5_RXD_C, + 0, 0, 0, + /* IP14_10_8 [3] */ + FN_SD2_CD, FN_MMC_D4, FN_SCL8_C, FN_TX5_B, FN_SCIFA5_TXD_C, + 0, 0, 0, + /* IP14_7 [1] */ + FN_SD2_DATA3, FN_MMC_D3, + /* IP14_6 [1] */ + FN_SD2_DATA2, FN_MMC_D2, + /* IP14_5 [1] */ + FN_SD2_DATA1, FN_MMC_D1, + /* IP14_4 [1] */ + FN_SD2_DATA0, FN_MMC_D0, + /* IP14_3 [1] */ + FN_SD2_CMD, FN_MMC_CMD, + /* IP14_2 [1] */ + FN_SD2_CLK, FN_MMC_CLK, + /* IP14_1_0 [2] */ + FN_SD1_WP, FN_PWM1_B, FN_SDA1_C, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR15", 0xE606005C, 32, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2) { + /* IP15_31_30 [2] */ + 0, 0, 0, 0, + /* IP15_29_27 [3] */ + FN_HTX0, FN_SCIFB0_TXD, 0, FN_GLO_SCLK_C, + FN_CAN0_TX_B, FN_VI1_DATA5_C, + 0, 0, + /* IP15_26_24 [3] */ + FN_HRX0, FN_SCIFB0_RXD, 0, FN_GLO_Q1_C, + FN_CAN0_RX_B, FN_VI1_DATA4_C, + 0, 0, + /* IP15_23_21 [3] */ + FN_HSCK0, FN_SCIFB0_SCK, 0, FN_GLO_Q0_C, FN_CAN_CLK, + FN_TCLK2, FN_VI1_DATA3_C, 0, + /* IP15_20_18 [3] */ + FN_HRTS0_N, FN_SCIFB0_RTS_N, 0, FN_GLO_I1_C, FN_VI1_DATA2_C, + 0, 0, 0, + /* IP15_17_15 [3] */ + FN_HCTS0_N, FN_SCIFB0_CTS_N, 0, FN_GLO_I0_C, + FN_TCLK1, FN_VI1_DATA1_C, + 0, 0, + /* IP15_14_12 [3] */ + FN_GPS_MAG, FN_RX4_C, FN_SCIFA4_RXD_C, FN_PWM6, + FN_VI1_G7_B, FN_SCIFA3_SCK_C, + 0, 0, + /* IP15_11_9 [3] */ + FN_GPS_SIGN, FN_TX4_C, FN_SCIFA4_TXD_C, FN_PWM5, + FN_VI1_G6_B, FN_SCIFA3_RXD_C, + 0, 0, + /* IP15_8_6 [3] */ + FN_GPS_CLK, FN_DU1_DOTCLKIN_C, FN_AUDIO_CLKB_B, + FN_PWM5_B, FN_SCIFA3_TXD_C, + 0, 0, 0, + /* IP15_5_4 [2] */ + FN_SIM0_D, FN_IERX, FN_CAN1_RX_D, 0, + /* IP15_3_2 [2] */ + FN_SIM0_CLK, FN_IECLK, FN_CAN_CLK_C, 0, + /* IP15_1_0 [2] */ + FN_SIM0_RST, FN_IETX, FN_CAN1_TX_D, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR16", 0xE6060160, 32, + 4, 4, 4, 4, 4, 2, 2, 2, 3, 3) { + /* IP16_31_28 [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* IP16_27_24 [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* IP16_23_20 [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* IP16_19_16 [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* IP16_15_12 [4] */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* IP16_11_10 [2] */ + FN_HRTS1_N, FN_SCIFB1_RTS_N, FN_MLB_DAT, FN_CAN1_RX_B, + /* IP16_9_8 [2] */ + FN_HCTS1_N, FN_SCIFB1_CTS_N, FN_MLB_SIG, FN_CAN1_TX_B, + /* IP16_7_6 [2] */ + FN_HSCK1, FN_SCIFB1_SCK, FN_MLB_CK, FN_GLO_RFON_C, + /* IP16_5_3 [3] */ + FN_HTX1, FN_SCIFB1_TXD, FN_VI1_R1_B, + FN_GLO_SS_C, FN_VI1_DATA7_C, + 0, 0, 0, + /* IP16_2_0 [3] */ + FN_HRX1, FN_SCIFB1_RXD, FN_VI1_R0_B, + FN_GLO_SDATA_C, FN_VI1_DATA6_C, + 0, 0, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32, + 1, 2, 2, 2, 3, 2, 1, 1, 1, 1, + 3, 2, 2, 2, 1, 2, 2, 2) { + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIF1 [2] */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, + /* SEL_SCIFB [2] */ + FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, + /* SEL_SCIFB2 [2] */ + FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, + FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, + /* SEL_SCIFB1 [3] */ + FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, + FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, + 0, 0, 0, 0, + /* SEL_SCIFA1 [2] */ + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, 0, + /* SEL_SSI9 [1] */ + FN_SEL_SSI9_0, FN_SEL_SSI9_1, + /* SEL_SCFA [1] */ + FN_SEL_SCFA_0, FN_SEL_SCFA_1, + /* SEL_QSP [1] */ + FN_SEL_QSP_0, FN_SEL_QSP_1, + /* SEL_SSI7 [1] */ + FN_SEL_SSI7_0, FN_SEL_SSI7_1, + /* SEL_HSCIF1 [3] */ + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, + FN_SEL_HSCIF1_3, FN_SEL_HSCIF1_4, + 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_VI1 [2] */ + FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_TMU [1] */ + FN_SEL_TMU1_0, FN_SEL_TMU1_1, + /* SEL_LBS [2] */ + FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, + /* SEL_TSIF0 [2] */ + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + /* SEL_SOF0 [2] */ + FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32, + 3, 1, 1, 3, 2, 1, 1, 2, 2, + 1, 3, 2, 1, 2, 2, 2, 1, 1, 1) { + /* SEL_SCIF0 [3] */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, + FN_SEL_SCIF0_3, FN_SEL_SCIF0_4, + 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIF [1] */ + FN_SEL_SCIF_0, FN_SEL_SCIF_1, + /* SEL_CAN0 [3] */ + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + FN_SEL_CAN0_4, FN_SEL_CAN0_5, + 0, 0, + /* SEL_CAN1 [2] */ + FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, + /* RESEVED [1] */ + 0, 0, + /* SEL_SCIFA2 [1] */ + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + /* SEL_SCIF4 [2] */ + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_ADG [1] */ + FN_SEL_ADG_0, FN_SEL_ADG_1, + /* SEL_FM [3] */ + FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, + FN_SEL_FM_3, FN_SEL_FM_4, + 0, 0, 0, + /* SEL_SCIFA5 [2] */ + FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_GPS [2] */ + FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, + /* SEL_SCIFA4 [2] */ + FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, 0, + /* SEL_SCIFA3 [2] */ + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, 0, + /* SEL_SIM [1] */ + FN_SEL_SIM_0, FN_SEL_SIM_1, + /* RESEVED [1] */ + 0, 0, + /* SEL_SSI8 [1] */ + FN_SEL_SSI8_0, FN_SEL_SSI8_1, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32, + 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 2, 2, 3, 2, 2, 2, 1) { + /* SEL_HSCIF2 [2] */ + FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, + FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, + /* SEL_CANCLK [2] */ + FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, + FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, + /* SEL_IIC8 [2] */ + FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, 0, + /* SEL_IIC7 [2] */ + FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, 0, + /* SEL_IIC4 [2] */ + FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, 0, + /* SEL_IIC3 [2] */ + FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, + /* SEL_SCIF3 [2] */ + FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, + /* SEL_IEB [2] */ + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0, + /* SEL_MMC [1] */ + FN_SEL_MMC_0, FN_SEL_MMC_1, + /* SEL_SCIF5 [1] */ + FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_IIC2 [2] */ + FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, + /* SEL_IIC1 [3] */ + FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, + FN_SEL_IIC1_4, + 0, 0, 0, + /* SEL_IIC0 [2] */ + FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [1] */ + 0, 0, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL4", 0xE606009C, 32, + 3, 2, 2, 1, 1, 1, 1, 3, 2, + 2, 3, 1, 1, 1, 2, 2, 2, 2) { + /* SEL_SOF1 [3] */ + FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, + FN_SEL_SOF1_4, + 0, 0, 0, + /* SEL_HSCIF0 [2] */ + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, 0, + /* SEL_DIS [2] */ + FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_RAD [1] */ + FN_SEL_RAD_0, FN_SEL_RAD_1, + /* SEL_RCN [1] */ + FN_SEL_RCN_0, FN_SEL_RCN_1, + /* SEL_RSP [1] */ + FN_SEL_RSP_0, FN_SEL_RSP_1, + /* SEL_SCIF2 [3] */ + FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, + FN_SEL_SCIF2_3, FN_SEL_SCIF2_4, + 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* SEL_SOF2 [3] */ + FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, + FN_SEL_SOF2_3, FN_SEL_SOF2_4, + 0, 0, 0, + /* RESEVED [1] */ + 0, 0, + /* SEL_SSI1 [1] */ + FN_SEL_SSI1_0, FN_SEL_SSI1_1, + /* SEL_SSI0 [1] */ + FN_SEL_SSI0_0, FN_SEL_SSI0_1, + /* SEL_SSP [2] */ + FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, + /* RESEVED [2] */ + 0, 0, 0, 0, } + }, + { PINMUX_CFG_REG("INOUTSEL0", 0xE6050004, 32, 1) { GP_INOUTSEL(0) } }, + { PINMUX_CFG_REG("INOUTSEL1", 0xE6051004, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_IN, GP_1_25_OUT, + GP_1_24_IN, GP_1_24_OUT, + GP_1_23_IN, GP_1_23_OUT, + GP_1_22_IN, GP_1_22_OUT, + GP_1_21_IN, GP_1_21_OUT, + GP_1_20_IN, GP_1_20_OUT, + GP_1_19_IN, GP_1_19_OUT, + GP_1_18_IN, GP_1_18_OUT, + GP_1_17_IN, GP_1_17_OUT, + GP_1_16_IN, GP_1_16_OUT, + GP_1_15_IN, GP_1_15_OUT, + GP_1_14_IN, GP_1_14_OUT, + GP_1_13_IN, GP_1_13_OUT, + GP_1_12_IN, GP_1_12_OUT, + GP_1_11_IN, GP_1_11_OUT, + GP_1_10_IN, GP_1_10_OUT, + GP_1_9_IN, GP_1_9_OUT, + GP_1_8_IN, GP_1_8_OUT, + GP_1_7_IN, GP_1_7_OUT, + GP_1_6_IN, GP_1_6_OUT, + GP_1_5_IN, GP_1_5_OUT, + GP_1_4_IN, GP_1_4_OUT, + GP_1_3_IN, GP_1_3_OUT, + GP_1_2_IN, GP_1_2_OUT, + GP_1_1_IN, GP_1_1_OUT, + GP_1_0_IN, GP_1_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL2", 0xE6052004, 32, 1) { GP_INOUTSEL(2) } }, + { PINMUX_CFG_REG("INOUTSEL3", 0xE6053004, 32, 1) { GP_INOUTSEL(3) } }, + { PINMUX_CFG_REG("INOUTSEL4", 0xE6054004, 32, 1) { GP_INOUTSEL(4) } }, + { PINMUX_CFG_REG("INOUTSEL5", 0xE6055004, 32, 1) { GP_INOUTSEL(5) } }, + { PINMUX_CFG_REG("INOUTSEL6", 0xE6055404, 32, 1) { GP_INOUTSEL(6) } }, + { PINMUX_CFG_REG("INOUTSEL7", 0xE6055804, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_7_25_IN, GP_7_25_OUT, + GP_7_24_IN, GP_7_24_OUT, + GP_7_23_IN, GP_7_23_OUT, + GP_7_22_IN, GP_7_22_OUT, + GP_7_21_IN, GP_7_21_OUT, + GP_7_20_IN, GP_7_20_OUT, + GP_7_19_IN, GP_7_19_OUT, + GP_7_18_IN, GP_7_18_OUT, + GP_7_17_IN, GP_7_17_OUT, + GP_7_16_IN, GP_7_16_OUT, + GP_7_15_IN, GP_7_15_OUT, + GP_7_14_IN, GP_7_14_OUT, + GP_7_13_IN, GP_7_13_OUT, + GP_7_12_IN, GP_7_12_OUT, + GP_7_11_IN, GP_7_11_OUT, + GP_7_10_IN, GP_7_10_OUT, + GP_7_9_IN, GP_7_9_OUT, + GP_7_8_IN, GP_7_8_OUT, + GP_7_7_IN, GP_7_7_OUT, + GP_7_6_IN, GP_7_6_OUT, + GP_7_5_IN, GP_7_5_OUT, + GP_7_4_IN, GP_7_4_OUT, + GP_7_3_IN, GP_7_3_OUT, + GP_7_2_IN, GP_7_2_OUT, + GP_7_1_IN, GP_7_1_OUT, + GP_7_0_IN, GP_7_0_OUT, } + }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("INDT0", 0xE6050008, 32) { GP_INDT(0) } }, + { PINMUX_DATA_REG("INDT1", 0xE6051008, 32) { + 0, 0, 0, 0, + 0, 0, GP_1_25_DATA, GP_1_24_DATA, + GP_1_23_DATA, GP_1_22_DATA, GP_1_21_DATA, GP_1_20_DATA, + GP_1_19_DATA, GP_1_18_DATA, GP_1_17_DATA, GP_1_16_DATA, + GP_1_15_DATA, GP_1_14_DATA, GP_1_13_DATA, GP_1_12_DATA, + GP_1_11_DATA, GP_1_10_DATA, GP_1_9_DATA, GP_1_8_DATA, + GP_1_7_DATA, GP_1_6_DATA, GP_1_5_DATA, GP_1_4_DATA, + GP_1_3_DATA, GP_1_2_DATA, GP_1_1_DATA, GP_1_0_DATA } + }, + { PINMUX_DATA_REG("INDT2", 0xE6052008, 32) { GP_INDT(2) } }, + { PINMUX_DATA_REG("INDT3", 0xE6053008, 32) { GP_INDT(3) } }, + { PINMUX_DATA_REG("INDT4", 0xE6054008, 32) { GP_INDT(4) } }, + { PINMUX_DATA_REG("INDT5", 0xE6055008, 32) { GP_INDT(5) } }, + { PINMUX_DATA_REG("INDT6", 0xE6055408, 32) { GP_INDT(6) } }, + { PINMUX_DATA_REG("INDT7", 0xE6055808, 32) { + 0, 0, 0, 0, + 0, 0, GP_7_25_DATA, GP_7_24_DATA, + GP_7_23_DATA, GP_7_22_DATA, GP_7_21_DATA, GP_7_20_DATA, + GP_7_19_DATA, GP_7_18_DATA, GP_7_17_DATA, GP_7_16_DATA, + GP_7_15_DATA, GP_7_14_DATA, GP_7_13_DATA, GP_7_12_DATA, + GP_7_11_DATA, GP_7_10_DATA, GP_7_9_DATA, GP_7_8_DATA, + GP_7_7_DATA, GP_7_6_DATA, GP_7_5_DATA, GP_7_4_DATA, + GP_7_3_DATA, GP_7_2_DATA, GP_7_1_DATA, GP_7_0_DATA } + }, + { }, +}; + +static struct pinmux_info r8a7793_pinmux_info = { + .name = "r8a7793_pfc", + + .unlock_reg = 0xe6060000, /* PMMR */ + + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_GP_0_0, + .last_gpio = GPIO_FN_CAN1_RX_B, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), +}; + +void r8a7793_pinmux_init(void) +{ + register_pinmux(&r8a7793_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7794.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7794.c new file mode 100644 index 0000000..7ea5edc --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-r8a7794.c
@@ -0,0 +1,1651 @@ +/* + * arch/arm/cpu/armv7/rmobile/pfc-r8a7794.c + * This file is r8a7794 processor support - PFC hardware block. + * + * Copyright (C) 2014 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <sh_pfc.h> +#include <asm/gpio.h> + +#define CPU_32_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_1(fn, pfx##31, sfx) + +#define CPU_26_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##20, sfx), PORT_1(fn, pfx##21, sfx), \ + PORT_1(fn, pfx##22, sfx), PORT_1(fn, pfx##23, sfx), \ + PORT_1(fn, pfx##24, sfx), PORT_1(fn, pfx##25, sfx) + +#define CPU_28_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_1(fn, pfx##20, sfx), PORT_1(fn, pfx##21, sfx), \ + PORT_1(fn, pfx##22, sfx), PORT_1(fn, pfx##23, sfx), \ + PORT_1(fn, pfx##24, sfx), PORT_1(fn, pfx##25, sfx), \ + PORT_1(fn, pfx##26, sfx), PORT_1(fn, pfx##27, sfx) + +/* + * GP_0_0_DATA -> GP_6_25_DATA + * (except for GP1[26],GP1[27],GP1[28],GP1[29]),GP1[30],GP1[31] + * GP5[28],GP5[29]),GP5[30],GP5[31],GP6[26],GP6[27],GP6[28], + * GP6[29]),GP6[30],GP6[31]) + */ +#define CPU_ALL_PORT(fn, pfx, sfx) \ + CPU_32_PORT(fn, pfx##_0_, sfx), \ + CPU_26_PORT(fn, pfx##_1_, sfx), \ + CPU_32_PORT(fn, pfx##_2_, sfx), \ + CPU_32_PORT(fn, pfx##_3_, sfx), \ + CPU_32_PORT(fn, pfx##_4_, sfx), \ + CPU_28_PORT(fn, pfx##_5_, sfx), \ + CPU_26_PORT(fn, pfx##_6_, sfx) + +#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA) +#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN, \ + GP##pfx##_IN, GP##pfx##_OUT) + +#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT +#define _GP_INDT(pfx, sfx) GP##pfx##_DATA + +#define GP_ALL(str) CPU_ALL_PORT(_PORT_ALL, GP, str) +#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused) +#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused) + + +#define PORT_10_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \ + PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \ + PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \ + PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \ + PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx) + +#define CPU_32_PORT_REV(fn, pfx, sfx) \ + PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \ + PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \ + PORT_10_REV(fn, pfx, sfx) + +#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused) +#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused) + +#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn) +#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \ + FN_##ipsr, FN_##fn) + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + GP_ALL(DATA), + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + GP_ALL(IN), + PINMUX_INPUT_END, + + PINMUX_OUTPUT_BEGIN, + GP_ALL(OUT), + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + GP_ALL(FN), + + /* GPSR0 */ + FN_IP0_23_22, FN_IP0_24, FN_IP0_25, FN_IP0_27_26, FN_IP0_29_28, + FN_IP0_31_30, FN_IP1_1_0, FN_IP1_3_2, FN_IP1_5_4, FN_IP1_7_6, + FN_IP1_10_8, FN_IP1_12_11, FN_IP1_14_13, FN_IP1_17_15, FN_IP1_19_18, + FN_IP1_21_20, FN_IP1_23_22, FN_IP1_24, FN_A2, FN_IP1_26, FN_IP1_27, + FN_IP1_29_28, FN_IP1_31_30, FN_IP2_1_0, FN_IP2_3_2, FN_IP2_5_4, + FN_IP2_7_6, FN_IP2_9_8, FN_IP2_11_10, FN_IP2_13_12, FN_IP2_15_14, + FN_IP2_17_16, + + /* GPSR1 */ + FN_IP2_20_18, FN_IP2_23_21, FN_IP2_26_24, FN_IP2_29_27, FN_IP2_31_30, + FN_IP3_1_0, FN_IP3_3_2, FN_IP3_5_4, FN_IP3_7_6, FN_IP3_9_8, FN_IP3_10, + FN_IP3_11, FN_IP3_12, FN_IP3_14_13, FN_IP3_17_15, FN_IP3_20_18, + FN_IP3_23_21, FN_IP3_26_24, FN_IP3_29_27, FN_IP3_30, FN_IP3_31, + FN_WE0_N, FN_WE1_N, FN_IP4_1_0 , FN_IP7_31, FN_DACK0, + + /* GPSR2 */ + FN_IP4_4_2, FN_IP4_7_5, FN_IP4_9_8, FN_IP4_11_10, FN_IP4_13_12, + FN_IP4_15_14, FN_IP4_17_16, FN_IP4_19_18, FN_IP4_22_20, FN_IP4_25_23, + FN_IP4_27_26, FN_IP4_29_28, FN_IP4_31_30, FN_IP5_1_0, FN_IP5_3_2, + FN_IP5_5_4, FN_IP5_8_6, FN_IP5_11_9, FN_IP5_13_12, FN_IP5_15_14, + FN_IP5_17_16, FN_IP5_19_18, FN_IP5_21_20, FN_IP5_23_22, FN_IP5_25_24, + FN_IP5_27_26, FN_IP5_29_28, FN_IP5_31_30, FN_IP6_1_0, FN_IP6_3_2, + FN_IP6_5_4, FN_IP6_7_6, + + /* GPSR3 */ + FN_IP6_8, FN_IP6_9, FN_IP6_10, FN_IP6_11, FN_IP6_12, FN_IP6_13, + FN_IP6_14, FN_IP6_15, FN_IP6_16, FN_IP6_19_17, FN_IP6_22_20, + FN_IP6_25_23, FN_IP6_28_26, FN_IP6_31_29, FN_IP7_2_0, FN_IP7_5_3, + FN_IP7_8_6, FN_IP7_11_9, FN_IP7_14_12, FN_IP7_17_15, FN_IP7_20_18, + FN_IP7_23_21, FN_IP7_26_24, FN_IP7_29_27, FN_IP8_2_0, FN_IP8_5_3, + FN_IP8_8_6, FN_IP8_11_9, FN_IP8_14_12, FN_IP8_16_15, FN_IP8_19_17, + FN_IP8_22_20, + + /* GPSR4 */ + FN_IP8_25_23, FN_IP8_28_26, FN_IP8_31_29, FN_IP9_2_0, FN_IP9_5_3, + FN_IP9_8_6, FN_IP9_11_9, FN_IP9_14_12, FN_IP9_16_15, FN_IP9_18_17, + FN_IP9_21_19, FN_IP9_24_22, FN_IP9_27_25, FN_IP9_30_28, FN_IP10_2_0, + FN_IP10_5_3, FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_17_15, + FN_IP10_20_18, FN_IP10_23_21, FN_IP10_26_24, FN_IP10_29_27, + FN_IP10_31_30, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_7_6, FN_IP11_10_8, + FN_IP11_13_11, FN_IP11_15_14, FN_IP11_17_16, + + /* GPSR5 */ + FN_IP11_20_18, FN_IP11_23_21, FN_IP11_26_24, FN_IP11_29_27, FN_IP12_2_0, + FN_IP12_5_3, FN_IP12_8_6, FN_IP12_10_9, FN_IP12_12_11, FN_IP12_14_13, + FN_IP12_17_15, FN_IP12_20_18, FN_IP12_23_21, FN_IP12_26_24, + FN_IP12_29_27, FN_IP13_2_0, FN_IP13_5_3, FN_IP13_8_6, FN_IP13_11_9, + FN_IP13_14_12, FN_IP13_17_15, FN_IP13_20_18, FN_IP13_23_21, + FN_IP13_26_24, FN_USB0_PWEN, FN_USB0_OVC, FN_USB1_PWEN, FN_USB1_OVC, + + /* GPSR6 */ + FN_SD0_CLK, FN_SD0_CMD, FN_SD0_DATA0, FN_SD0_DATA1, FN_SD0_DATA2, + FN_SD0_DATA3, FN_SD0_CD, FN_SD0_WP, FN_SD1_CLK, FN_SD1_CMD, + FN_SD1_DATA0, FN_SD1_DATA1, FN_SD1_DATA2, FN_SD1_DATA3, FN_IP0_0, + FN_IP0_9_8, FN_IP0_10, FN_IP0_11, FN_IP0_12, FN_IP0_13, FN_IP0_14, + FN_IP0_15, FN_IP0_16, FN_IP0_17, FN_IP0_19_18, FN_IP0_21_20, + + /* IPSR0 */ + FN_SD1_CD, FN_CAN0_RX, FN_SD1_WP, FN_IRQ7, FN_CAN0_TX, FN_MMC_CLK, + FN_SD2_CLK, FN_MMC_CMD, FN_SD2_CMD, FN_MMC_D0, FN_SD2_DATA0, FN_MMC_D1, + FN_SD2_DATA1, FN_MMC_D2, FN_SD2_DATA2, FN_MMC_D3, FN_SD2_DATA3, + FN_MMC_D4, FN_SD2_CD, FN_MMC_D5, FN_SD2_WP, FN_MMC_D6, FN_SCIF0_RXD, + FN_I2C2_SCL_B, FN_CAN1_RX, FN_MMC_D7, FN_SCIF0_TXD, FN_I2C2_SDA_B, + FN_CAN1_TX, FN_D0, FN_SCIFA3_SCK_B, FN_IRQ4, FN_D1, FN_SCIFA3_RXD_B, + FN_D2, FN_SCIFA3_TXD_B, FN_D3, FN_I2C3_SCL_B, FN_SCIF5_RXD_B, FN_D4, + FN_I2C3_SDA_B, FN_SCIF5_TXD_B, FN_D5, FN_SCIF4_RXD_B, FN_I2C0_SCL_D, + + /* + * From IPSR1 to IPSR5 have been removed because they does not use. + */ + + /* IPSR6 */ + FN_DU0_EXVSYNC_DU0_VSYNC, FN_QSTB_QHE, FN_CC50_STATE28, + FN_DU0_EXODDF_DU0_ODDF_DISP_CDE, FN_QCPV_QDE, FN_CC50_STATE29, + FN_DU0_DISP, FN_QPOLA, FN_CC50_STATE30, FN_DU0_CDE, FN_QPOLB, + FN_CC50_STATE31, FN_VI0_CLK, FN_AVB_RX_CLK, FN_VI0_DATA0_VI0_B0, + FN_AVB_RX_DV, FN_VI0_DATA1_VI0_B1, FN_AVB_RXD0, FN_VI0_DATA2_VI0_B2, + FN_AVB_RXD1, FN_VI0_DATA3_VI0_B3, FN_AVB_RXD2, FN_VI0_DATA4_VI0_B4, + FN_AVB_RXD3, FN_VI0_DATA5_VI0_B5, FN_AVB_RXD4, FN_VI0_DATA6_VI0_B6, + FN_AVB_RXD5, FN_VI0_DATA7_VI0_B7, FN_AVB_RXD6, FN_VI0_CLKENB, + FN_I2C3_SCL, FN_SCIFA5_RXD_C, FN_IETX_C, FN_AVB_RXD7, FN_VI0_FIELD, + FN_I2C3_SDA, FN_SCIFA5_TXD_C, FN_IECLK_C, FN_AVB_RX_ER, FN_VI0_HSYNC_N, + FN_SCIF0_RXD_B, FN_I2C0_SCL_C, FN_IERX_C, FN_AVB_COL, FN_VI0_VSYNC_N, + FN_SCIF0_TXD_B, FN_I2C0_SDA_C, FN_AUDIO_CLKOUT_B, FN_AVB_TX_EN, + FN_ETH_MDIO, FN_VI0_G0, FN_MSIOF2_RXD_B, FN_IIC0_SCL_D, FN_AVB_TX_CLK, + FN_ADIDATA, FN_AD_DI, + + /* IPSR7 */ + FN_ETH_CRS_DV, FN_VI0_G1, FN_MSIOF2_TXD_B, FN_IIC0_SDA_D, FN_AVB_TXD0, + FN_ADICS_SAMP, FN_AD_DO, FN_ETH_RX_ER, FN_VI0_G2, FN_MSIOF2_SCK_B, + FN_CAN0_RX_B, FN_AVB_TXD1, FN_ADICLK, FN_AD_CLK, FN_ETH_RXD0, FN_VI0_G3, + FN_MSIOF2_SYNC_B, FN_CAN0_TX_B, FN_AVB_TXD2, FN_ADICHS0, FN_AD_NCS_N, + FN_ETH_RXD1, FN_VI0_G4, FN_MSIOF2_SS1_B, FN_SCIF4_RXD_D, FN_AVB_TXD3, + FN_ADICHS1, FN_ETH_LINK, FN_VI0_G5, FN_MSIOF2_SS2_B, FN_SCIF4_TXD_D, + FN_AVB_TXD4, FN_ADICHS2, FN_ETH_REFCLK, FN_VI0_G6, FN_SCIF2_SCK_C, + FN_AVB_TXD5, FN_SSI_SCK5_B, FN_ETH_TXD1, FN_VI0_G7, FN_SCIF2_RXD_C, + FN_IIC1_SCL_D, FN_AVB_TXD6, FN_SSI_WS5_B, FN_ETH_TX_EN, FN_VI0_R0, + FN_SCIF2_TXD_C, FN_IIC1_SDA_D, FN_AVB_TXD7, FN_SSI_SDATA5_B, + FN_ETH_MAGIC, FN_VI0_R1, FN_SCIF3_SCK_B, FN_AVB_TX_ER, FN_SSI_SCK6_B, + FN_ETH_TXD0, FN_VI0_R2, FN_SCIF3_RXD_B, FN_I2C4_SCL_E, FN_AVB_GTX_CLK, + FN_SSI_WS6_B, FN_DREQ0_N, FN_SCIFB1_RXD, + + /* IPSR8 */ + FN_ETH_MDC, FN_VI0_R3, FN_SCIF3_TXD_B, FN_I2C4_SDA_E, FN_AVB_MDC, + FN_SSI_SDATA6_B, FN_HSCIF0_HRX, FN_VI0_R4, FN_I2C1_SCL_C, + FN_AUDIO_CLKA_B, FN_AVB_MDIO, FN_SSI_SCK78_B, FN_HSCIF0_HTX, + FN_VI0_R5, FN_I2C1_SDA_C, FN_AUDIO_CLKB_B, FN_AVB_LINK, FN_SSI_WS78_B, + FN_HSCIF0_HCTS_N, FN_VI0_R6, FN_SCIF0_RXD_D, FN_I2C0_SCL_E, + FN_AVB_MAGIC, FN_SSI_SDATA7_B, FN_HSCIF0_HRTS_N, FN_VI0_R7, + FN_SCIF0_TXD_D, FN_I2C0_SDA_E, FN_AVB_PHY_INT, FN_SSI_SDATA8_B, + FN_HSCIF0_HSCK, FN_SCIF_CLK_B, FN_AVB_CRS, FN_AUDIO_CLKC_B, + FN_I2C0_SCL, FN_SCIF0_RXD_C, FN_PWM5, FN_TCLK1_B, FN_AVB_GTXREFCLK, + FN_CAN1_RX_D, FN_TPUTO0_B, FN_I2C0_SDA, FN_SCIF0_TXD_C, FN_TPUTO0, + FN_CAN_CLK, FN_DVC_MUTE, FN_CAN1_TX_D, FN_I2C1_SCL, FN_SCIF4_RXD, + FN_PWM5_B, FN_DU1_DR0, FN_RIF1_SYNC_B, FN_TS_SDATA_D, FN_TPUTO1_B, + FN_I2C1_SDA, FN_SCIF4_TXD, FN_IRQ5, FN_DU1_DR1, FN_RIF1_CLK_B, + FN_TS_SCK_D, FN_BPFCLK_C, FN_MSIOF0_RXD, FN_SCIF5_RXD, FN_I2C2_SCL_C, + FN_DU1_DR2, FN_RIF1_D0_B, FN_TS_SDEN_D, FN_FMCLK_C, FN_RDS_CLK, + + /* + * From IPSR9 to IPSR10 have been removed because they does not use. + */ + + /* IPSR11 */ + FN_SSI_WS5, FN_SCIFA3_RXD, FN_I2C3_SCL_C, FN_DU1_DOTCLKOUT0, + FN_CAN_DEBUGOUT11, FN_SSI_SDATA5, FN_SCIFA3_TXD, FN_I2C3_SDA_C, + FN_DU1_DOTCLKOUT1, FN_CAN_DEBUGOUT12, FN_SSI_SCK6, FN_SCIFA1_SCK_B, + FN_DU1_EXHSYNC_DU1_HSYNC, FN_CAN_DEBUGOUT13, FN_SSI_WS6, + FN_SCIFA1_RXD_B, FN_I2C4_SCL_C, FN_DU1_EXVSYNC_DU1_VSYNC, + FN_CAN_DEBUGOUT14, FN_SSI_SDATA6, FN_SCIFA1_TXD_B, FN_I2C4_SDA_C, + FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_CAN_DEBUGOUT15, FN_SSI_SCK78, + FN_SCIFA2_SCK_B, FN_IIC0_SDA_C, FN_DU1_DISP, FN_SSI_WS78, + FN_SCIFA2_RXD_B, FN_IIC0_SCL_C, FN_DU1_CDE, FN_SSI_SDATA7, + FN_SCIFA2_TXD_B, FN_IRQ8, FN_AUDIO_CLKA_D, FN_CAN_CLK_D, FN_PCMOE_N, + FN_SSI_SCK0129, FN_MSIOF1_RXD_B, FN_SCIF5_RXD_D, FN_ADIDATA_B, + FN_AD_DI_B, FN_PCMWE_N, FN_SSI_WS0129, FN_MSIOF1_TXD_B, FN_SCIF5_TXD_D, + FN_ADICS_SAMP_B, FN_AD_DO_B, FN_SSI_SDATA0, FN_MSIOF1_SCK_B, FN_PWM0_B, + FN_ADICLK_B, FN_AD_CLK_B, + + /* + * From IPSR12 to IPSR13 have been removed because they does not use. + */ + + /* MOD_SEL */ + FN_SEL_ADG_0, FN_SEL_ADG_1, FN_SEL_ADG_2, FN_SEL_ADG_3, + FN_SEL_ADI_0, FN_SEL_ADI_1, FN_SEL_CAN_0, FN_SEL_CAN_1, + FN_SEL_CAN_2, FN_SEL_CAN_3, FN_SEL_DARC_0, FN_SEL_DARC_1, + FN_SEL_DARC_2, FN_SEL_DARC_3, FN_SEL_DARC_4, FN_SEL_DR0_0, + FN_SEL_DR0_1, FN_SEL_DR1_0, FN_SEL_DR1_1, FN_SEL_DR2_0, FN_SEL_DR2_1, + FN_SEL_DR3_0, FN_SEL_DR3_1, FN_SEL_ETH_0, FN_SEL_ETH_1, FN_SEL_FSN_0, + FN_SEL_FSN_1, FN_SEL_I2C00_0, FN_SEL_I2C00_1, FN_SEL_I2C00_2, + FN_SEL_I2C00_3, FN_SEL_I2C00_4, FN_SEL_I2C01_0, FN_SEL_I2C01_1, + FN_SEL_I2C01_2, FN_SEL_I2C01_3, FN_SEL_I2C01_4, FN_SEL_I2C02_0, + FN_SEL_I2C02_1, FN_SEL_I2C02_2, FN_SEL_I2C02_3, FN_SEL_I2C02_4, + FN_SEL_I2C03_0, FN_SEL_I2C03_1, FN_SEL_I2C03_2, FN_SEL_I2C03_3, + FN_SEL_I2C03_4, FN_SEL_I2C04_0, FN_SEL_I2C04_1, FN_SEL_I2C04_2, + FN_SEL_I2C04_3, FN_SEL_I2C04_4, FN_SEL_IIC00_0, FN_SEL_IIC00_1, + FN_SEL_IIC00_2, FN_SEL_IIC00_3, FN_SEL_AVB_0, FN_SEL_AVB_1, + + /* MOD_SEL2 */ + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, FN_SEL_IIC01_0, + FN_SEL_IIC01_1, FN_SEL_IIC01_2, FN_SEL_IIC01_3, FN_SEL_LBS_0, + FN_SEL_LBS_1, FN_SEL_MSI1_0, FN_SEL_MSI1_1, FN_SEL_MSI2_0, + FN_SEL_MSI2_1, FN_SEL_RAD_0, FN_SEL_RAD_1, FN_SEL_RCN_0, + FN_SEL_RCN_1, FN_SEL_RSP_0, FN_SEL_RSP_1, FN_SEL_SCIFA0_0, + FN_SEL_SCIFA0_1, FN_SEL_SCIFA0_2, FN_SEL_SCIFA0_3, FN_SEL_SCIFA1_0, + FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, + FN_SEL_SCIFA4_2, FN_SEL_SCIFA4_3, FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, + FN_SEL_SCIFA5_2, FN_SEL_SCIFA5_3, FN_SEL_SPDM_0, FN_SEL_SPDM_1, + FN_SEL_TMU_0, FN_SEL_TMU_1, FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, + FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, FN_SEL_CAN0_0, FN_SEL_CAN0_1, + FN_SEL_CAN0_2, FN_SEL_CAN0_3, FN_SEL_CAN1_0, FN_SEL_CAN1_1, + FN_SEL_CAN1_2, FN_SEL_CAN1_3, FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_RDS_0, FN_SEL_RDS_1, + FN_SEL_RDS_2, FN_SEL_RDS_3, + + /* MOD_SEL3 */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3, + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF2_0, + FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, FN_SEL_SCIF4_3, + FN_SEL_SCIF4_4, FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, FN_SEL_SCIF5_2, + FN_SEL_SCIF5_3, FN_SEL_SSI1_0, FN_SEL_SSI1_1, FN_SEL_SSI2_0, + FN_SEL_SSI2_1, FN_SEL_SSI4_0, FN_SEL_SSI4_1, FN_SEL_SSI5_0, + FN_SEL_SSI5_1, FN_SEL_SSI6_0, FN_SEL_SSI6_1, FN_SEL_SSI7_0, + FN_SEL_SSI7_1, FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI9_0, + FN_SEL_SSI9_1, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + A2_MARK, WE0_N_MARK, WE1_N_MARK, DACK0_MARK, + + USB0_PWEN_MARK, USB0_OVC_MARK, USB1_PWEN_MARK, USB1_OVC_MARK, + + SD0_CLK_MARK, SD0_CMD_MARK, SD0_DATA0_MARK, SD0_DATA1_MARK, + SD0_DATA2_MARK, SD0_DATA3_MARK, SD0_CD_MARK, SD0_WP_MARK, + + SD1_CLK_MARK, SD1_CMD_MARK, SD1_DATA0_MARK, SD1_DATA1_MARK, + SD1_DATA2_MARK, SD1_DATA3_MARK, + + /* IPSR0 */ + SD1_CD_MARK, CAN0_RX_MARK, SD1_WP_MARK, IRQ7_MARK, CAN0_TX_MARK, + MMC_CLK_MARK, SD2_CLK_MARK, MMC_CMD_MARK, SD2_CMD_MARK, MMC_D0_MARK, + SD2_DATA0_MARK, MMC_D1_MARK, SD2_DATA1_MARK, MMC_D2_MARK, + SD2_DATA2_MARK, MMC_D3_MARK, SD2_DATA3_MARK, MMC_D4_MARK, SD2_CD_MARK, + MMC_D5_MARK, SD2_WP_MARK, MMC_D6_MARK, SCIF0_RXD_MARK, I2C2_SCL_B_MARK, + CAN1_RX_MARK, MMC_D7_MARK, SCIF0_TXD_MARK, I2C2_SDA_B_MARK, + CAN1_TX_MARK, D0_MARK, SCIFA3_SCK_B_MARK, IRQ4_MARK, D1_MARK, + SCIFA3_RXD_B_MARK, D2_MARK, SCIFA3_TXD_B_MARK, D3_MARK, I2C3_SCL_B_MARK, + SCIF5_RXD_B_MARK, D4_MARK, I2C3_SDA_B_MARK, SCIF5_TXD_B_MARK, D5_MARK, + SCIF4_RXD_B_MARK, I2C0_SCL_D_MARK, + + /* + * From IPSR1 to IPSR5 have been removed because they does not use. + */ + + /* IPSR6 */ + DU0_EXVSYNC_DU0_VSYNC_MARK, QSTB_QHE_MARK, CC50_STATE28_MARK, + DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK, QCPV_QDE_MARK, CC50_STATE29_MARK, + DU0_DISP_MARK, QPOLA_MARK, CC50_STATE30_MARK, DU0_CDE_MARK, QPOLB_MARK, + CC50_STATE31_MARK, VI0_CLK_MARK, AVB_RX_CLK_MARK, VI0_DATA0_VI0_B0_MARK, + AVB_RX_DV_MARK, VI0_DATA1_VI0_B1_MARK, AVB_RXD0_MARK, + VI0_DATA2_VI0_B2_MARK, AVB_RXD1_MARK, VI0_DATA3_VI0_B3_MARK, + AVB_RXD2_MARK, VI0_DATA4_VI0_B4_MARK, AVB_RXD3_MARK, + VI0_DATA5_VI0_B5_MARK, AVB_RXD4_MARK, VI0_DATA6_VI0_B6_MARK, + AVB_RXD5_MARK, VI0_DATA7_VI0_B7_MARK, AVB_RXD6_MARK, VI0_CLKENB_MARK, + I2C3_SCL_MARK, SCIFA5_RXD_C_MARK, IETX_C_MARK, AVB_RXD7_MARK, + VI0_FIELD_MARK, I2C3_SDA_MARK, SCIFA5_TXD_C_MARK, IECLK_C_MARK, + AVB_RX_ER_MARK, VI0_HSYNC_N_MARK, SCIF0_RXD_B_MARK, I2C0_SCL_C_MARK, + IERX_C_MARK, AVB_COL_MARK, VI0_VSYNC_N_MARK, SCIF0_TXD_B_MARK, + I2C0_SDA_C_MARK, AUDIO_CLKOUT_B_MARK, AVB_TX_EN_MARK, ETH_MDIO_MARK, + VI0_G0_MARK, MSIOF2_RXD_B_MARK, IIC0_SCL_D_MARK, AVB_TX_CLK_MARK, + ADIDATA_MARK, AD_DI_MARK, + + /* IPSR7 */ + ETH_CRS_DV_MARK, VI0_G1_MARK, MSIOF2_TXD_B_MARK, IIC0_SDA_D_MARK, + AVB_TXD0_MARK, ADICS_SAMP_MARK, AD_DO_MARK, ETH_RX_ER_MARK, VI0_G2_MARK, + MSIOF2_SCK_B_MARK, CAN0_RX_B_MARK, AVB_TXD1_MARK, ADICLK_MARK, + AD_CLK_MARK, ETH_RXD0_MARK, VI0_G3_MARK, MSIOF2_SYNC_B_MARK, + CAN0_TX_B_MARK, AVB_TXD2_MARK, ADICHS0_MARK, AD_NCS_N_MARK, + ETH_RXD1_MARK, VI0_G4_MARK, MSIOF2_SS1_B_MARK, SCIF4_RXD_D_MARK, + AVB_TXD3_MARK, ADICHS1_MARK, ETH_LINK_MARK, VI0_G5_MARK, + MSIOF2_SS2_B_MARK, SCIF4_TXD_D_MARK, AVB_TXD4_MARK, ADICHS2_MARK, + ETH_REFCLK_MARK, VI0_G6_MARK, SCIF2_SCK_C_MARK, AVB_TXD5_MARK, + SSI_SCK5_B_MARK, ETH_TXD1_MARK, VI0_G7_MARK, SCIF2_RXD_C_MARK, + IIC1_SCL_D_MARK, AVB_TXD6_MARK, SSI_WS5_B_MARK, ETH_TX_EN_MARK, + VI0_R0_MARK, SCIF2_TXD_C_MARK, IIC1_SDA_D_MARK, AVB_TXD7_MARK, + SSI_SDATA5_B_MARK, ETH_MAGIC_MARK, VI0_R1_MARK, SCIF3_SCK_B_MARK, + AVB_TX_ER_MARK, SSI_SCK6_B_MARK, ETH_TXD0_MARK, VI0_R2_MARK, + SCIF3_RXD_B_MARK, I2C4_SCL_E_MARK, AVB_GTX_CLK_MARK, SSI_WS6_B_MARK, + DREQ0_N_MARK, SCIFB1_RXD_MARK, + + /* IPSR8 */ + ETH_MDC_MARK, VI0_R3_MARK, SCIF3_TXD_B_MARK, I2C4_SDA_E_MARK, + AVB_MDC_MARK, SSI_SDATA6_B_MARK, HSCIF0_HRX_MARK, VI0_R4_MARK, + I2C1_SCL_C_MARK, AUDIO_CLKA_B_MARK, AVB_MDIO_MARK, SSI_SCK78_B_MARK, + HSCIF0_HTX_MARK, VI0_R5_MARK, I2C1_SDA_C_MARK, AUDIO_CLKB_B_MARK, + AVB_LINK_MARK, SSI_WS78_B_MARK, HSCIF0_HCTS_N_MARK, VI0_R6_MARK, + SCIF0_RXD_D_MARK, I2C0_SCL_E_MARK, AVB_MAGIC_MARK, SSI_SDATA7_B_MARK, + HSCIF0_HRTS_N_MARK, VI0_R7_MARK, SCIF0_TXD_D_MARK, I2C0_SDA_E_MARK, + AVB_PHY_INT_MARK, SSI_SDATA8_B_MARK, + HSCIF0_HSCK_MARK, SCIF_CLK_B_MARK, AVB_CRS_MARK, AUDIO_CLKC_B_MARK, + I2C0_SCL_MARK, SCIF0_RXD_C_MARK, PWM5_MARK, TCLK1_B_MARK, + AVB_GTXREFCLK_MARK, CAN1_RX_D_MARK, TPUTO0_B_MARK, I2C0_SDA_MARK, + SCIF0_TXD_C_MARK, TPUTO0_MARK, CAN_CLK_MARK, DVC_MUTE_MARK, + CAN1_TX_D_MARK, I2C1_SCL_MARK, SCIF4_RXD_MARK, PWM5_B_MARK, + DU1_DR0_MARK, RIF1_SYNC_B_MARK, TS_SDATA_D_MARK, TPUTO1_B_MARK, + I2C1_SDA_MARK, SCIF4_TXD_MARK, IRQ5_MARK, DU1_DR1_MARK, RIF1_CLK_B_MARK, + TS_SCK_D_MARK, BPFCLK_C_MARK, MSIOF0_RXD_MARK, SCIF5_RXD_MARK, + I2C2_SCL_C_MARK, DU1_DR2_MARK, RIF1_D0_B_MARK, TS_SDEN_D_MARK, + FMCLK_C_MARK, RDS_CLK_MARK, + + /* + * From IPSR9 to IPSR10 have been removed because they does not use. + */ + + /* IPSR11 */ + SSI_WS5_MARK, SCIFA3_RXD_MARK, I2C3_SCL_C_MARK, DU1_DOTCLKOUT0_MARK, + CAN_DEBUGOUT11_MARK, SSI_SDATA5_MARK, SCIFA3_TXD_MARK, I2C3_SDA_C_MARK, + DU1_DOTCLKOUT1_MARK, CAN_DEBUGOUT12_MARK, SSI_SCK6_MARK, + SCIFA1_SCK_B_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK, CAN_DEBUGOUT13_MARK, + SSI_WS6_MARK, SCIFA1_RXD_B_MARK, I2C4_SCL_C_MARK, + DU1_EXVSYNC_DU1_VSYNC_MARK, CAN_DEBUGOUT14_MARK, SSI_SDATA6_MARK, + SCIFA1_TXD_B_MARK, I2C4_SDA_C_MARK, DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK, + CAN_DEBUGOUT15_MARK, SSI_SCK78_MARK, SCIFA2_SCK_B_MARK, IIC0_SDA_C_MARK, + DU1_DISP_MARK, SSI_WS78_MARK, SCIFA2_RXD_B_MARK, IIC0_SCL_C_MARK, + DU1_CDE_MARK, SSI_SDATA7_MARK, SCIFA2_TXD_B_MARK, IRQ8_MARK, + AUDIO_CLKA_D_MARK, CAN_CLK_D_MARK, PCMOE_N_MARK, SSI_SCK0129_MARK, + MSIOF1_RXD_B_MARK, SCIF5_RXD_D_MARK, ADIDATA_B_MARK, AD_DI_B_MARK, + PCMWE_N_MARK, SSI_WS0129_MARK, MSIOF1_TXD_B_MARK, SCIF5_TXD_D_MARK, + ADICS_SAMP_B_MARK, AD_DO_B_MARK, SSI_SDATA0_MARK, MSIOF1_SCK_B_MARK, + PWM0_B_MARK, ADICLK_B_MARK, AD_CLK_B_MARK, + + /* + * From IPSR12 to IPSR13 have been removed because they does not use. + */ + + PINMUX_MARK_END, +}; + +static pinmux_enum_t pinmux_data[] = { + PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ + + PINMUX_DATA(A2_MARK, FN_A2), + PINMUX_DATA(WE0_N_MARK, FN_WE0_N), + PINMUX_DATA(WE1_N_MARK, FN_WE1_N), + PINMUX_DATA(DACK0_MARK, FN_DACK0), + PINMUX_DATA(USB0_PWEN_MARK, FN_USB0_PWEN), + PINMUX_DATA(USB0_OVC_MARK, FN_USB0_OVC), + PINMUX_DATA(USB1_PWEN_MARK, FN_USB1_PWEN), + PINMUX_DATA(USB1_OVC_MARK, FN_USB1_OVC), + PINMUX_DATA(SD0_CLK_MARK, FN_SD0_CLK), + PINMUX_DATA(SD0_CMD_MARK, FN_SD0_CMD), + PINMUX_DATA(SD0_DATA0_MARK, FN_SD0_DATA0), + PINMUX_DATA(SD0_DATA1_MARK, FN_SD0_DATA1), + PINMUX_DATA(SD0_DATA2_MARK, FN_SD0_DATA2), + PINMUX_DATA(SD0_DATA3_MARK, FN_SD0_DATA3), + PINMUX_DATA(SD0_CD_MARK, FN_SD0_CD), + PINMUX_DATA(SD0_WP_MARK, FN_SD0_WP), + PINMUX_DATA(SD1_CLK_MARK, FN_SD1_CLK), + PINMUX_DATA(SD1_CMD_MARK, FN_SD1_CMD), + PINMUX_DATA(SD1_DATA0_MARK, FN_SD1_DATA0), + PINMUX_DATA(SD1_DATA1_MARK, FN_SD1_DATA1), + PINMUX_DATA(SD1_DATA2_MARK, FN_SD1_DATA2), + PINMUX_DATA(SD1_DATA3_MARK, FN_SD1_DATA3), + + /* IPSR0 */ + PINMUX_IPSR_DATA(IP0_0, SD1_CD), + PINMUX_IPSR_MODSEL_DATA(IP0_0, CAN0_RX, SEL_CAN0_0), + PINMUX_IPSR_DATA(IP0_9_8, SD1_WP), + PINMUX_IPSR_DATA(IP0_9_8, IRQ7), + PINMUX_IPSR_MODSEL_DATA(IP0_9_8, CAN0_TX, SEL_CAN0_0), + PINMUX_IPSR_DATA(IP0_10, MMC_CLK), + PINMUX_IPSR_DATA(IP0_10, SD2_CLK), + PINMUX_IPSR_DATA(IP0_11, MMC_CMD), + PINMUX_IPSR_DATA(IP0_11, SD2_CMD), + PINMUX_IPSR_DATA(IP0_12, MMC_D0), + PINMUX_IPSR_DATA(IP0_12, SD2_DATA0), + PINMUX_IPSR_DATA(IP0_13, MMC_D1), + PINMUX_IPSR_DATA(IP0_13, SD2_DATA1), + PINMUX_IPSR_DATA(IP0_14, MMC_D2), + PINMUX_IPSR_DATA(IP0_14, SD2_DATA2), + PINMUX_IPSR_DATA(IP0_15, MMC_D3), + PINMUX_IPSR_DATA(IP0_15, SD2_DATA3), + PINMUX_IPSR_DATA(IP0_16, MMC_D4), + PINMUX_IPSR_DATA(IP0_16, SD2_CD), + PINMUX_IPSR_DATA(IP0_17, MMC_D5), + PINMUX_IPSR_DATA(IP0_17, SD2_WP), + PINMUX_IPSR_DATA(IP0_19_18, MMC_D6), + PINMUX_IPSR_MODSEL_DATA(IP0_19_18, SCIF0_RXD, SEL_SCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP0_19_18, I2C2_SCL_B, SEL_I2C02_1), + PINMUX_IPSR_MODSEL_DATA(IP0_19_18, CAN1_RX, SEL_CAN1_0), + PINMUX_IPSR_DATA(IP0_21_20, MMC_D7), + PINMUX_IPSR_MODSEL_DATA(IP0_21_20, SCIF0_TXD, SEL_SCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP0_21_20, I2C2_SDA_B, SEL_I2C02_1), + PINMUX_IPSR_MODSEL_DATA(IP0_21_20, CAN1_TX, SEL_CAN1_0), + PINMUX_IPSR_DATA(IP0_23_22, D0), + PINMUX_IPSR_MODSEL_DATA(IP0_23_22, SCIFA3_SCK_B, SEL_SCIFA3_1), + PINMUX_IPSR_DATA(IP0_23_22, IRQ4), + PINMUX_IPSR_DATA(IP0_24, D1), + PINMUX_IPSR_MODSEL_DATA(IP0_24, SCIFA3_RXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_DATA(IP0_25, D2), + PINMUX_IPSR_MODSEL_DATA(IP0_25, SCIFA3_TXD_B, SEL_SCIFA3_1), + PINMUX_IPSR_DATA(IP0_27_26, D3), + PINMUX_IPSR_MODSEL_DATA(IP0_27_26, I2C3_SCL_B, SEL_I2C03_1), + PINMUX_IPSR_MODSEL_DATA(IP0_27_26, SCIF5_RXD_B, SEL_SCIF5_1), + PINMUX_IPSR_DATA(IP0_29_28, D4), + PINMUX_IPSR_MODSEL_DATA(IP0_29_28, I2C3_SDA_B, SEL_I2C03_1), + PINMUX_IPSR_MODSEL_DATA(IP0_29_28, SCIF5_TXD_B, SEL_SCIF5_1), + PINMUX_IPSR_DATA(IP0_31_30, D5), + PINMUX_IPSR_MODSEL_DATA(IP0_31_30, SCIF4_RXD_B, SEL_SCIF4_1), + PINMUX_IPSR_MODSEL_DATA(IP0_31_30, I2C0_SCL_D, SEL_I2C00_3), + + /* + * From IPSR1 to IPSR5 have been removed because they does not use. + */ + + /* IPSR6 */ + PINMUX_IPSR_DATA(IP6_1_0, DU0_EXVSYNC_DU0_VSYNC), + PINMUX_IPSR_DATA(IP6_1_0, QSTB_QHE), + PINMUX_IPSR_DATA(IP6_1_0, CC50_STATE28), + PINMUX_IPSR_DATA(IP6_3_2, DU0_EXODDF_DU0_ODDF_DISP_CDE), + PINMUX_IPSR_DATA(IP6_3_2, QCPV_QDE), + PINMUX_IPSR_DATA(IP6_3_2, CC50_STATE29), + PINMUX_IPSR_DATA(IP6_5_4, DU0_DISP), + PINMUX_IPSR_DATA(IP6_5_4, QPOLA), + PINMUX_IPSR_DATA(IP6_5_4, CC50_STATE30), + PINMUX_IPSR_DATA(IP6_7_6, DU0_CDE), + PINMUX_IPSR_DATA(IP6_7_6, QPOLB), + PINMUX_IPSR_DATA(IP6_7_6, CC50_STATE31), + PINMUX_IPSR_DATA(IP6_8, VI0_CLK), + PINMUX_IPSR_DATA(IP6_8, AVB_RX_CLK), + PINMUX_IPSR_DATA(IP6_9, VI0_DATA0_VI0_B0), + PINMUX_IPSR_DATA(IP6_9, AVB_RX_DV), + PINMUX_IPSR_DATA(IP6_10, VI0_DATA1_VI0_B1), + PINMUX_IPSR_DATA(IP6_10, AVB_RXD0), + PINMUX_IPSR_DATA(IP6_11, VI0_DATA2_VI0_B2), + PINMUX_IPSR_DATA(IP6_11, AVB_RXD1), + PINMUX_IPSR_DATA(IP6_12, VI0_DATA3_VI0_B3), + PINMUX_IPSR_DATA(IP6_12, AVB_RXD2), + PINMUX_IPSR_DATA(IP6_13, VI0_DATA4_VI0_B4), + PINMUX_IPSR_DATA(IP6_13, AVB_RXD3), + PINMUX_IPSR_DATA(IP6_14, VI0_DATA5_VI0_B5), + PINMUX_IPSR_DATA(IP6_14, AVB_RXD4), + PINMUX_IPSR_DATA(IP6_15, VI0_DATA6_VI0_B6), + PINMUX_IPSR_DATA(IP6_15, AVB_RXD5), + PINMUX_IPSR_DATA(IP6_16, VI0_DATA7_VI0_B7), + PINMUX_IPSR_DATA(IP6_16, AVB_RXD6), + PINMUX_IPSR_DATA(IP6_19_17, VI0_CLKENB), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, I2C3_SCL, SEL_I2C03_0), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, SCIFA5_RXD_C, SEL_SCIFA5_2), + PINMUX_IPSR_MODSEL_DATA(IP6_19_17, IETX_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP6_19_17, AVB_RXD7), + PINMUX_IPSR_DATA(IP6_22_20, VI0_FIELD), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, I2C3_SDA, SEL_I2C03_0), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCIFA5_TXD_C, SEL_SCIFA5_2), + PINMUX_IPSR_MODSEL_DATA(IP6_22_20, IECLK_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP6_22_20, AVB_RX_ER), + PINMUX_IPSR_DATA(IP6_25_23, VI0_HSYNC_N), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, SCIF0_RXD_B, SEL_SCIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, I2C0_SCL_C, SEL_I2C00_2), + PINMUX_IPSR_MODSEL_DATA(IP6_25_23, IERX_C, SEL_IEB_2), + PINMUX_IPSR_DATA(IP6_25_23, AVB_COL), + PINMUX_IPSR_DATA(IP6_28_26, VI0_VSYNC_N), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, SCIF0_TXD_B, SEL_SCIF0_1), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, I2C0_SDA_C, SEL_I2C00_2), + PINMUX_IPSR_MODSEL_DATA(IP6_28_26, AUDIO_CLKOUT_B, SEL_ADG_1), + PINMUX_IPSR_DATA(IP6_28_26, AVB_TX_EN), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, ETH_MDIO, SEL_ETH_0), + PINMUX_IPSR_DATA(IP6_31_29, VI0_G0), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, MSIOF2_RXD_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, IIC0_SCL_D, SEL_IIC00_3), + PINMUX_IPSR_DATA(IP6_31_29, AVB_TX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, ADIDATA, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP6_31_29, AD_DI, SEL_ADI_0), + + /* IPSR7 */ + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, ETH_CRS_DV, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_2_0, VI0_G1), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, MSIOF2_TXD_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, IIC0_SDA_D, SEL_IIC00_3), + PINMUX_IPSR_DATA(IP7_2_0, AVB_TXD0), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, ADICS_SAMP, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP7_2_0, AD_DO, SEL_ADI_0), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, ETH_RX_ER, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_5_3, VI0_G2), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, MSIOF2_SCK_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, CAN0_RX_B, SEL_CAN0_1), + PINMUX_IPSR_DATA(IP7_5_3, AVB_TXD1), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, ADICLK, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP7_5_3, AD_CLK, SEL_ADI_0), + PINMUX_IPSR_MODSEL_DATA(IP7_8_6, ETH_RXD0, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_8_6, VI0_G3), + PINMUX_IPSR_MODSEL_DATA(IP7_8_6, MSIOF2_SYNC_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP7_8_6, CAN0_TX_B, SEL_CAN0_1), + PINMUX_IPSR_DATA(IP7_8_6, AVB_TXD2), + PINMUX_IPSR_MODSEL_DATA(IP7_8_6, ADICHS0, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP7_8_6, AD_NCS_N, SEL_ADI_0), + PINMUX_IPSR_MODSEL_DATA(IP7_11_9, ETH_RXD1, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_11_9, VI0_G4), + PINMUX_IPSR_MODSEL_DATA(IP7_11_9, MSIOF2_SS1_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP7_11_9, SCIF4_RXD_D, SEL_SCIF4_3), + PINMUX_IPSR_DATA(IP7_11_9, AVB_TXD3), + PINMUX_IPSR_MODSEL_DATA(IP7_11_9, ADICHS1, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP7_14_12, ETH_LINK, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_14_12, VI0_G5), + PINMUX_IPSR_MODSEL_DATA(IP7_14_12, MSIOF2_SS2_B, SEL_MSI2_1), + PINMUX_IPSR_MODSEL_DATA(IP7_14_12, SCIF4_TXD_D, SEL_SCIF4_3), + PINMUX_IPSR_DATA(IP7_14_12, AVB_TXD4), + PINMUX_IPSR_MODSEL_DATA(IP7_14_12, ADICHS2, SEL_RAD_0), + PINMUX_IPSR_MODSEL_DATA(IP7_17_15, ETH_REFCLK, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_17_15, VI0_G6), + PINMUX_IPSR_MODSEL_DATA(IP7_17_15, SCIF2_SCK_C, SEL_SCIF2_2), + PINMUX_IPSR_DATA(IP7_17_15, AVB_TXD5), + PINMUX_IPSR_MODSEL_DATA(IP7_17_15, SSI_SCK5_B, SEL_SSI5_1), + PINMUX_IPSR_MODSEL_DATA(IP7_20_18, ETH_TXD1, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_20_18, VI0_G7), + PINMUX_IPSR_MODSEL_DATA(IP7_20_18, SCIF2_RXD_C, SEL_SCIF2_2), + PINMUX_IPSR_MODSEL_DATA(IP7_20_18, IIC1_SCL_D, SEL_IIC01_3), + PINMUX_IPSR_DATA(IP7_20_18, AVB_TXD6), + PINMUX_IPSR_MODSEL_DATA(IP7_20_18, SSI_WS5_B, SEL_SSI5_1), + PINMUX_IPSR_MODSEL_DATA(IP7_23_21, ETH_TX_EN, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_23_21, VI0_R0), + PINMUX_IPSR_MODSEL_DATA(IP7_23_21, SCIF2_TXD_C, SEL_SCIF2_2), + PINMUX_IPSR_MODSEL_DATA(IP7_23_21, IIC1_SDA_D, SEL_IIC01_3), + PINMUX_IPSR_DATA(IP7_23_21, AVB_TXD7), + PINMUX_IPSR_MODSEL_DATA(IP7_23_21, SSI_SDATA5_B, SEL_SSI5_1), + PINMUX_IPSR_MODSEL_DATA(IP7_26_24, ETH_MAGIC, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_26_24, VI0_R1), + PINMUX_IPSR_MODSEL_DATA(IP7_26_24, SCIF3_SCK_B, SEL_SCIF3_1), + PINMUX_IPSR_DATA(IP7_26_24, AVB_TX_ER), + PINMUX_IPSR_MODSEL_DATA(IP7_26_24, SSI_SCK6_B, SEL_SSI6_1), + PINMUX_IPSR_MODSEL_DATA(IP7_29_27, ETH_TXD0, SEL_ETH_0), + PINMUX_IPSR_DATA(IP7_29_27, VI0_R2), + PINMUX_IPSR_MODSEL_DATA(IP7_29_27, SCIF3_RXD_B, SEL_SCIF3_1), + PINMUX_IPSR_MODSEL_DATA(IP7_29_27, I2C4_SCL_E, SEL_I2C04_4), + PINMUX_IPSR_DATA(IP7_29_27, AVB_GTX_CLK), + PINMUX_IPSR_MODSEL_DATA(IP7_29_27, SSI_WS6_B, SEL_SSI6_1), + PINMUX_IPSR_DATA(IP7_31, DREQ0_N), + PINMUX_IPSR_DATA(IP7_31, SCIFB1_RXD), + + /* IPSR8 */ + PINMUX_IPSR_MODSEL_DATA(IP8_2_0, ETH_MDC, SEL_ETH_0), + PINMUX_IPSR_DATA(IP8_2_0, VI0_R3), + PINMUX_IPSR_MODSEL_DATA(IP8_2_0, SCIF3_TXD_B, SEL_SCIF3_1), + PINMUX_IPSR_MODSEL_DATA(IP8_2_0, I2C4_SDA_E, SEL_I2C04_4), + PINMUX_IPSR_DATA(IP8_2_0, AVB_MDC), + PINMUX_IPSR_MODSEL_DATA(IP8_2_0, SSI_SDATA6_B, SEL_SSI6_1), + PINMUX_IPSR_MODSEL_DATA(IP8_5_3, HSCIF0_HRX, SEL_HSCIF0_0), + PINMUX_IPSR_DATA(IP8_5_3, VI0_R4), + PINMUX_IPSR_MODSEL_DATA(IP8_5_3, I2C1_SCL_C, SEL_I2C01_2), + PINMUX_IPSR_MODSEL_DATA(IP8_5_3, AUDIO_CLKA_B, SEL_ADG_1), + PINMUX_IPSR_DATA(IP8_5_3, AVB_MDIO), + PINMUX_IPSR_MODSEL_DATA(IP8_5_3, SSI_SCK78_B, SEL_SSI7_1), + PINMUX_IPSR_MODSEL_DATA(IP8_8_6, HSCIF0_HTX, SEL_HSCIF0_0), + PINMUX_IPSR_DATA(IP8_8_6, VI0_R5), + PINMUX_IPSR_MODSEL_DATA(IP8_8_6, I2C1_SDA_C, SEL_I2C01_2), + PINMUX_IPSR_MODSEL_DATA(IP8_8_6, AUDIO_CLKB_B, SEL_ADG_1), + PINMUX_IPSR_DATA(IP8_5_3, AVB_LINK), + PINMUX_IPSR_MODSEL_DATA(IP8_8_6, SSI_WS78_B, SEL_SSI7_1), + PINMUX_IPSR_DATA(IP8_11_9, HSCIF0_HCTS_N), + PINMUX_IPSR_DATA(IP8_11_9, VI0_R6), + PINMUX_IPSR_MODSEL_DATA(IP8_11_9, SCIF0_RXD_D, SEL_SCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP8_11_9, I2C0_SCL_E, SEL_I2C00_4), + PINMUX_IPSR_DATA(IP8_11_9, AVB_MAGIC), + PINMUX_IPSR_MODSEL_DATA(IP8_11_9, SSI_SDATA7_B, SEL_SSI7_1), + PINMUX_IPSR_DATA(IP8_14_12, HSCIF0_HRTS_N), + PINMUX_IPSR_DATA(IP8_14_12, VI0_R7), + PINMUX_IPSR_MODSEL_DATA(IP8_14_12, SCIF0_TXD_D, SEL_SCIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP8_14_12, I2C0_SDA_E, SEL_I2C00_4), + PINMUX_IPSR_DATA(IP8_14_12, AVB_PHY_INT), + PINMUX_IPSR_MODSEL_DATA(IP8_14_12, SSI_SDATA8_B, SEL_SSI8_1), + PINMUX_IPSR_MODSEL_DATA(IP8_16_15, HSCIF0_HSCK, SEL_HSCIF0_0), + PINMUX_IPSR_MODSEL_DATA(IP8_16_15, SCIF_CLK_B, SEL_SCIF0_1), + PINMUX_IPSR_DATA(IP8_16_15, AVB_CRS), + PINMUX_IPSR_MODSEL_DATA(IP8_16_15, AUDIO_CLKC_B, SEL_ADG_1), + PINMUX_IPSR_MODSEL_DATA(IP8_19_17, I2C0_SCL, SEL_I2C00_0), + PINMUX_IPSR_MODSEL_DATA(IP8_19_17, SCIF0_RXD_C, SEL_SCIF0_2), + PINMUX_IPSR_DATA(IP8_19_17, PWM5), + PINMUX_IPSR_MODSEL_DATA(IP8_19_17, TCLK1_B, SEL_TMU_1), + PINMUX_IPSR_DATA(IP8_19_17, AVB_GTXREFCLK), + PINMUX_IPSR_MODSEL_DATA(IP8_19_17, CAN1_RX_D, SEL_CAN1_3), + PINMUX_IPSR_DATA(IP8_19_17, TPUTO0_B), + PINMUX_IPSR_MODSEL_DATA(IP8_22_20, I2C0_SDA, SEL_I2C00_0), + PINMUX_IPSR_MODSEL_DATA(IP8_22_20, SCIF0_TXD_C, SEL_SCIF0_2), + PINMUX_IPSR_DATA(IP8_22_20, TPUTO0), + PINMUX_IPSR_MODSEL_DATA(IP8_22_20, CAN_CLK, SEL_CAN_0), + PINMUX_IPSR_DATA(IP8_22_20, DVC_MUTE), + PINMUX_IPSR_MODSEL_DATA(IP8_22_20, CAN1_TX_D, SEL_CAN1_3), + PINMUX_IPSR_MODSEL_DATA(IP8_25_23, I2C1_SCL, SEL_I2C01_0), + PINMUX_IPSR_MODSEL_DATA(IP8_25_23, SCIF4_RXD, SEL_SCIF4_0), + PINMUX_IPSR_DATA(IP8_25_23, PWM5_B), + PINMUX_IPSR_DATA(IP8_25_23, DU1_DR0), + PINMUX_IPSR_MODSEL_DATA(IP8_25_23, RIF1_SYNC_B, SEL_DR2_1), + PINMUX_IPSR_MODSEL_DATA(IP8_25_23, TS_SDATA_D, SEL_TSIF0_3), + PINMUX_IPSR_DATA(IP8_25_23, TPUTO1_B), + PINMUX_IPSR_MODSEL_DATA(IP8_28_26, I2C1_SDA, SEL_I2C01_0), + PINMUX_IPSR_MODSEL_DATA(IP8_28_26, SCIF4_TXD, SEL_SCIF4_0), + PINMUX_IPSR_DATA(IP8_28_26, IRQ5), + PINMUX_IPSR_DATA(IP8_28_26, DU1_DR1), + PINMUX_IPSR_MODSEL_DATA(IP8_28_26, RIF1_CLK_B, SEL_DR2_1), + PINMUX_IPSR_MODSEL_DATA(IP8_28_26, TS_SCK_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP8_28_26, BPFCLK_C, SEL_DARC_2), + PINMUX_IPSR_DATA(IP8_31_29, MSIOF0_RXD), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, SCIF5_RXD, SEL_SCIF5_0), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, I2C2_SCL_C, SEL_I2C02_2), + PINMUX_IPSR_DATA(IP8_31_29, DU1_DR2), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, RIF1_D0_B, SEL_DR2_1), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, TS_SDEN_D, SEL_TSIF0_3), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, FMCLK_C, SEL_DARC_2), + PINMUX_IPSR_MODSEL_DATA(IP8_31_29, RDS_CLK, SEL_RDS_0), + + /* + * From IPSR9 to IPSR10 have been removed because they does not use. + */ + + /* IPSR11 */ + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SSI_WS5, SEL_SSI5_0), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SCIFA3_RXD, SEL_SCIFA3_0), + PINMUX_IPSR_MODSEL_DATA(IP11_2_0, I2C3_SCL_C, SEL_I2C03_2), + PINMUX_IPSR_DATA(IP11_2_0, DU1_DOTCLKOUT0), + PINMUX_IPSR_DATA(IP11_2_0, CAN_DEBUGOUT11), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SSI_SDATA5, SEL_SSI5_0), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SCIFA3_TXD, SEL_SCIFA3_0), + PINMUX_IPSR_MODSEL_DATA(IP11_5_3, I2C3_SDA_C, SEL_I2C03_2), + PINMUX_IPSR_DATA(IP11_5_3, DU1_DOTCLKOUT1), + PINMUX_IPSR_DATA(IP11_5_3, CAN_DEBUGOUT12), + PINMUX_IPSR_MODSEL_DATA(IP11_7_6, SSI_SCK6, SEL_SSI6_0), + PINMUX_IPSR_MODSEL_DATA(IP11_7_6, SCIFA1_SCK_B, SEL_SCIFA1_1), + PINMUX_IPSR_DATA(IP11_7_6, DU1_EXHSYNC_DU1_HSYNC), + PINMUX_IPSR_DATA(IP11_7_6, CAN_DEBUGOUT13), + PINMUX_IPSR_MODSEL_DATA(IP11_10_8, SSI_WS6, SEL_SSI6_0), + PINMUX_IPSR_MODSEL_DATA(IP11_10_8, SCIFA1_RXD_B, SEL_SCIFA1_1), + PINMUX_IPSR_MODSEL_DATA(IP11_10_8, I2C4_SCL_C, SEL_I2C04_2), + PINMUX_IPSR_DATA(IP11_10_8, DU1_EXVSYNC_DU1_VSYNC), + PINMUX_IPSR_DATA(IP11_10_8, CAN_DEBUGOUT14), + PINMUX_IPSR_MODSEL_DATA(IP11_13_11, SSI_SDATA6, SEL_SSI6_0), + PINMUX_IPSR_MODSEL_DATA(IP11_13_11, SCIFA1_TXD_B, SEL_SCIFA1_1), + PINMUX_IPSR_MODSEL_DATA(IP11_13_11, I2C4_SDA_C, SEL_I2C04_2), + PINMUX_IPSR_DATA(IP11_13_11, DU1_EXODDF_DU1_ODDF_DISP_CDE), + PINMUX_IPSR_DATA(IP11_13_11, CAN_DEBUGOUT15), + PINMUX_IPSR_MODSEL_DATA(IP11_15_14, SSI_SCK78, SEL_SSI7_0), + PINMUX_IPSR_MODSEL_DATA(IP11_15_14, SCIFA2_SCK_B, SEL_SCIFA2_1), + PINMUX_IPSR_MODSEL_DATA(IP11_15_14, IIC0_SDA_C, SEL_IIC00_2), + PINMUX_IPSR_DATA(IP11_15_14, DU1_DISP), + PINMUX_IPSR_MODSEL_DATA(IP11_17_16, SSI_WS78, SEL_SSI7_0), + PINMUX_IPSR_MODSEL_DATA(IP11_17_16, SCIFA2_RXD_B, SEL_SCIFA2_1), + PINMUX_IPSR_MODSEL_DATA(IP11_17_16, IIC0_SCL_C, SEL_IIC00_2), + PINMUX_IPSR_DATA(IP11_17_16, DU1_CDE), + PINMUX_IPSR_MODSEL_DATA(IP11_20_18, SSI_SDATA7, SEL_SSI7_0), + PINMUX_IPSR_MODSEL_DATA(IP11_20_18, SCIFA2_TXD_B, SEL_SCIFA2_1), + PINMUX_IPSR_DATA(IP11_20_18, IRQ8), + PINMUX_IPSR_MODSEL_DATA(IP11_20_18, AUDIO_CLKA_D, SEL_ADG_3), + PINMUX_IPSR_MODSEL_DATA(IP11_20_18, CAN_CLK_D, SEL_CAN_3), + PINMUX_IPSR_DATA(IP11_20_18, PCMOE_N), + PINMUX_IPSR_DATA(IP11_23_21, SSI_SCK0129), + PINMUX_IPSR_MODSEL_DATA(IP11_23_21, MSIOF1_RXD_B, SEL_MSI1_1), + PINMUX_IPSR_MODSEL_DATA(IP11_23_21, SCIF5_RXD_D, SEL_SCIF5_3), + PINMUX_IPSR_MODSEL_DATA(IP11_23_21, ADIDATA_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP11_23_21, AD_DI_B, SEL_ADI_1), + PINMUX_IPSR_DATA(IP11_23_21, PCMWE_N), + PINMUX_IPSR_DATA(IP11_26_24, SSI_WS0129), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, MSIOF1_TXD_B, SEL_MSI1_1), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SCIF5_TXD_D, SEL_SCIF5_3), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, ADICS_SAMP_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP11_26_24, AD_DO_B, SEL_ADI_1), + PINMUX_IPSR_DATA(IP11_29_27, SSI_SDATA0), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, MSIOF1_SCK_B, SEL_MSI1_1), + PINMUX_IPSR_DATA(IP11_29_27, PWM0_B), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, ADICLK_B, SEL_RAD_1), + PINMUX_IPSR_MODSEL_DATA(IP11_29_27, AD_CLK_B, SEL_ADI_1), + + /* + * From IPSR12 to IPSR13 have been removed because they does not use. + */ +}; + +static struct pinmux_gpio pinmux_gpios[] = { + PINMUX_GPIO_GP_ALL(), + + GPIO_FN(A2), GPIO_FN(WE0_N), GPIO_FN(WE1_N), GPIO_FN(DACK0), + GPIO_FN(USB0_PWEN), GPIO_FN(USB0_OVC), GPIO_FN(USB1_PWEN), + GPIO_FN(USB1_OVC), GPIO_FN(SD0_CLK), GPIO_FN(SD0_CMD), + GPIO_FN(SD0_DATA0), GPIO_FN(SD0_DATA1), GPIO_FN(SD0_DATA2), + GPIO_FN(SD0_DATA3), GPIO_FN(SD0_CD), GPIO_FN(SD0_WP), + GPIO_FN(SD1_CLK), GPIO_FN(SD1_CMD), GPIO_FN(SD1_DATA0), + GPIO_FN(SD1_DATA1), GPIO_FN(SD1_DATA2), GPIO_FN(SD1_DATA3), + + /* IPSR0 */ + GPIO_FN(SD1_CD), GPIO_FN(CAN0_RX), GPIO_FN(SD1_WP), GPIO_FN(IRQ7), + GPIO_FN(CAN0_TX), GPIO_FN(MMC_CLK), GPIO_FN(SD2_CLK), GPIO_FN(MMC_CMD), + GPIO_FN(SD2_CMD), GPIO_FN(MMC_D0), GPIO_FN(SD2_DATA0), GPIO_FN(MMC_D1), + GPIO_FN(SD2_DATA1), GPIO_FN(MMC_D2), GPIO_FN(SD2_DATA2), + GPIO_FN(MMC_D3), GPIO_FN(SD2_DATA3), GPIO_FN(MMC_D4), + GPIO_FN(SD2_CD), GPIO_FN(MMC_D5), GPIO_FN(SD2_WP), GPIO_FN(MMC_D6), + GPIO_FN(SCIF0_RXD), GPIO_FN(I2C2_SCL_B), GPIO_FN(CAN1_RX), + GPIO_FN(MMC_D7), GPIO_FN(SCIF0_TXD), GPIO_FN(I2C2_SDA_B), + GPIO_FN(CAN1_TX), GPIO_FN(D0), GPIO_FN(SCIFA3_SCK_B), GPIO_FN(IRQ4), + GPIO_FN(D1), GPIO_FN(SCIFA3_RXD_B), GPIO_FN(D2), GPIO_FN(SCIFA3_TXD_B), + GPIO_FN(D3), GPIO_FN(I2C3_SCL_B), GPIO_FN(SCIF5_RXD_B), GPIO_FN(D4), + GPIO_FN(I2C3_SDA_B), GPIO_FN(SCIF5_TXD_B), GPIO_FN(D5), + GPIO_FN(SCIF4_RXD_B), GPIO_FN(I2C0_SCL_D), + + /* + * From IPSR1 to IPSR5 have been removed because they does not use. + */ + + /* IPSR6 */ + GPIO_FN(DU0_EXVSYNC_DU0_VSYNC), GPIO_FN(QSTB_QHE), + GPIO_FN(CC50_STATE28), GPIO_FN(DU0_EXODDF_DU0_ODDF_DISP_CDE), + GPIO_FN(QCPV_QDE), GPIO_FN(CC50_STATE29), GPIO_FN(DU0_DISP), + GPIO_FN(QPOLA), GPIO_FN(CC50_STATE30), GPIO_FN(DU0_CDE), GPIO_FN(QPOLB), + GPIO_FN(CC50_STATE31), GPIO_FN(VI0_CLK), GPIO_FN(AVB_RX_CLK), + GPIO_FN(VI0_DATA0_VI0_B0), GPIO_FN(AVB_RX_DV), + GPIO_FN(VI0_DATA1_VI0_B1), GPIO_FN(AVB_RXD0), GPIO_FN(VI0_DATA2_VI0_B2), + GPIO_FN(AVB_RXD1), GPIO_FN(VI0_DATA3_VI0_B3), GPIO_FN(AVB_RXD2), + GPIO_FN(VI0_DATA4_VI0_B4), GPIO_FN(AVB_RXD3), GPIO_FN(VI0_DATA5_VI0_B5), + GPIO_FN(AVB_RXD4), GPIO_FN(VI0_DATA6_VI0_B6), GPIO_FN(AVB_RXD5), + GPIO_FN(VI0_DATA7_VI0_B7), GPIO_FN(AVB_RXD6), GPIO_FN(VI0_CLKENB), + GPIO_FN(I2C3_SCL), GPIO_FN(SCIFA5_RXD_C), GPIO_FN(IETX_C), + GPIO_FN(AVB_RXD7), GPIO_FN(VI0_FIELD), GPIO_FN(I2C3_SDA), + GPIO_FN(SCIFA5_TXD_C), GPIO_FN(IECLK_C), GPIO_FN(AVB_RX_ER), + GPIO_FN(VI0_HSYNC_N), GPIO_FN(SCIF0_RXD_B), GPIO_FN(I2C0_SCL_C), + GPIO_FN(IERX_C), GPIO_FN(AVB_COL), GPIO_FN(VI0_VSYNC_N), + GPIO_FN(SCIF0_TXD_B), GPIO_FN(I2C0_SDA_C), GPIO_FN(AUDIO_CLKOUT_B), + GPIO_FN(AVB_TX_EN), GPIO_FN(ETH_MDIO), GPIO_FN(VI0_G0), + GPIO_FN(MSIOF2_RXD_B), GPIO_FN(IIC0_SCL_D), GPIO_FN(AVB_TX_CLK), + GPIO_FN(ADIDATA), GPIO_FN(AD_DI), + + /* IPSR7 */ + GPIO_FN(ETH_CRS_DV), GPIO_FN(VI0_G1), GPIO_FN(MSIOF2_TXD_B), + GPIO_FN(IIC0_SDA_D), GPIO_FN(AVB_TXD0), GPIO_FN(ADICS_SAMP), + GPIO_FN(AD_DO), GPIO_FN(ETH_RX_ER), GPIO_FN(VI0_G2), + GPIO_FN(MSIOF2_SCK_B), GPIO_FN(CAN0_RX_B), GPIO_FN(AVB_TXD1), + GPIO_FN(ADICLK), GPIO_FN(AD_CLK), GPIO_FN(ETH_RXD0), GPIO_FN(VI0_G3), + GPIO_FN(MSIOF2_SYNC_B), GPIO_FN(CAN0_TX_B), GPIO_FN(AVB_TXD2), + GPIO_FN(ADICHS0), GPIO_FN(AD_NCS_N), GPIO_FN(ETH_RXD1), + GPIO_FN(VI0_G4), GPIO_FN(MSIOF2_SS1_B), GPIO_FN(SCIF4_RXD_D), + GPIO_FN(AVB_TXD3), GPIO_FN(ADICHS1), GPIO_FN(ETH_LINK), GPIO_FN(VI0_G5), + GPIO_FN(MSIOF2_SS2_B), GPIO_FN(SCIF4_TXD_D), GPIO_FN(AVB_TXD4), + GPIO_FN(ADICHS2), GPIO_FN(ETH_REFCLK), GPIO_FN(VI0_G6), + GPIO_FN(SCIF2_SCK_C), GPIO_FN(AVB_TXD5), GPIO_FN(SSI_SCK5_B), + GPIO_FN(ETH_TXD1), GPIO_FN(VI0_G7), GPIO_FN(SCIF2_RXD_C), + GPIO_FN(IIC1_SCL_D), GPIO_FN(AVB_TXD6), GPIO_FN(SSI_WS5_B), + GPIO_FN(ETH_TX_EN), GPIO_FN(VI0_R0), GPIO_FN(SCIF2_TXD_C), + GPIO_FN(IIC1_SDA_D), GPIO_FN(AVB_TXD7), GPIO_FN(SSI_SDATA5_B), + GPIO_FN(ETH_MAGIC), GPIO_FN(VI0_R1), GPIO_FN(SCIF3_SCK_B), + GPIO_FN(AVB_TX_ER), GPIO_FN(SSI_SCK6_B), GPIO_FN(ETH_TXD0), + GPIO_FN(VI0_R2), GPIO_FN(SCIF3_RXD_B), GPIO_FN(I2C4_SCL_E), + GPIO_FN(AVB_GTX_CLK), GPIO_FN(SSI_WS6_B), GPIO_FN(DREQ0_N), + GPIO_FN(SCIFB1_RXD), + + /* IPSR8 */ + GPIO_FN(ETH_MDC), GPIO_FN(VI0_R3), GPIO_FN(SCIF3_TXD_B), + GPIO_FN(I2C4_SDA_E), GPIO_FN(AVB_MDC), GPIO_FN(SSI_SDATA6_B), + GPIO_FN(HSCIF0_HRX), GPIO_FN(VI0_R4), GPIO_FN(I2C1_SCL_C), + GPIO_FN(AUDIO_CLKA_B), GPIO_FN(AVB_MDIO), GPIO_FN(SSI_SCK78_B), + GPIO_FN(HSCIF0_HTX), GPIO_FN(VI0_R5), GPIO_FN(I2C1_SDA_C), + GPIO_FN(AUDIO_CLKB_B), GPIO_FN(AVB_LINK), GPIO_FN(SSI_WS78_B), + GPIO_FN(HSCIF0_HCTS_N), GPIO_FN(VI0_R6), GPIO_FN(SCIF0_RXD_D), + GPIO_FN(I2C0_SCL_E), GPIO_FN(AVB_MAGIC), GPIO_FN(SSI_SDATA7_B), + GPIO_FN(HSCIF0_HRTS_N), GPIO_FN(VI0_R7), GPIO_FN(SCIF0_TXD_D), + GPIO_FN(I2C0_SDA_E), GPIO_FN(AVB_PHY_INT), GPIO_FN(SSI_SDATA8_B), + GPIO_FN(HSCIF0_HSCK), GPIO_FN(SCIF_CLK_B), GPIO_FN(AVB_CRS), + GPIO_FN(AUDIO_CLKC_B), GPIO_FN(I2C0_SCL), GPIO_FN(SCIF0_RXD_C), + GPIO_FN(PWM5), GPIO_FN(TCLK1_B), GPIO_FN(AVB_GTXREFCLK), + GPIO_FN(CAN1_RX_D), GPIO_FN(TPUTO0_B), GPIO_FN(I2C0_SDA), + GPIO_FN(SCIF0_TXD_C), GPIO_FN(TPUTO0), GPIO_FN(CAN_CLK), + GPIO_FN(DVC_MUTE), GPIO_FN(CAN1_TX_D), GPIO_FN(I2C1_SCL), + GPIO_FN(SCIF4_RXD), GPIO_FN(PWM5_B), GPIO_FN(DU1_DR0), + GPIO_FN(RIF1_SYNC_B), GPIO_FN(TS_SDATA_D), GPIO_FN(TPUTO1_B), + GPIO_FN(I2C1_SDA), GPIO_FN(SCIF4_TXD), GPIO_FN(IRQ5), + GPIO_FN(DU1_DR1), GPIO_FN(RIF1_CLK_B), GPIO_FN(TS_SCK_D), + GPIO_FN(BPFCLK_C), GPIO_FN(MSIOF0_RXD), GPIO_FN(SCIF5_RXD), + GPIO_FN(I2C2_SCL_C), GPIO_FN(DU1_DR2), GPIO_FN(RIF1_D0_B), + GPIO_FN(TS_SDEN_D), GPIO_FN(FMCLK_C), GPIO_FN(RDS_CLK), + + /* + * From IPSR9 to IPSR10 have been removed because they does not use. + */ + + /* IPSR11 */ + GPIO_FN(SSI_WS5), GPIO_FN(SCIFA3_RXD), GPIO_FN(I2C3_SCL_C), + GPIO_FN(DU1_DOTCLKOUT0), GPIO_FN(CAN_DEBUGOUT11), GPIO_FN(SSI_SDATA5), + GPIO_FN(SCIFA3_TXD), GPIO_FN(I2C3_SDA_C), GPIO_FN(DU1_DOTCLKOUT1), + GPIO_FN(CAN_DEBUGOUT12), GPIO_FN(SSI_SCK6), GPIO_FN(SCIFA1_SCK_B), + GPIO_FN(DU1_EXHSYNC_DU1_HSYNC), GPIO_FN(CAN_DEBUGOUT13), + GPIO_FN(SSI_WS6), GPIO_FN(SCIFA1_RXD_B), GPIO_FN(I2C4_SCL_C), + GPIO_FN(DU1_EXVSYNC_DU1_VSYNC), GPIO_FN(CAN_DEBUGOUT14), + GPIO_FN(SSI_SDATA6), GPIO_FN(SCIFA1_TXD_B), GPIO_FN(I2C4_SDA_C), + GPIO_FN(DU1_EXODDF_DU1_ODDF_DISP_CDE), GPIO_FN(CAN_DEBUGOUT15), + GPIO_FN(SSI_SCK78), GPIO_FN(SCIFA2_SCK_B), GPIO_FN(IIC0_SDA_C), + GPIO_FN(DU1_DISP), GPIO_FN(SSI_WS78), GPIO_FN(SCIFA2_RXD_B), + GPIO_FN(IIC0_SCL_C), GPIO_FN(DU1_CDE), GPIO_FN(SSI_SDATA7), + GPIO_FN(SCIFA2_TXD_B), GPIO_FN(IRQ8), GPIO_FN(AUDIO_CLKA_D), + GPIO_FN(CAN_CLK_D), GPIO_FN(PCMOE_N), GPIO_FN(SSI_SCK0129), + GPIO_FN(MSIOF1_RXD_B), GPIO_FN(SCIF5_RXD_D), GPIO_FN(ADIDATA_B), + GPIO_FN(AD_DI_B), GPIO_FN(PCMWE_N), GPIO_FN(SSI_WS0129), + GPIO_FN(MSIOF1_TXD_B), GPIO_FN(SCIF5_TXD_D), GPIO_FN(ADICS_SAMP_B), + GPIO_FN(AD_DO_B), GPIO_FN(SSI_SDATA0), GPIO_FN(MSIOF1_SCK_B), + GPIO_FN(PWM0_B), GPIO_FN(ADICLK_B), GPIO_FN(AD_CLK_B), + + /* + * From IPSR12 to IPSR13 have been removed because they does not use. + */ +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + { PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) { + GP_0_31_FN, FN_IP2_17_16, + GP_0_30_FN, FN_IP2_15_14, + GP_0_29_FN, FN_IP2_13_12, + GP_0_28_FN, FN_IP2_11_10, + GP_0_27_FN, FN_IP2_9_8, + GP_0_26_FN, FN_IP2_7_6, + GP_0_25_FN, FN_IP2_5_4, + GP_0_24_FN, FN_IP2_3_2, + GP_0_23_FN, FN_IP2_1_0, + GP_0_22_FN, FN_IP1_31_30, + GP_0_21_FN, FN_IP1_29_28, + GP_0_20_FN, FN_IP1_27, + GP_0_19_FN, FN_IP1_26, + GP_0_18_FN, FN_A2, + GP_0_17_FN, FN_IP1_24, + GP_0_16_FN, FN_IP1_23_22, + GP_0_15_FN, FN_IP1_21_20, + GP_0_14_FN, FN_IP1_19_18, + GP_0_13_FN, FN_IP1_17_15, + GP_0_12_FN, FN_IP1_14_13, + GP_0_11_FN, FN_IP1_12_11, + GP_0_10_FN, FN_IP1_10_8, + GP_0_9_FN, FN_IP1_7_6, + GP_0_8_FN, FN_IP1_5_4, + GP_0_7_FN, FN_IP1_3_2, + GP_0_6_FN, FN_IP1_1_0, + GP_0_5_FN, FN_IP0_31_30, + GP_0_4_FN, FN_IP0_29_28, + GP_0_3_FN, FN_IP0_27_26, + GP_0_2_FN, FN_IP0_25, + GP_0_1_FN, FN_IP0_24, + GP_0_0_FN, FN_IP0_23_22, } + }, + { PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_FN, FN_DACK0, + GP_1_24_FN, FN_IP7_31, + GP_1_23_FN, FN_IP4_1_0, + GP_1_22_FN, FN_WE1_N, + GP_1_21_FN, FN_WE0_N, + GP_1_20_FN, FN_IP3_31, + GP_1_19_FN, FN_IP3_30, + GP_1_18_FN, FN_IP3_29_27, + GP_1_17_FN, FN_IP3_26_24, + GP_1_16_FN, FN_IP3_23_21, + GP_1_15_FN, FN_IP3_20_18, + GP_1_14_FN, FN_IP3_17_15, + GP_1_13_FN, FN_IP3_14_13, + GP_1_12_FN, FN_IP3_12, + GP_1_11_FN, FN_IP3_11, + GP_1_10_FN, FN_IP3_10, + GP_1_9_FN, FN_IP3_9_8, + GP_1_8_FN, FN_IP3_7_6, + GP_1_7_FN, FN_IP3_5_4, + GP_1_6_FN, FN_IP3_3_2, + GP_1_5_FN, FN_IP3_1_0, + GP_1_4_FN, FN_IP2_31_30, + GP_1_3_FN, FN_IP2_29_27, + GP_1_2_FN, FN_IP2_26_24, + GP_1_1_FN, FN_IP2_23_21, + GP_1_0_FN, FN_IP2_20_18, } + }, + { PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) { + GP_2_31_FN, FN_IP6_7_6, + GP_2_30_FN, FN_IP6_5_4, + GP_2_29_FN, FN_IP6_3_2, + GP_2_28_FN, FN_IP6_1_0, + GP_2_27_FN, FN_IP5_31_30, + GP_2_26_FN, FN_IP5_29_28, + GP_2_25_FN, FN_IP5_27_26, + GP_2_24_FN, FN_IP5_25_24, + GP_2_23_FN, FN_IP5_23_22, + GP_2_22_FN, FN_IP5_21_20, + GP_2_21_FN, FN_IP5_19_18, + GP_2_20_FN, FN_IP5_17_16, + GP_2_19_FN, FN_IP5_15_14, + GP_2_18_FN, FN_IP5_13_12, + GP_2_17_FN, FN_IP5_11_9, + GP_2_16_FN, FN_IP5_8_6, + GP_2_15_FN, FN_IP5_5_4, + GP_2_14_FN, FN_IP5_3_2, + GP_2_13_FN, FN_IP5_1_0, + GP_2_12_FN, FN_IP4_31_30, + GP_2_11_FN, FN_IP4_29_28, + GP_2_10_FN, FN_IP4_27_26, + GP_2_9_FN, FN_IP4_25_23, + GP_2_8_FN, FN_IP4_22_20, + GP_2_7_FN, FN_IP4_19_18, + GP_2_6_FN, FN_IP4_17_16, + GP_2_5_FN, FN_IP4_15_14, + GP_2_4_FN, FN_IP4_13_12, + GP_2_3_FN, FN_IP4_11_10, + GP_2_2_FN, FN_IP4_9_8, + GP_2_1_FN, FN_IP4_7_5, + GP_2_0_FN, FN_IP4_4_2 } + }, + { PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) { + GP_3_31_FN, FN_IP8_22_20, + GP_3_30_FN, FN_IP8_19_17, + GP_3_29_FN, FN_IP8_16_15, + GP_3_28_FN, FN_IP8_14_12, + GP_3_27_FN, FN_IP8_11_9, + GP_3_26_FN, FN_IP8_8_6, + GP_3_25_FN, FN_IP8_5_3, + GP_3_24_FN, FN_IP8_2_0, + GP_3_23_FN, FN_IP7_29_27, + GP_3_22_FN, FN_IP7_26_24, + GP_3_21_FN, FN_IP7_23_21, + GP_3_20_FN, FN_IP7_20_18, + GP_3_19_FN, FN_IP7_17_15, + GP_3_18_FN, FN_IP7_14_12, + GP_3_17_FN, FN_IP7_11_9, + GP_3_16_FN, FN_IP7_8_6, + GP_3_15_FN, FN_IP7_5_3, + GP_3_14_FN, FN_IP7_2_0, + GP_3_13_FN, FN_IP6_31_29, + GP_3_12_FN, FN_IP6_28_26, + GP_3_11_FN, FN_IP6_25_23, + GP_3_10_FN, FN_IP6_22_20, + GP_3_9_FN, FN_IP6_19_17, + GP_3_8_FN, FN_IP6_16, + GP_3_7_FN, FN_IP6_15, + GP_3_6_FN, FN_IP6_14, + GP_3_5_FN, FN_IP6_13, + GP_3_4_FN, FN_IP6_12, + GP_3_3_FN, FN_IP6_11, + GP_3_2_FN, FN_IP6_10, + GP_3_1_FN, FN_IP6_9, + GP_3_0_FN, FN_IP6_8 } + }, + { PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) { + GP_4_31_FN, FN_IP11_17_16, + GP_4_30_FN, FN_IP11_15_14, + GP_4_29_FN, FN_IP11_13_11, + GP_4_28_FN, FN_IP11_10_8, + GP_4_27_FN, FN_IP11_7_6, + GP_4_26_FN, FN_IP11_5_3, + GP_4_25_FN, FN_IP11_2_0, + GP_4_24_FN, FN_IP10_31_30, + GP_4_23_FN, FN_IP10_29_27, + GP_4_22_FN, FN_IP10_26_24, + GP_4_21_FN, FN_IP10_23_21, + GP_4_20_FN, FN_IP10_20_18, + GP_4_19_FN, FN_IP10_17_15, + GP_4_18_FN, FN_IP10_14_12, + GP_4_17_FN, FN_IP10_11_9, + GP_4_16_FN, FN_IP10_8_6, + GP_4_15_FN, FN_IP10_5_3, + GP_4_14_FN, FN_IP10_2_0, + GP_4_13_FN, FN_IP9_30_28, + GP_4_12_FN, FN_IP9_27_25, + GP_4_11_FN, FN_IP9_24_22, + GP_4_10_FN, FN_IP9_21_19, + GP_4_9_FN, FN_IP9_18_17, + GP_4_8_FN, FN_IP9_16_15, + GP_4_7_FN, FN_IP9_14_12, + GP_4_6_FN, FN_IP9_11_9, + GP_4_5_FN, FN_IP9_8_6, + GP_4_4_FN, FN_IP9_5_3, + GP_4_3_FN, FN_IP9_2_0, + GP_4_2_FN, FN_IP8_31_29, + GP_4_1_FN, FN_IP8_28_26, + GP_4_0_FN, FN_IP8_25_23 } + }, + { PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_5_27_FN, FN_USB1_OVC, + GP_5_26_FN, FN_USB1_PWEN, + GP_5_25_FN, FN_USB0_OVC, + GP_5_24_FN, FN_USB0_PWEN, + GP_5_23_FN, FN_IP13_26_24, + GP_5_22_FN, FN_IP13_23_21, + GP_5_21_FN, FN_IP13_20_18, + GP_5_20_FN, FN_IP13_17_15, + GP_5_19_FN, FN_IP13_14_12, + GP_5_18_FN, FN_IP13_11_9, + GP_5_17_FN, FN_IP13_8_6, + GP_5_16_FN, FN_IP13_5_3, + GP_5_15_FN, FN_IP13_2_0, + GP_5_14_FN, FN_IP12_29_27, + GP_5_13_FN, FN_IP12_26_24, + GP_5_12_FN, FN_IP12_23_21, + GP_5_11_FN, FN_IP12_20_18, + GP_5_10_FN, FN_IP12_17_15, + GP_5_9_FN, FN_IP12_14_13, + GP_5_8_FN, FN_IP12_12_11, + GP_5_7_FN, FN_IP12_10_9, + GP_5_6_FN, FN_IP12_8_6, + GP_5_5_FN, FN_IP12_5_3, + GP_5_4_FN, FN_IP12_2_0, + GP_5_3_FN, FN_IP11_29_27, + GP_5_2_FN, FN_IP11_26_24, + GP_5_1_FN, FN_IP11_23_21, + GP_5_0_FN, FN_IP11_20_18 } + }, + { PINMUX_CFG_REG("GPSR6", 0xE606001C, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_6_25_FN, FN_IP0_21_20, + GP_6_24_FN, FN_IP0_19_18, + GP_6_23_FN, FN_IP0_17, + GP_6_22_FN, FN_IP0_16, + GP_6_21_FN, FN_IP0_15, + GP_6_20_FN, FN_IP0_14, + GP_6_19_FN, FN_IP0_13, + GP_6_18_FN, FN_IP0_12, + GP_6_17_FN, FN_IP0_11, + GP_6_16_FN, FN_IP0_10, + GP_6_15_FN, FN_IP0_9_8, + GP_6_14_FN, FN_IP0_0, + GP_6_13_FN, FN_SD1_DATA3, + GP_6_12_FN, FN_SD1_DATA2, + GP_6_11_FN, FN_SD1_DATA1, + GP_6_10_FN, FN_SD1_DATA0, + GP_6_9_FN, FN_SD1_CMD, + GP_6_8_FN, FN_SD1_CLK, + GP_6_7_FN, FN_SD0_WP, + GP_6_6_FN, FN_SD0_CD, + GP_6_5_FN, FN_SD0_DATA3, + GP_6_4_FN, FN_SD0_DATA2, + GP_6_3_FN, FN_SD0_DATA1, + GP_6_2_FN, FN_SD0_DATA0, + GP_6_1_FN, FN_SD0_CMD, + GP_6_0_FN, FN_SD0_CLK } + }, + { PINMUX_CFG_REG_VAR("IPSR0", 0xE6060020, 32, + 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1) { + /* IP0_31_30 [2] */ + FN_D5, FN_SCIF4_RXD_B, FN_I2C0_SCL_D, 0, + /* IP0_29_28 [2] */ + FN_D4, FN_I2C3_SDA_B, FN_SCIF5_TXD_B, 0, + /* IP0_27_26 [2] */ + FN_D3, FN_I2C3_SCL_B, FN_SCIF5_RXD_B, 0, + /* IP0_25 [1] */ + FN_D2, FN_SCIFA3_TXD_B, + /* IP0_24 [1] */ + FN_D1, FN_SCIFA3_RXD_B, + /* IP0_23_22 [2] */ + FN_D0, FN_SCIFA3_SCK_B, FN_IRQ4, 0, + /* IP0_21_20 [2] */ + FN_MMC_D7, FN_SCIF0_TXD, FN_I2C2_SDA_B, FN_CAN1_TX, + /* IP0_19_18 [2] */ + FN_MMC_D6, FN_SCIF0_RXD, FN_I2C2_SCL_B, FN_CAN1_RX, + /* IP0_17 [1] */ + FN_MMC_D5, FN_SD2_WP, + /* IP0_16 [1] */ + FN_MMC_D4, FN_SD2_CD, + /* IP0_15 [1] */ + FN_MMC_D3, FN_SD2_DATA3, + /* IP0_14 [1] */ + FN_MMC_D2, FN_SD2_DATA2, + /* IP0_13 [1] */ + FN_MMC_D1, FN_SD2_DATA1, + /* IP0_12 [1] */ + FN_MMC_D0, FN_SD2_DATA0, + /* IP0_11 [1] */ + FN_MMC_CMD, FN_SD2_CMD, + /* IP0_10 [1] */ + FN_MMC_CLK, FN_SD2_CLK, + /* IP0_9_8 [2] */ + FN_SD1_WP, FN_IRQ7, FN_CAN0_TX, 0, + /* IP0_7 [1] */ + 0, 0, + /* IP0_6 [1] */ + 0, 0, + /* IP0_5 [1] */ + 0, 0, + /* IP0_4 [1] */ + 0, 0, + /* IP0_3 [1] */ + 0, 0, + /* IP0_2 [1] */ + 0, 0, + /* IP0_1 [1] */ + 0, 0, + /* IP0_0 [1] */ + FN_SD1_CD, FN_CAN0_RX, } + }, + + /* + * From IPSR1 to IPSR5 have been removed because they does not use. + */ + + { PINMUX_CFG_REG_VAR("IPSR6", 0xE6060038, 32, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2) { + /* IP6_31_29 [3] */ + FN_ETH_MDIO, FN_VI0_G0, FN_MSIOF2_RXD_B, FN_IIC0_SCL_D, + FN_AVB_TX_CLK, FN_ADIDATA, FN_AD_DI, 0, + /* IP6_28_26 [3] */ + FN_VI0_VSYNC_N, FN_SCIF0_TXD_B, FN_I2C0_SDA_C, + FN_AUDIO_CLKOUT_B, FN_AVB_TX_EN, 0, 0, 0, + /* IP6_25_23 [3] */ + FN_VI0_HSYNC_N, FN_SCIF0_RXD_B, FN_I2C0_SCL_C, FN_IERX_C, + FN_AVB_COL, 0, 0, 0, + /* IP6_22_20 [3] */ + FN_VI0_FIELD, FN_I2C3_SDA, FN_SCIFA5_TXD_C, FN_IECLK_C, + FN_AVB_RX_ER, 0, 0, 0, + /* IP6_19_17 [3] */ + FN_VI0_CLKENB, FN_I2C3_SCL, FN_SCIFA5_RXD_C, FN_IETX_C, + FN_AVB_RXD7, 0, 0, 0, + /* IP6_16 [1] */ + FN_VI0_DATA7_VI0_B7, FN_AVB_RXD6, + /* IP6_15 [1] */ + FN_VI0_DATA6_VI0_B6, FN_AVB_RXD5, + /* IP6_14 [1] */ + FN_VI0_DATA5_VI0_B5, FN_AVB_RXD4, + /* IP6_13 [1] */ + FN_VI0_DATA4_VI0_B4, FN_AVB_RXD3, + /* IP6_12 [1] */ + FN_VI0_DATA3_VI0_B3, FN_AVB_RXD2, + /* IP6_11 [1] */ + FN_VI0_DATA2_VI0_B2, FN_AVB_RXD1, + /* IP6_10 [1] */ + FN_VI0_DATA1_VI0_B1, FN_AVB_RXD0, + /* IP6_9 [1] */ + FN_VI0_DATA0_VI0_B0, FN_AVB_RX_DV, + /* IP6_8 [1] */ + FN_VI0_CLK, FN_AVB_RX_CLK, + /* IP6_7_6 [2] */ + FN_DU0_CDE, FN_QPOLB, FN_CC50_STATE31, 0, + /* IP6_5_4 [2] */ + FN_DU0_DISP, FN_QPOLA, FN_CC50_STATE30, 0, + /* IP6_3_2 [2] */ + FN_DU0_EXODDF_DU0_ODDF_DISP_CDE, FN_QCPV_QDE, FN_CC50_STATE29, + /* IP6_1_0 [2] */ + FN_DU0_EXVSYNC_DU0_VSYNC, FN_QSTB_QHE, FN_CC50_STATE28, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) { + /* IP7_31 [1] */ + FN_DREQ0_N, FN_SCIFB1_RXD, + /* IP7_30 [1] */ + 0, 0, + /* IP7_29_27 [3] */ + FN_ETH_TXD0, FN_VI0_R2, FN_SCIF3_RXD_B, FN_I2C4_SCL_E, + FN_AVB_GTX_CLK, FN_SSI_WS6_B, 0, 0, + /* IP7_26_24 [3] */ + FN_ETH_MAGIC, FN_VI0_R1, FN_SCIF3_SCK_B, FN_AVB_TX_ER, + FN_SSI_SCK6_B, 0, 0, 0, + /* IP7_23_21 [3] */ + FN_ETH_TX_EN, FN_VI0_R0, FN_SCIF2_TXD_C, FN_IIC1_SDA_D, + FN_AVB_TXD7, FN_SSI_SDATA5_B, 0, 0, + /* IP7_20_18 [3] */ + FN_ETH_TXD1, FN_VI0_G7, FN_SCIF2_RXD_C, FN_IIC1_SCL_D, + FN_AVB_TXD6, FN_SSI_WS5_B, 0, 0, + /* IP7_17_15 [3] */ + FN_ETH_REFCLK, FN_VI0_G6, FN_SCIF2_SCK_C, FN_AVB_TXD5, + FN_SSI_SCK5_B, 0, 0, 0, + /* IP7_14_12 [3] */ + FN_ETH_LINK, FN_VI0_G5, FN_MSIOF2_SS2_B, FN_SCIF4_TXD_D, + FN_AVB_TXD4, FN_ADICHS2, 0, 0, + /* IP7_11_9 [3] */ + FN_ETH_RXD1, FN_VI0_G4, FN_MSIOF2_SS1_B, FN_SCIF4_RXD_D, + FN_AVB_TXD3, FN_ADICHS1, 0, 0, + /* IP7_8_6 [3] */ + FN_ETH_RXD0, FN_VI0_G3, FN_MSIOF2_SYNC_B, FN_CAN0_TX_B, + FN_AVB_TXD2, FN_ADICHS0, FN_AD_NCS_N, 0, + /* IP7_5_3 [3] */ + FN_ETH_RX_ER, FN_VI0_G2, FN_MSIOF2_SCK_B, FN_CAN0_RX_B, + FN_AVB_TXD1, FN_ADICLK, FN_AD_CLK, 0, + /* IP7_2_0 [3] */ + FN_ETH_CRS_DV, FN_VI0_G1, FN_MSIOF2_TXD_B, FN_IIC0_SDA_D, + FN_AVB_TXD0, FN_ADICS_SAMP, FN_AD_DO, 0, } + }, + { PINMUX_CFG_REG_VAR("IPSR8", 0xE6060040, 32, + 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3) { + /* IP8_31_29 [3] */ + FN_MSIOF0_RXD, FN_SCIF5_RXD, FN_I2C2_SCL_C, FN_DU1_DR2, + FN_RIF1_D0_B, FN_TS_SDEN_D, FN_FMCLK_C, FN_RDS_CLK, + /* IP8_28_26 [3] */ + FN_I2C1_SDA, FN_SCIF4_TXD, FN_IRQ5, FN_DU1_DR1, + FN_RIF1_CLK_B, FN_TS_SCK_D, FN_BPFCLK_C, 0, + /* IP8_25_23 [3] */ + FN_I2C1_SCL, FN_SCIF4_RXD, FN_PWM5_B, FN_DU1_DR0, + FN_RIF1_SYNC_B, FN_TS_SDATA_D, FN_TPUTO1_B, 0, + /* IP8_22_20 [3] */ + FN_I2C0_SDA, FN_SCIF0_TXD_C, FN_TPUTO0, FN_CAN_CLK, + FN_DVC_MUTE, FN_CAN1_TX_D, 0, 0, + /* IP8_19_17 [3] */ + FN_I2C0_SCL, FN_SCIF0_RXD_C, FN_PWM5, FN_TCLK1_B, + FN_AVB_GTXREFCLK, FN_CAN1_RX_D, FN_TPUTO0_B, 0, + /* IP8_16_15 [2] */ + FN_HSCIF0_HSCK, FN_SCIF_CLK_B, FN_AVB_CRS, FN_AUDIO_CLKC_B, + /* IP8_14_12 [3] */ + FN_HSCIF0_HRTS_N, FN_VI0_R7, FN_SCIF0_TXD_D, FN_I2C0_SDA_E, + FN_AVB_PHY_INT, FN_SSI_SDATA8_B, 0, 0, + /* IP8_11_9 [3] */ + FN_HSCIF0_HCTS_N, FN_VI0_R6, FN_SCIF0_RXD_D, FN_I2C0_SCL_E, + FN_AVB_MAGIC, FN_SSI_SDATA7_B, 0, 0, + /* IP8_8_6 [3] */ + FN_HSCIF0_HTX, FN_VI0_R5, FN_I2C1_SDA_C, FN_AUDIO_CLKB_B, + FN_AVB_LINK, FN_SSI_WS78_B, 0, 0, + /* IP8_5_3 [3] */ + FN_HSCIF0_HRX, FN_VI0_R4, FN_I2C1_SCL_C, FN_AUDIO_CLKA_B, + FN_AVB_MDIO, FN_SSI_SCK78_B, 0, 0, + /* IP8_2_0 [3] */ + FN_ETH_MDC, FN_VI0_R3, FN_SCIF3_TXD_B, FN_I2C4_SDA_E, + FN_AVB_MDC, FN_SSI_SDATA6_B, 0, 0, } + }, + + /* + * From IPSR9 to IPSR10 have been removed because they does not use. + */ + + { PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32, + 2, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3) { + /* IP11_31_30 [2] */ + 0, 0, 0, 0, + /* IP11_29_27 [3] */ + FN_SSI_SDATA0, FN_MSIOF1_SCK_B, FN_PWM0_B, FN_ADICLK_B, + FN_AD_CLK_B, 0, 0, 0, + /* IP11_26_24 [3] */ + FN_SSI_WS0129, FN_MSIOF1_TXD_B, FN_SCIF5_TXD_D, FN_ADICS_SAMP_B, + FN_AD_DO_B, 0, 0, 0, + /* IP11_23_21 [3] */ + FN_SSI_SCK0129, FN_MSIOF1_RXD_B, FN_SCIF5_RXD_D, FN_ADIDATA_B, + FN_AD_DI_B, FN_PCMWE_N, 0, 0, + /* IP11_20_18 [3] */ + FN_SSI_SDATA7, FN_SCIFA2_TXD_B, FN_IRQ8, FN_AUDIO_CLKA_D, + FN_CAN_CLK_D, FN_PCMOE_N, 0, 0, + /* IP11_17_16 [2] */ + FN_SSI_WS78, FN_SCIFA2_RXD_B, FN_IIC0_SCL_C, FN_DU1_CDE, + /* IP11_15_14 [2] */ + FN_SSI_SCK78, FN_SCIFA2_SCK_B, FN_IIC0_SDA_C, FN_DU1_DISP, + /* IP11_13_11 [3] */ + FN_SSI_SDATA6, FN_SCIFA1_TXD_B, FN_I2C4_SDA_C, + FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_CAN_DEBUGOUT15, 0, 0, 0, + /* IP11_10_8 [3] */ + FN_SSI_WS6, FN_SCIFA1_RXD_B, FN_I2C4_SCL_C, + FN_DU1_EXVSYNC_DU1_VSYNC, FN_CAN_DEBUGOUT14, 0, 0, 0, + /* IP11_7_6 [2] */ + FN_SSI_SCK6, FN_SCIFA1_SCK_B, FN_DU1_EXHSYNC_DU1_HSYNC, + FN_CAN_DEBUGOUT13, + /* IP11_5_3 [3] */ + FN_SSI_SDATA5, FN_SCIFA3_TXD, FN_I2C3_SDA_C, FN_DU1_DOTCLKOUT1, + FN_CAN_DEBUGOUT12, 0, 0, 0, + /* IP11_2_0 [3] */ + FN_SSI_WS5, FN_SCIFA3_RXD, FN_I2C3_SCL_C, FN_DU1_DOTCLKOUT0, + FN_CAN_DEBUGOUT11, 0, 0, 0, } + }, + + /* + * From IPSR12 to IPSR13 have been removed because they does not use. + */ + + { PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32, + 2, 1, 2, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 2, 1) { + /* SEL_ADG [2] */ + FN_SEL_ADG_0, FN_SEL_ADG_1, FN_SEL_ADG_2, FN_SEL_ADG_3, + /* SEL_ADI [1] */ + FN_SEL_ADI_0, FN_SEL_ADI_1, + /* SEL_CAN [2] */ + FN_SEL_CAN_0, FN_SEL_CAN_1, FN_SEL_CAN_2, FN_SEL_CAN_3, + /* SEL_DARC [3] */ + FN_SEL_DARC_0, FN_SEL_DARC_1, FN_SEL_DARC_2, FN_SEL_DARC_3, + FN_SEL_DARC_4, 0, 0, 0, + /* SEL_DR0 [1] */ + FN_SEL_DR0_0, FN_SEL_DR0_1, + /* SEL_DR1 [1] */ + FN_SEL_DR1_0, FN_SEL_DR1_1, + /* SEL_DR2 [1] */ + FN_SEL_DR2_0, FN_SEL_DR2_1, + /* SEL_DR3 [1] */ + FN_SEL_DR3_0, FN_SEL_DR3_1, + /* SEL_ETH [1] */ + FN_SEL_ETH_0, FN_SEL_ETH_1, + /* SLE_FSN [1] */ + FN_SEL_FSN_0, FN_SEL_FSN_1, + /* SEL_IC200 [3] */ + FN_SEL_I2C00_0, FN_SEL_I2C00_1, FN_SEL_I2C00_2, FN_SEL_I2C00_3, + FN_SEL_I2C00_4, 0, 0, 0, + /* SEL_I2C01 [3] */ + FN_SEL_I2C01_0, FN_SEL_I2C01_1, FN_SEL_I2C01_2, FN_SEL_I2C01_3, + FN_SEL_I2C01_4, 0, 0, 0, + /* SEL_I2C02 [3] */ + FN_SEL_I2C02_0, FN_SEL_I2C02_1, FN_SEL_I2C02_2, FN_SEL_I2C02_3, + FN_SEL_I2C02_4, 0, 0, 0, + /* SEL_I2C03 [3] */ + FN_SEL_I2C03_0, FN_SEL_I2C03_1, FN_SEL_I2C03_2, FN_SEL_I2C03_3, + FN_SEL_I2C03_4, 0, 0, 0, + /* SEL_I2C04 [3] */ + FN_SEL_I2C04_0, FN_SEL_I2C04_1, FN_SEL_I2C04_2, FN_SEL_I2C04_3, + FN_SEL_I2C04_4, 0, 0, 0, + /* SEL_IIC00 [2] */ + FN_SEL_IIC00_0, FN_SEL_IIC00_1, FN_SEL_IIC00_2, FN_SEL_IIC00_3, + /* SEL_AVB [1] */ + FN_SEL_AVB_0, FN_SEL_AVB_1, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32, + 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, + 2, 2, 2, 1, 1, 2) { + /* SEL_IEB [2] */ + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0, + /* SEL_IIC0 [2] */ + FN_SEL_IIC01_0, FN_SEL_IIC01_1, FN_SEL_IIC01_2, FN_SEL_IIC01_3, + /* SEL_LBS [1] */ + FN_SEL_LBS_0, FN_SEL_LBS_1, + /* SEL_MSI1 [1] */ + FN_SEL_MSI1_0, FN_SEL_MSI1_1, + /* SEL_MSI2 [1] */ + FN_SEL_MSI2_0, FN_SEL_MSI2_1, + /* SEL_RAD [1] */ + FN_SEL_RAD_0, FN_SEL_RAD_1, + /* SEL_RCN [1] */ + FN_SEL_RCN_0, FN_SEL_RCN_1, + /* SEL_RSP [1] */ + FN_SEL_RSP_0, FN_SEL_RSP_1, + /* SEL_SCIFA0 [2] */ + FN_SEL_SCIFA0_0, FN_SEL_SCIFA0_1, FN_SEL_SCIFA0_2, + FN_SEL_SCIFA0_3, + /* SEL_SCIFA1 [2] */ + FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, 0, + /* SEL_SCIFA2 [1] */ + FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, + /* SEL_SCIFA3 [1] */ + FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, + /* SEL_SCIFA4 [2] */ + FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, + FN_SEL_SCIFA4_3, + /* SEL_SCIFA5 [2] */ + FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, + FN_SEL_SCIFA5_3, + /* SEL_SPDM [1] */ + FN_SEL_SPDM_0, FN_SEL_SPDM_1, + /* SEL_TMU [1] */ + FN_SEL_TMU_0, FN_SEL_TMU_1, + /* SEL_TSIF0 [2] */ + FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, + /* SEL_CAN0 [2] */ + FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, + /* SEL_CAN1 [2] */ + FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, + /* SEL_HSCIF0 [1] */ + FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, + /* SEL_HSCIF1 [1] */ + FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, + /* SEL_RDS [2] */ + FN_SEL_RDS_0, FN_SEL_RDS_1, FN_SEL_RDS_2, FN_SEL_RDS_3, } + }, + { PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32, + 2, 2, 2, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) { + /* SEL_SCIF0 [2] */ + FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3, + /* SEL_SCIF1 [2] */ + FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, 0, + /* SEL_SCIF2 [2] */ + FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, 0, + /* SEL_SCIF3 [1] */ + FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, + /* SEL_SCIF4 [3] */ + FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, FN_SEL_SCIF4_3, + FN_SEL_SCIF4_4, 0, 0, 0, + /* SEL_SCIF5 [2] */ + FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, FN_SEL_SCIF5_2, FN_SEL_SCIF5_3, + /* SEL_SSI1 [1] */ + FN_SEL_SSI1_0, FN_SEL_SSI1_1, + /* SEL_SSI2 [1] */ + FN_SEL_SSI2_0, FN_SEL_SSI2_1, + /* SEL_SSI4 [1] */ + FN_SEL_SSI4_0, FN_SEL_SSI4_1, + /* SEL_SSI5 [1] */ + FN_SEL_SSI5_0, FN_SEL_SSI5_1, + /* SEL_SSI6 [1] */ + FN_SEL_SSI6_0, FN_SEL_SSI6_1, + /* SEL_SSI7 [1] */ + FN_SEL_SSI7_0, FN_SEL_SSI7_1, + /* SEL_SSI8 [1] */ + FN_SEL_SSI8_0, FN_SEL_SSI8_1, + /* SEL_SSI9 [1] */ + FN_SEL_SSI9_0, FN_SEL_SSI9_1, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, + /* RESEVED [1] */ + 0, 0, } + }, + { PINMUX_CFG_REG("INOUTSEL0", 0xE6050004, 32, 1) { GP_INOUTSEL(0) } }, + { PINMUX_CFG_REG("INOUTSEL1", 0xE6051004, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_1_25_IN, GP_1_25_OUT, + GP_1_24_IN, GP_1_24_OUT, + GP_1_23_IN, GP_1_23_OUT, + GP_1_22_IN, GP_1_22_OUT, + GP_1_21_IN, GP_1_21_OUT, + GP_1_20_IN, GP_1_20_OUT, + GP_1_19_IN, GP_1_19_OUT, + GP_1_18_IN, GP_1_18_OUT, + GP_1_17_IN, GP_1_17_OUT, + GP_1_16_IN, GP_1_16_OUT, + GP_1_15_IN, GP_1_15_OUT, + GP_1_14_IN, GP_1_14_OUT, + GP_1_13_IN, GP_1_13_OUT, + GP_1_12_IN, GP_1_12_OUT, + GP_1_11_IN, GP_1_11_OUT, + GP_1_10_IN, GP_1_10_OUT, + GP_1_9_IN, GP_1_9_OUT, + GP_1_8_IN, GP_1_8_OUT, + GP_1_7_IN, GP_1_7_OUT, + GP_1_6_IN, GP_1_6_OUT, + GP_1_5_IN, GP_1_5_OUT, + GP_1_4_IN, GP_1_4_OUT, + GP_1_3_IN, GP_1_3_OUT, + GP_1_2_IN, GP_1_2_OUT, + GP_1_1_IN, GP_1_1_OUT, + GP_1_0_IN, GP_1_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL2", 0xE6052004, 32, 1) { GP_INOUTSEL(2) } }, + { PINMUX_CFG_REG("INOUTSEL3", 0xE6053004, 32, 1) { GP_INOUTSEL(3) } }, + { PINMUX_CFG_REG("INOUTSEL4", 0xE6054004, 32, 1) { GP_INOUTSEL(4) } }, + { PINMUX_CFG_REG("INOUTSEL5", 0xE6055004, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_5_27_IN, GP_5_27_OUT, + GP_5_26_IN, GP_5_26_OUT, + GP_5_25_IN, GP_5_25_OUT, + GP_5_24_IN, GP_5_24_OUT, + GP_5_23_IN, GP_5_23_OUT, + GP_5_22_IN, GP_5_22_OUT, + GP_5_21_IN, GP_5_21_OUT, + GP_5_20_IN, GP_5_20_OUT, + GP_5_19_IN, GP_5_19_OUT, + GP_5_18_IN, GP_5_18_OUT, + GP_5_17_IN, GP_5_17_OUT, + GP_5_16_IN, GP_5_16_OUT, + GP_5_15_IN, GP_5_15_OUT, + GP_5_14_IN, GP_5_14_OUT, + GP_5_13_IN, GP_5_13_OUT, + GP_5_12_IN, GP_5_12_OUT, + GP_5_11_IN, GP_5_11_OUT, + GP_5_10_IN, GP_5_10_OUT, + GP_5_9_IN, GP_5_9_OUT, + GP_5_8_IN, GP_5_8_OUT, + GP_5_7_IN, GP_5_7_OUT, + GP_5_6_IN, GP_5_6_OUT, + GP_5_5_IN, GP_5_5_OUT, + GP_5_4_IN, GP_5_4_OUT, + GP_5_3_IN, GP_5_3_OUT, + GP_5_2_IN, GP_5_2_OUT, + GP_5_1_IN, GP_5_1_OUT, + GP_5_0_IN, GP_5_0_OUT, } + }, + { PINMUX_CFG_REG("INOUTSEL6", 0xE6055404, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + GP_6_25_IN, GP_6_25_OUT, + GP_6_24_IN, GP_6_24_OUT, + GP_6_23_IN, GP_6_23_OUT, + GP_6_22_IN, GP_6_22_OUT, + GP_6_21_IN, GP_6_21_OUT, + GP_6_20_IN, GP_6_20_OUT, + GP_6_19_IN, GP_6_19_OUT, + GP_6_18_IN, GP_6_18_OUT, + GP_6_17_IN, GP_6_17_OUT, + GP_6_16_IN, GP_6_16_OUT, + GP_6_15_IN, GP_6_15_OUT, + GP_6_14_IN, GP_6_14_OUT, + GP_6_13_IN, GP_6_13_OUT, + GP_6_12_IN, GP_6_12_OUT, + GP_6_11_IN, GP_6_11_OUT, + GP_6_10_IN, GP_6_10_OUT, + GP_6_9_IN, GP_6_9_OUT, + GP_6_8_IN, GP_6_8_OUT, + GP_6_7_IN, GP_6_7_OUT, + GP_6_6_IN, GP_6_6_OUT, + GP_6_5_IN, GP_6_5_OUT, + GP_6_4_IN, GP_6_4_OUT, + GP_6_3_IN, GP_6_3_OUT, + GP_6_2_IN, GP_6_2_OUT, + GP_6_1_IN, GP_6_1_OUT, + GP_6_0_IN, GP_6_0_OUT, } + }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("INDT0", 0xE6050008, 32) { GP_INDT(0) } }, + { PINMUX_DATA_REG("INDT1", 0xE6051008, 32) { + 0, 0, 0, 0, + 0, 0, GP_1_25_DATA, GP_1_24_DATA, + GP_1_23_DATA, GP_1_22_DATA, GP_1_21_DATA, GP_1_20_DATA, + GP_1_19_DATA, GP_1_18_DATA, GP_1_17_DATA, GP_1_16_DATA, + GP_1_15_DATA, GP_1_14_DATA, GP_1_13_DATA, GP_1_12_DATA, + GP_1_11_DATA, GP_1_10_DATA, GP_1_9_DATA, GP_1_8_DATA, + GP_1_7_DATA, GP_1_6_DATA, GP_1_5_DATA, GP_1_4_DATA, + GP_1_3_DATA, GP_1_2_DATA, GP_1_1_DATA, GP_1_0_DATA } + }, + { PINMUX_DATA_REG("INDT2", 0xE6052008, 32) { GP_INDT(2) } }, + { PINMUX_DATA_REG("INDT3", 0xE6053008, 32) { GP_INDT(3) } }, + { PINMUX_DATA_REG("INDT4", 0xE6054008, 32) { GP_INDT(4) } }, + { PINMUX_DATA_REG("INDT5", 0xE6055008, 32) { + 0, 0, 0, 0, + GP_5_27_DATA, GP_5_26_DATA, GP_5_25_DATA, GP_5_24_DATA, + GP_5_23_DATA, GP_5_22_DATA, GP_5_21_DATA, GP_5_20_DATA, + GP_5_19_DATA, GP_5_18_DATA, GP_5_17_DATA, GP_5_16_DATA, + GP_5_15_DATA, GP_5_14_DATA, GP_5_13_DATA, GP_5_12_DATA, + GP_5_11_DATA, GP_5_10_DATA, GP_5_9_DATA, GP_5_8_DATA, + GP_5_7_DATA, GP_5_6_DATA, GP_5_5_DATA, GP_5_4_DATA, + GP_5_3_DATA, GP_5_2_DATA, GP_5_1_DATA, GP_5_0_DATA } + }, + { PINMUX_DATA_REG("INDT6", 0xE6055408, 32) { + 0, 0, 0, 0, + 0, 0, GP_6_25_DATA, GP_6_24_DATA, + GP_6_23_DATA, GP_6_22_DATA, GP_6_21_DATA, GP_6_20_DATA, + GP_6_19_DATA, GP_6_18_DATA, GP_6_17_DATA, GP_6_16_DATA, + GP_6_15_DATA, GP_6_14_DATA, GP_6_13_DATA, GP_6_12_DATA, + GP_6_11_DATA, GP_6_10_DATA, GP_6_9_DATA, GP_6_8_DATA, + GP_6_7_DATA, GP_6_6_DATA, GP_6_5_DATA, GP_6_4_DATA, + GP_6_3_DATA, GP_6_2_DATA, GP_6_1_DATA, GP_6_0_DATA } + }, + { }, +}; + +static struct pinmux_info r8a7794_pinmux_info = { + .name = "r8a7794_pfc", + + .unlock_reg = 0xe6060000, /* PMMR */ + + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_GP_0_0, + .last_gpio = GPIO_FN_AD_CLK_B, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), +}; + +void r8a7794_pinmux_init(void) +{ + register_pinmux(&r8a7794_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-sh73a0.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-sh73a0.c new file mode 100644 index 0000000..55dab7c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/pfc-sh73a0.c
@@ -0,0 +1,2807 @@ +/* + * sh73a0 processor support - PFC hardware block + * + * Copyright (C) 2010 Renesas Solutions Corp. + * Copyright (C) 2010 NISHIMOTO Hiroki + * + * 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <common.h> +#include <sh_pfc.h> +#include <asm/arch/sh73a0-gpio.h> + +#define CPU_ALL_PORT(fn, pfx, sfx) \ + PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \ + PORT_10(fn, pfx##2, sfx), PORT_10(fn, pfx##3, sfx), \ + PORT_10(fn, pfx##4, sfx), PORT_10(fn, pfx##5, sfx), \ + PORT_10(fn, pfx##6, sfx), PORT_10(fn, pfx##7, sfx), \ + PORT_10(fn, pfx##8, sfx), PORT_10(fn, pfx##9, sfx), \ + PORT_10(fn, pfx##10, sfx), \ + PORT_1(fn, pfx##110, sfx), PORT_1(fn, pfx##111, sfx), \ + PORT_1(fn, pfx##112, sfx), PORT_1(fn, pfx##113, sfx), \ + PORT_1(fn, pfx##114, sfx), PORT_1(fn, pfx##115, sfx), \ + PORT_1(fn, pfx##116, sfx), PORT_1(fn, pfx##117, sfx), \ + PORT_1(fn, pfx##118, sfx), \ + PORT_1(fn, pfx##128, sfx), PORT_1(fn, pfx##129, sfx), \ + PORT_10(fn, pfx##13, sfx), PORT_10(fn, pfx##14, sfx), \ + PORT_10(fn, pfx##15, sfx), \ + PORT_1(fn, pfx##160, sfx), PORT_1(fn, pfx##161, sfx), \ + PORT_1(fn, pfx##162, sfx), PORT_1(fn, pfx##163, sfx), \ + PORT_1(fn, pfx##164, sfx), \ + PORT_1(fn, pfx##192, sfx), PORT_1(fn, pfx##193, sfx), \ + PORT_1(fn, pfx##194, sfx), PORT_1(fn, pfx##195, sfx), \ + PORT_1(fn, pfx##196, sfx), PORT_1(fn, pfx##197, sfx), \ + PORT_1(fn, pfx##198, sfx), PORT_1(fn, pfx##199, sfx), \ + PORT_10(fn, pfx##20, sfx), PORT_10(fn, pfx##21, sfx), \ + PORT_10(fn, pfx##22, sfx), PORT_10(fn, pfx##23, sfx), \ + PORT_10(fn, pfx##24, sfx), PORT_10(fn, pfx##25, sfx), \ + PORT_10(fn, pfx##26, sfx), PORT_10(fn, pfx##27, sfx), \ + PORT_1(fn, pfx##280, sfx), PORT_1(fn, pfx##281, sfx), \ + PORT_1(fn, pfx##282, sfx), \ + PORT_1(fn, pfx##288, sfx), PORT_1(fn, pfx##289, sfx), \ + PORT_10(fn, pfx##29, sfx), PORT_10(fn, pfx##30, sfx) + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + PORT_ALL(DATA), /* PORT0_DATA -> PORT309_DATA */ + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + PORT_ALL(IN), /* PORT0_IN -> PORT309_IN */ + PINMUX_INPUT_END, + + PINMUX_INPUT_PULLUP_BEGIN, + PORT_ALL(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */ + PINMUX_INPUT_PULLUP_END, + + PINMUX_INPUT_PULLDOWN_BEGIN, + PORT_ALL(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */ + PINMUX_INPUT_PULLDOWN_END, + + PINMUX_OUTPUT_BEGIN, + PORT_ALL(OUT), /* PORT0_OUT -> PORT309_OUT */ + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT309_FN_IN */ + PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT309_FN_OUT */ + PORT_ALL(FN0), /* PORT0_FN0 -> PORT309_FN0 */ + PORT_ALL(FN1), /* PORT0_FN1 -> PORT309_FN1 */ + PORT_ALL(FN2), /* PORT0_FN2 -> PORT309_FN2 */ + PORT_ALL(FN3), /* PORT0_FN3 -> PORT309_FN3 */ + PORT_ALL(FN4), /* PORT0_FN4 -> PORT309_FN4 */ + PORT_ALL(FN5), /* PORT0_FN5 -> PORT309_FN5 */ + PORT_ALL(FN6), /* PORT0_FN6 -> PORT309_FN6 */ + PORT_ALL(FN7), /* PORT0_FN7 -> PORT309_FN7 */ + + MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1, + MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1, + MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1, + MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1, + MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1, + MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1, + MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1, + MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1, + MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1, + MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1, + MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1, + MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1, + MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1, + MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1, + MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1, + MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1, + MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1, + MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1, + MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1, + MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_1, + MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1, + MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1, + MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1, + MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1, + MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1, + MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1, + MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1, + MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1, + MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1, + MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1, + MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1, + MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1, + MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1, + MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1, + MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1, + MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1, + MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1, + MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1, + MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1, + MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1, + MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + /* Hardware manual Table 25-1 (Function 0-7) */ + VBUS_0_MARK, + GPI0_MARK, + GPI1_MARK, + GPI2_MARK, + GPI3_MARK, + GPI4_MARK, + GPI5_MARK, + GPI6_MARK, + GPI7_MARK, + SCIFA7_RXD_MARK, + SCIFA7_CTS__MARK, + GPO7_MARK, MFG0_OUT2_MARK, + GPO6_MARK, MFG1_OUT2_MARK, + GPO5_MARK, SCIFA0_SCK_MARK, FSICOSLDT3_MARK, PORT16_VIO_CKOR_MARK, + SCIFA0_TXD_MARK, + SCIFA7_TXD_MARK, + SCIFA7_RTS__MARK, PORT19_VIO_CKO2_MARK, + GPO0_MARK, + GPO1_MARK, + GPO2_MARK, STATUS0_MARK, + GPO3_MARK, STATUS1_MARK, + GPO4_MARK, STATUS2_MARK, + VINT_MARK, + TCKON_MARK, + XDVFS1_MARK, PORT27_I2C_SCL2_MARK, PORT27_I2C_SCL3_MARK, \ + MFG0_OUT1_MARK, PORT27_IROUT_MARK, + XDVFS2_MARK, PORT28_I2C_SDA2_MARK, PORT28_I2C_SDA3_MARK, \ + PORT28_TPU1TO1_MARK, + SIM_RST_MARK, PORT29_TPU1TO1_MARK, + SIM_CLK_MARK, PORT30_VIO_CKOR_MARK, + SIM_D_MARK, PORT31_IROUT_MARK, + SCIFA4_TXD_MARK, + SCIFA4_RXD_MARK, XWUP_MARK, + SCIFA4_RTS__MARK, + SCIFA4_CTS__MARK, + FSIBOBT_MARK, FSIBIBT_MARK, + FSIBOLR_MARK, FSIBILR_MARK, + FSIBOSLD_MARK, + FSIBISLD_MARK, + VACK_MARK, + XTAL1L_MARK, + SCIFA0_RTS__MARK, FSICOSLDT2_MARK, + SCIFA0_RXD_MARK, + SCIFA0_CTS__MARK, FSICOSLDT1_MARK, + FSICOBT_MARK, FSICIBT_MARK, FSIDOBT_MARK, FSIDIBT_MARK, + FSICOLR_MARK, FSICILR_MARK, FSIDOLR_MARK, FSIDILR_MARK, + FSICOSLD_MARK, PORT47_FSICSPDIF_MARK, + FSICISLD_MARK, FSIDISLD_MARK, + FSIACK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK, FSIAOMC_MARK, + FSIAOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, FSIAILR_MARK, + + FSIAOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, FSIAIBT_MARK, + FSIAOSLD_MARK, BBIF2_TXD2_MARK, + FSIASPDIF_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, FSIBSPDIF_MARK, \ + PORT53_FSICSPDIF_MARK, + FSIBCK_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FSIBOMC_MARK, \ + FSICCK_MARK, FSICOMC_MARK, + FSIAISLD_MARK, TPU0TO0_MARK, + A0_MARK, BS__MARK, + A12_MARK, PORT58_KEYOUT7_MARK, TPU4TO2_MARK, + A13_MARK, PORT59_KEYOUT6_MARK, TPU0TO1_MARK, + A14_MARK, KEYOUT5_MARK, + A15_MARK, KEYOUT4_MARK, + A16_MARK, KEYOUT3_MARK, MSIOF0_SS1_MARK, + A17_MARK, KEYOUT2_MARK, MSIOF0_TSYNC_MARK, + A18_MARK, KEYOUT1_MARK, MSIOF0_TSCK_MARK, + A19_MARK, KEYOUT0_MARK, MSIOF0_TXD_MARK, + A20_MARK, KEYIN0_MARK, MSIOF0_RSCK_MARK, + A21_MARK, KEYIN1_MARK, MSIOF0_RSYNC_MARK, + A22_MARK, KEYIN2_MARK, MSIOF0_MCK0_MARK, + A23_MARK, KEYIN3_MARK, MSIOF0_MCK1_MARK, + A24_MARK, KEYIN4_MARK, MSIOF0_RXD_MARK, + A25_MARK, KEYIN5_MARK, MSIOF0_SS2_MARK, + A26_MARK, KEYIN6_MARK, + KEYIN7_MARK, + D0_NAF0_MARK, + D1_NAF1_MARK, + D2_NAF2_MARK, + D3_NAF3_MARK, + D4_NAF4_MARK, + D5_NAF5_MARK, + D6_NAF6_MARK, + D7_NAF7_MARK, + D8_NAF8_MARK, + D9_NAF9_MARK, + D10_NAF10_MARK, + D11_NAF11_MARK, + D12_NAF12_MARK, + D13_NAF13_MARK, + D14_NAF14_MARK, + D15_NAF15_MARK, + CS4__MARK, + CS5A__MARK, PORT91_RDWR_MARK, + CS5B__MARK, FCE1__MARK, + CS6B__MARK, DACK0_MARK, + FCE0__MARK, CS6A__MARK, + WAIT__MARK, DREQ0_MARK, + RD__FSC_MARK, + WE0__FWE_MARK, RDWR_FWE_MARK, + WE1__MARK, + FRB_MARK, + CKO_MARK, + NBRSTOUT__MARK, + NBRST__MARK, + BBIF2_TXD_MARK, + BBIF2_RXD_MARK, + BBIF2_SYNC_MARK, + BBIF2_SCK_MARK, + SCIFA3_CTS__MARK, MFG3_IN2_MARK, + SCIFA3_RXD_MARK, MFG3_IN1_MARK, + BBIF1_SS2_MARK, SCIFA3_RTS__MARK, MFG3_OUT1_MARK, + SCIFA3_TXD_MARK, + HSI_RX_DATA_MARK, BBIF1_RXD_MARK, + HSI_TX_WAKE_MARK, BBIF1_TSCK_MARK, + HSI_TX_DATA_MARK, BBIF1_TSYNC_MARK, + HSI_TX_READY_MARK, BBIF1_TXD_MARK, + HSI_RX_READY_MARK, BBIF1_RSCK_MARK, PORT115_I2C_SCL2_MARK, \ + PORT115_I2C_SCL3_MARK, + HSI_RX_WAKE_MARK, BBIF1_RSYNC_MARK, PORT116_I2C_SDA2_MARK, \ + PORT116_I2C_SDA3_MARK, + HSI_RX_FLAG_MARK, BBIF1_SS1_MARK, BBIF1_FLOW_MARK, + HSI_TX_FLAG_MARK, + VIO_VD_MARK, PORT128_LCD2VSYN_MARK, VIO2_VD_MARK, LCD2D0_MARK, + + VIO_HD_MARK, PORT129_LCD2HSYN_MARK, PORT129_LCD2CS__MARK, \ + VIO2_HD_MARK, LCD2D1_MARK, + VIO_D0_MARK, PORT130_MSIOF2_RXD_MARK, LCD2D10_MARK, + VIO_D1_MARK, PORT131_KEYOUT6_MARK, PORT131_MSIOF2_SS1_MARK, \ + PORT131_KEYOUT11_MARK, LCD2D11_MARK, + VIO_D2_MARK, PORT132_KEYOUT7_MARK, PORT132_MSIOF2_SS2_MARK, \ + PORT132_KEYOUT10_MARK, LCD2D12_MARK, + VIO_D3_MARK, MSIOF2_TSYNC_MARK, LCD2D13_MARK, + VIO_D4_MARK, MSIOF2_TXD_MARK, LCD2D14_MARK, + VIO_D5_MARK, MSIOF2_TSCK_MARK, LCD2D15_MARK, + VIO_D6_MARK, PORT136_KEYOUT8_MARK, LCD2D16_MARK, + VIO_D7_MARK, PORT137_KEYOUT9_MARK, LCD2D17_MARK, + VIO_D8_MARK, PORT138_KEYOUT8_MARK, VIO2_D0_MARK, LCD2D6_MARK, + VIO_D9_MARK, PORT139_KEYOUT9_MARK, VIO2_D1_MARK, LCD2D7_MARK, + VIO_D10_MARK, TPU0TO2_MARK, VIO2_D2_MARK, LCD2D8_MARK, + VIO_D11_MARK, TPU0TO3_MARK, VIO2_D3_MARK, LCD2D9_MARK, + VIO_D12_MARK, PORT142_KEYOUT10_MARK, VIO2_D4_MARK, LCD2D2_MARK, + VIO_D13_MARK, PORT143_KEYOUT11_MARK, PORT143_KEYOUT6_MARK, \ + VIO2_D5_MARK, LCD2D3_MARK, + VIO_D14_MARK, PORT144_KEYOUT7_MARK, VIO2_D6_MARK, LCD2D4_MARK, + VIO_D15_MARK, TPU1TO3_MARK, PORT145_LCD2DISP_MARK, \ + PORT145_LCD2RS_MARK, VIO2_D7_MARK, LCD2D5_MARK, + VIO_CLK_MARK, LCD2DCK_MARK, PORT146_LCD2WR__MARK, VIO2_CLK_MARK, \ + LCD2D18_MARK, + VIO_FIELD_MARK, LCD2RD__MARK, VIO2_FIELD_MARK, LCD2D19_MARK, + VIO_CKO_MARK, + A27_MARK, PORT149_RDWR_MARK, MFG0_IN1_MARK, PORT149_KEYOUT9_MARK, + MFG0_IN2_MARK, + TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK, + TS_SDAT3_MARK, MSIOF2_RSYNC_MARK, + TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK, + SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK, + SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK, + SCIFA2_RTS1__MARK, PORT156_MSIOF2_SS2_MARK, + SCIFA2_CTS1__MARK, PORT157_MSIOF2_RXD_MARK, + DINT__MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK, + PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK, + PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK, + PORT161_SCIFB_CTS__MARK, PORT161_SCIFA5_CTS__MARK, + PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK, + PORT163_SCIFB_RTS__MARK, PORT163_SCIFA5_RTS__MARK, TPU3TO0_MARK, + LCDD0_MARK, + LCDD1_MARK, PORT193_SCIFA5_CTS__MARK, BBIF2_TSYNC1_MARK, + LCDD2_MARK, PORT194_SCIFA5_RTS__MARK, BBIF2_TSCK1_MARK, + LCDD3_MARK, PORT195_SCIFA5_RXD_MARK, BBIF2_TXD1_MARK, + LCDD4_MARK, PORT196_SCIFA5_TXD_MARK, + LCDD5_MARK, PORT197_SCIFA5_SCK_MARK, MFG2_OUT2_MARK, TPU2TO1_MARK, + LCDD6_MARK, + LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK, + LCDD8_MARK, D16_MARK, + LCDD9_MARK, D17_MARK, + LCDD10_MARK, D18_MARK, + LCDD11_MARK, D19_MARK, + LCDD12_MARK, D20_MARK, + LCDD13_MARK, D21_MARK, + LCDD14_MARK, D22_MARK, + LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, D23_MARK, + LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, D24_MARK, + LCDD17_MARK, D25_MARK, + LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK, + LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK, + LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK, + LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK, + LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK, + LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK, + LCDDCK_MARK, LCDWR__MARK, + LCDRD__MARK, DACK2_MARK, PORT217_LCD2RS_MARK, MSIOF0L_TSYNC_MARK, \ + VIO2_FIELD3_MARK, PORT217_LCD2DISP_MARK, + LCDHSYN_MARK, LCDCS__MARK, LCDCS2__MARK, DACK3_MARK, \ + PORT218_VIO_CKOR_MARK, + LCDDISP_MARK, LCDRS_MARK, PORT219_LCD2WR__MARK, DREQ3_MARK, \ + MSIOF0L_TSCK_MARK, VIO2_CLK3_MARK, LCD2DCK_2_MARK, + LCDVSYN_MARK, LCDVSYN2_MARK, + LCDLCLK_MARK, DREQ1_MARK, PORT221_LCD2CS__MARK, PWEN_MARK, \ + MSIOF0L_RXD_MARK, VIO2_HD3_MARK, PORT221_LCD2HSYN_MARK, + LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK, \ + VIO2_VD3_MARK, PORT222_LCD2VSYN_MARK, + + SCIFA1_TXD_MARK, OVCN2_MARK, + EXTLP_MARK, SCIFA1_SCK_MARK, PORT226_VIO_CKO2_MARK, + SCIFA1_RTS__MARK, IDIN_MARK, + SCIFA1_RXD_MARK, + SCIFA1_CTS__MARK, MFG1_IN1_MARK, + MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK, + MSIOF1_TSYNC_MARK, SCIFA2_CTS2__MARK, + MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK, + MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK, + MSIOF1_RSCK_MARK, SCIFA2_RTS2__MARK, VIO2_CLK2_MARK, LCD2D20_MARK, + MSIOF1_RSYNC_MARK, MFG1_IN2_MARK, VIO2_VD2_MARK, LCD2D21_MARK, + MSIOF1_MCK0_MARK, PORT236_I2C_SDA2_MARK, + MSIOF1_MCK1_MARK, PORT237_I2C_SCL2_MARK, + MSIOF1_SS1_MARK, VIO2_FIELD2_MARK, LCD2D22_MARK, + MSIOF1_SS2_MARK, VIO2_HD2_MARK, LCD2D23_MARK, + SCIFA6_TXD_MARK, + PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK, TPU4TO0_MARK, + PORT242_IRDA_IN_MARK, MFG4_IN2_MARK, + PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK, + PORT244_SCIFA5_CTS__MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS__MARK, \ + MSIOF2R_RXD_MARK, + PORT245_SCIFA5_RTS__MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS__MARK, \ + MSIOF2R_TXD_MARK, + PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK, \ + TPU1TO0_MARK, + PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK, \ + TPU3TO1_MARK, + PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK, \ + TPU2TO0_MARK, PORT248_I2C_SCL3_MARK, MSIOF2R_TSCK_MARK, + PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_I2C_SDA3_MARK, \ + MSIOF2R_TSYNC_MARK, + SDHICLK0_MARK, + SDHICD0_MARK, + SDHID0_0_MARK, + SDHID0_1_MARK, + SDHID0_2_MARK, + SDHID0_3_MARK, + SDHICMD0_MARK, + SDHIWP0_MARK, + SDHICLK1_MARK, + SDHID1_0_MARK, TS_SPSYNC2_MARK, + SDHID1_1_MARK, TS_SDAT2_MARK, + SDHID1_2_MARK, TS_SDEN2_MARK, + SDHID1_3_MARK, TS_SCK2_MARK, + SDHICMD1_MARK, + SDHICLK2_MARK, + SDHID2_0_MARK, TS_SPSYNC4_MARK, + SDHID2_1_MARK, TS_SDAT4_MARK, + SDHID2_2_MARK, TS_SDEN4_MARK, + SDHID2_3_MARK, TS_SCK4_MARK, + SDHICMD2_MARK, + MMCCLK0_MARK, + MMCD0_0_MARK, + MMCD0_1_MARK, + MMCD0_2_MARK, + MMCD0_3_MARK, + MMCD0_4_MARK, TS_SPSYNC5_MARK, + MMCD0_5_MARK, TS_SDAT5_MARK, + MMCD0_6_MARK, TS_SDEN5_MARK, + MMCD0_7_MARK, TS_SCK5_MARK, + MMCCMD0_MARK, + RESETOUTS__MARK, EXTAL2OUT_MARK, + MCP_WAIT__MCP_FRB_MARK, + MCP_CKO_MARK, MMCCLK1_MARK, + MCP_D15_MCP_NAF15_MARK, + MCP_D14_MCP_NAF14_MARK, + MCP_D13_MCP_NAF13_MARK, + MCP_D12_MCP_NAF12_MARK, + MCP_D11_MCP_NAF11_MARK, + MCP_D10_MCP_NAF10_MARK, + MCP_D9_MCP_NAF9_MARK, + MCP_D8_MCP_NAF8_MARK, MMCCMD1_MARK, + MCP_D7_MCP_NAF7_MARK, MMCD1_7_MARK, + + MCP_D6_MCP_NAF6_MARK, MMCD1_6_MARK, + MCP_D5_MCP_NAF5_MARK, MMCD1_5_MARK, + MCP_D4_MCP_NAF4_MARK, MMCD1_4_MARK, + MCP_D3_MCP_NAF3_MARK, MMCD1_3_MARK, + MCP_D2_MCP_NAF2_MARK, MMCD1_2_MARK, + MCP_D1_MCP_NAF1_MARK, MMCD1_1_MARK, + MCP_D0_MCP_NAF0_MARK, MMCD1_0_MARK, + MCP_NBRSTOUT__MARK, + MCP_WE0__MCP_FWE_MARK, MCP_RDWR_MCP_FWE_MARK, + + /* MSEL2 special cases */ + TSIF2_TS_XX1_MARK, + TSIF2_TS_XX2_MARK, + TSIF2_TS_XX3_MARK, + TSIF2_TS_XX4_MARK, + TSIF2_TS_XX5_MARK, + TSIF1_TS_XX1_MARK, + TSIF1_TS_XX2_MARK, + TSIF1_TS_XX3_MARK, + TSIF1_TS_XX4_MARK, + TSIF1_TS_XX5_MARK, + TSIF0_TS_XX1_MARK, + TSIF0_TS_XX2_MARK, + TSIF0_TS_XX3_MARK, + TSIF0_TS_XX4_MARK, + TSIF0_TS_XX5_MARK, + MST1_TS_XX1_MARK, + MST1_TS_XX2_MARK, + MST1_TS_XX3_MARK, + MST1_TS_XX4_MARK, + MST1_TS_XX5_MARK, + MST0_TS_XX1_MARK, + MST0_TS_XX2_MARK, + MST0_TS_XX3_MARK, + MST0_TS_XX4_MARK, + MST0_TS_XX5_MARK, + + /* MSEL3 special cases */ + SDHI0_VCCQ_MC0_ON_MARK, + SDHI0_VCCQ_MC0_OFF_MARK, + DEBUG_MON_VIO_MARK, + DEBUG_MON_LCDD_MARK, + LCDC_LCDC0_MARK, + LCDC_LCDC1_MARK, + + /* MSEL4 special cases */ + IRQ9_MEM_INT_MARK, + IRQ9_MCP_INT_MARK, + A11_MARK, + KEYOUT8_MARK, + TPU4TO3_MARK, + RESETA_N_PU_ON_MARK, + RESETA_N_PU_OFF_MARK, + EDBGREQ_PD_MARK, + EDBGREQ_PU_MARK, + + /* Functions with pull-ups */ + KEYIN0_PU_MARK, + KEYIN1_PU_MARK, + KEYIN2_PU_MARK, + KEYIN3_PU_MARK, + KEYIN4_PU_MARK, + KEYIN5_PU_MARK, + KEYIN6_PU_MARK, + KEYIN7_PU_MARK, + SDHICD0_PU_MARK, + SDHID0_0_PU_MARK, + SDHID0_1_PU_MARK, + SDHID0_2_PU_MARK, + SDHID0_3_PU_MARK, + SDHICMD0_PU_MARK, + SDHIWP0_PU_MARK, + SDHID1_0_PU_MARK, + SDHID1_1_PU_MARK, + SDHID1_2_PU_MARK, + SDHID1_3_PU_MARK, + SDHICMD1_PU_MARK, + SDHID2_0_PU_MARK, + SDHID2_1_PU_MARK, + SDHID2_2_PU_MARK, + SDHID2_3_PU_MARK, + SDHICMD2_PU_MARK, + MMCCMD0_PU_MARK, + MMCCMD1_PU_MARK, + MMCD0_0_PU_MARK, + MMCD0_1_PU_MARK, + MMCD0_2_PU_MARK, + MMCD0_3_PU_MARK, + MMCD0_4_PU_MARK, + MMCD0_5_PU_MARK, + MMCD0_6_PU_MARK, + MMCD0_7_PU_MARK, + FSIBISLD_PU_MARK, + FSIACK_PU_MARK, + FSIAILR_PU_MARK, + FSIAIBT_PU_MARK, + FSIAISLD_PU_MARK, + + PINMUX_MARK_END, +}; + +static unsigned short pinmux_data[] = { + /* specify valid pin states for each pin in GPIO mode */ + + /* Table 25-1 (I/O and Pull U/D) */ + PORT_DATA_I_PD(0), + PORT_DATA_I_PU(1), + PORT_DATA_I_PU(2), + PORT_DATA_I_PU(3), + PORT_DATA_I_PU(4), + PORT_DATA_I_PU(5), + PORT_DATA_I_PU(6), + PORT_DATA_I_PU(7), + PORT_DATA_I_PU(8), + PORT_DATA_I_PD(9), + PORT_DATA_I_PD(10), + PORT_DATA_I_PU_PD(11), + PORT_DATA_IO_PU_PD(12), + PORT_DATA_IO_PU_PD(13), + PORT_DATA_IO_PU_PD(14), + PORT_DATA_IO_PU_PD(15), + PORT_DATA_IO_PD(16), + PORT_DATA_IO_PD(17), + PORT_DATA_IO_PU(18), + PORT_DATA_IO_PU(19), + PORT_DATA_O(20), + PORT_DATA_O(21), + PORT_DATA_O(22), + PORT_DATA_O(23), + PORT_DATA_O(24), + PORT_DATA_I_PD(25), + PORT_DATA_I_PD(26), + PORT_DATA_IO_PU(27), + PORT_DATA_IO_PU(28), + PORT_DATA_IO_PD(29), + PORT_DATA_IO_PD(30), + PORT_DATA_IO_PU(31), + PORT_DATA_IO_PD(32), + PORT_DATA_I_PU_PD(33), + PORT_DATA_IO_PD(34), + PORT_DATA_I_PU_PD(35), + PORT_DATA_IO_PD(36), + PORT_DATA_IO(37), + PORT_DATA_O(38), + PORT_DATA_I_PU(39), + PORT_DATA_I_PU_PD(40), + PORT_DATA_O(41), + PORT_DATA_IO_PD(42), + PORT_DATA_IO_PU_PD(43), + PORT_DATA_IO_PU_PD(44), + PORT_DATA_IO_PD(45), + PORT_DATA_IO_PD(46), + PORT_DATA_IO_PD(47), + PORT_DATA_I_PD(48), + PORT_DATA_IO_PU_PD(49), + PORT_DATA_IO_PD(50), + + PORT_DATA_IO_PD(51), + PORT_DATA_O(52), + PORT_DATA_IO_PU_PD(53), + PORT_DATA_IO_PU_PD(54), + PORT_DATA_IO_PD(55), + PORT_DATA_I_PU_PD(56), + PORT_DATA_IO(57), + PORT_DATA_IO(58), + PORT_DATA_IO(59), + PORT_DATA_IO(60), + PORT_DATA_IO(61), + PORT_DATA_IO_PD(62), + PORT_DATA_IO_PD(63), + PORT_DATA_IO_PU_PD(64), + PORT_DATA_IO_PD(65), + PORT_DATA_IO_PU_PD(66), + PORT_DATA_IO_PU_PD(67), + PORT_DATA_IO_PU_PD(68), + PORT_DATA_IO_PU_PD(69), + PORT_DATA_IO_PU_PD(70), + PORT_DATA_IO_PU_PD(71), + PORT_DATA_IO_PU_PD(72), + PORT_DATA_I_PU_PD(73), + PORT_DATA_IO_PU(74), + PORT_DATA_IO_PU(75), + PORT_DATA_IO_PU(76), + PORT_DATA_IO_PU(77), + PORT_DATA_IO_PU(78), + PORT_DATA_IO_PU(79), + PORT_DATA_IO_PU(80), + PORT_DATA_IO_PU(81), + PORT_DATA_IO_PU(82), + PORT_DATA_IO_PU(83), + PORT_DATA_IO_PU(84), + PORT_DATA_IO_PU(85), + PORT_DATA_IO_PU(86), + PORT_DATA_IO_PU(87), + PORT_DATA_IO_PU(88), + PORT_DATA_IO_PU(89), + PORT_DATA_O(90), + PORT_DATA_IO_PU(91), + PORT_DATA_O(92), + PORT_DATA_IO_PU(93), + PORT_DATA_O(94), + PORT_DATA_I_PU_PD(95), + PORT_DATA_IO(96), + PORT_DATA_IO(97), + PORT_DATA_IO(98), + PORT_DATA_I_PU(99), + PORT_DATA_O(100), + PORT_DATA_O(101), + PORT_DATA_I_PU(102), + PORT_DATA_IO_PD(103), + PORT_DATA_I_PU_PD(104), + PORT_DATA_I_PD(105), + PORT_DATA_I_PD(106), + PORT_DATA_I_PU_PD(107), + PORT_DATA_I_PU_PD(108), + PORT_DATA_IO_PD(109), + PORT_DATA_IO_PD(110), + PORT_DATA_IO_PU_PD(111), + PORT_DATA_IO_PU_PD(112), + PORT_DATA_IO_PU_PD(113), + PORT_DATA_IO_PD(114), + PORT_DATA_IO_PU(115), + PORT_DATA_IO_PU(116), + PORT_DATA_IO_PU_PD(117), + PORT_DATA_IO_PU_PD(118), + PORT_DATA_IO_PD(128), + + PORT_DATA_IO_PD(129), + PORT_DATA_IO_PU_PD(130), + PORT_DATA_IO_PD(131), + PORT_DATA_IO_PD(132), + PORT_DATA_IO_PD(133), + PORT_DATA_IO_PU_PD(134), + PORT_DATA_IO_PU_PD(135), + PORT_DATA_IO_PU_PD(136), + PORT_DATA_IO_PU_PD(137), + PORT_DATA_IO_PD(138), + PORT_DATA_IO_PD(139), + PORT_DATA_IO_PD(140), + PORT_DATA_IO_PD(141), + PORT_DATA_IO_PD(142), + PORT_DATA_IO_PD(143), + PORT_DATA_IO_PU_PD(144), + PORT_DATA_IO_PD(145), + PORT_DATA_IO_PU_PD(146), + PORT_DATA_IO_PU_PD(147), + PORT_DATA_IO_PU_PD(148), + PORT_DATA_IO_PU_PD(149), + PORT_DATA_I_PU_PD(150), + PORT_DATA_IO_PU_PD(151), + PORT_DATA_IO_PU_PD(152), + PORT_DATA_IO_PD(153), + PORT_DATA_IO_PD(154), + PORT_DATA_I_PU_PD(155), + PORT_DATA_IO_PU_PD(156), + PORT_DATA_I_PD(157), + PORT_DATA_IO_PD(158), + PORT_DATA_IO_PU_PD(159), + PORT_DATA_IO_PU_PD(160), + PORT_DATA_I_PU_PD(161), + PORT_DATA_I_PU_PD(162), + PORT_DATA_IO_PU_PD(163), + PORT_DATA_I_PU_PD(164), + PORT_DATA_IO_PD(192), + PORT_DATA_IO_PU_PD(193), + PORT_DATA_IO_PD(194), + PORT_DATA_IO_PU_PD(195), + PORT_DATA_IO_PD(196), + PORT_DATA_IO_PD(197), + PORT_DATA_IO_PD(198), + PORT_DATA_IO_PD(199), + PORT_DATA_IO_PU_PD(200), + PORT_DATA_IO_PU_PD(201), + PORT_DATA_IO_PU_PD(202), + PORT_DATA_IO_PU_PD(203), + PORT_DATA_IO_PU_PD(204), + PORT_DATA_IO_PU_PD(205), + PORT_DATA_IO_PU_PD(206), + PORT_DATA_IO_PD(207), + PORT_DATA_IO_PD(208), + PORT_DATA_IO_PD(209), + PORT_DATA_IO_PD(210), + PORT_DATA_IO_PD(211), + PORT_DATA_IO_PD(212), + PORT_DATA_IO_PD(213), + PORT_DATA_IO_PU_PD(214), + PORT_DATA_IO_PU_PD(215), + PORT_DATA_IO_PD(216), + PORT_DATA_IO_PD(217), + PORT_DATA_O(218), + PORT_DATA_IO_PD(219), + PORT_DATA_IO_PD(220), + PORT_DATA_IO_PU_PD(221), + PORT_DATA_IO_PU_PD(222), + PORT_DATA_I_PU_PD(223), + PORT_DATA_I_PU_PD(224), + + PORT_DATA_IO_PU_PD(225), + PORT_DATA_O(226), + PORT_DATA_IO_PU_PD(227), + PORT_DATA_I_PU_PD(228), + PORT_DATA_I_PD(229), + PORT_DATA_IO(230), + PORT_DATA_IO_PU_PD(231), + PORT_DATA_IO_PU_PD(232), + PORT_DATA_I_PU_PD(233), + PORT_DATA_IO_PU_PD(234), + PORT_DATA_IO_PU_PD(235), + PORT_DATA_IO_PU_PD(236), + PORT_DATA_IO_PD(237), + PORT_DATA_IO_PU_PD(238), + PORT_DATA_IO_PU_PD(239), + PORT_DATA_IO_PU_PD(240), + PORT_DATA_O(241), + PORT_DATA_I_PD(242), + PORT_DATA_IO_PU_PD(243), + PORT_DATA_IO_PU_PD(244), + PORT_DATA_IO_PU_PD(245), + PORT_DATA_IO_PU_PD(246), + PORT_DATA_IO_PU_PD(247), + PORT_DATA_IO_PU_PD(248), + PORT_DATA_IO_PU_PD(249), + PORT_DATA_IO_PU_PD(250), + PORT_DATA_IO_PU_PD(251), + PORT_DATA_IO_PU_PD(252), + PORT_DATA_IO_PU_PD(253), + PORT_DATA_IO_PU_PD(254), + PORT_DATA_IO_PU_PD(255), + PORT_DATA_IO_PU_PD(256), + PORT_DATA_IO_PU_PD(257), + PORT_DATA_IO_PU_PD(258), + PORT_DATA_IO_PU_PD(259), + PORT_DATA_IO_PU_PD(260), + PORT_DATA_IO_PU_PD(261), + PORT_DATA_IO_PU_PD(262), + PORT_DATA_IO_PU_PD(263), + PORT_DATA_IO_PU_PD(264), + PORT_DATA_IO_PU_PD(265), + PORT_DATA_IO_PU_PD(266), + PORT_DATA_IO_PU_PD(267), + PORT_DATA_IO_PU_PD(268), + PORT_DATA_IO_PU_PD(269), + PORT_DATA_IO_PU_PD(270), + PORT_DATA_IO_PU_PD(271), + PORT_DATA_IO_PU_PD(272), + PORT_DATA_IO_PU_PD(273), + PORT_DATA_IO_PU_PD(274), + PORT_DATA_IO_PU_PD(275), + PORT_DATA_IO_PU_PD(276), + PORT_DATA_IO_PU_PD(277), + PORT_DATA_IO_PU_PD(278), + PORT_DATA_IO_PU_PD(279), + PORT_DATA_IO_PU_PD(280), + PORT_DATA_O(281), + PORT_DATA_O(282), + PORT_DATA_I_PU(288), + PORT_DATA_IO_PU_PD(289), + PORT_DATA_IO_PU_PD(290), + PORT_DATA_IO_PU_PD(291), + PORT_DATA_IO_PU_PD(292), + PORT_DATA_IO_PU_PD(293), + PORT_DATA_IO_PU_PD(294), + PORT_DATA_IO_PU_PD(295), + PORT_DATA_IO_PU_PD(296), + PORT_DATA_IO_PU_PD(297), + PORT_DATA_IO_PU_PD(298), + + PORT_DATA_IO_PU_PD(299), + PORT_DATA_IO_PU_PD(300), + PORT_DATA_IO_PU_PD(301), + PORT_DATA_IO_PU_PD(302), + PORT_DATA_IO_PU_PD(303), + PORT_DATA_IO_PU_PD(304), + PORT_DATA_IO_PU_PD(305), + PORT_DATA_O(306), + PORT_DATA_O(307), + PORT_DATA_I_PU(308), + PORT_DATA_O(309), + + /* Table 25-1 (Function 0-7) */ + PINMUX_DATA(VBUS_0_MARK, PORT0_FN1), + PINMUX_DATA(GPI0_MARK, PORT1_FN1), + PINMUX_DATA(GPI1_MARK, PORT2_FN1), + PINMUX_DATA(GPI2_MARK, PORT3_FN1), + PINMUX_DATA(GPI3_MARK, PORT4_FN1), + PINMUX_DATA(GPI4_MARK, PORT5_FN1), + PINMUX_DATA(GPI5_MARK, PORT6_FN1), + PINMUX_DATA(GPI6_MARK, PORT7_FN1), + PINMUX_DATA(GPI7_MARK, PORT8_FN1), + PINMUX_DATA(SCIFA7_RXD_MARK, PORT12_FN2), + PINMUX_DATA(SCIFA7_CTS__MARK, PORT13_FN2), + PINMUX_DATA(GPO7_MARK, PORT14_FN1), \ + PINMUX_DATA(MFG0_OUT2_MARK, PORT14_FN4), + PINMUX_DATA(GPO6_MARK, PORT15_FN1), \ + PINMUX_DATA(MFG1_OUT2_MARK, PORT15_FN4), + PINMUX_DATA(GPO5_MARK, PORT16_FN1), \ + PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2), \ + PINMUX_DATA(FSICOSLDT3_MARK, PORT16_FN3), \ + PINMUX_DATA(PORT16_VIO_CKOR_MARK, PORT16_FN4), + PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2), + PINMUX_DATA(SCIFA7_TXD_MARK, PORT18_FN2), + PINMUX_DATA(SCIFA7_RTS__MARK, PORT19_FN2), \ + PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3), + PINMUX_DATA(GPO0_MARK, PORT20_FN1), + PINMUX_DATA(GPO1_MARK, PORT21_FN1), + PINMUX_DATA(GPO2_MARK, PORT22_FN1), \ + PINMUX_DATA(STATUS0_MARK, PORT22_FN2), + PINMUX_DATA(GPO3_MARK, PORT23_FN1), \ + PINMUX_DATA(STATUS1_MARK, PORT23_FN2), + PINMUX_DATA(GPO4_MARK, PORT24_FN1), \ + PINMUX_DATA(STATUS2_MARK, PORT24_FN2), + PINMUX_DATA(VINT_MARK, PORT25_FN1), + PINMUX_DATA(TCKON_MARK, PORT26_FN1), + PINMUX_DATA(XDVFS1_MARK, PORT27_FN1), \ + PINMUX_DATA(PORT27_I2C_SCL2_MARK, PORT27_FN2, MSEL2CR_MSEL17_0, + MSEL2CR_MSEL16_1), \ + PINMUX_DATA(PORT27_I2C_SCL3_MARK, PORT27_FN3, MSEL2CR_MSEL19_0, + MSEL2CR_MSEL18_1), \ + PINMUX_DATA(MFG0_OUT1_MARK, PORT27_FN4), \ + PINMUX_DATA(PORT27_IROUT_MARK, PORT27_FN7), + PINMUX_DATA(XDVFS2_MARK, PORT28_FN1), \ + PINMUX_DATA(PORT28_I2C_SDA2_MARK, PORT28_FN2, MSEL2CR_MSEL17_0, + MSEL2CR_MSEL16_1), \ + PINMUX_DATA(PORT28_I2C_SDA3_MARK, PORT28_FN3, MSEL2CR_MSEL19_0, + MSEL2CR_MSEL18_1), \ + PINMUX_DATA(PORT28_TPU1TO1_MARK, PORT28_FN7), + PINMUX_DATA(SIM_RST_MARK, PORT29_FN1), \ + PINMUX_DATA(PORT29_TPU1TO1_MARK, PORT29_FN4), + PINMUX_DATA(SIM_CLK_MARK, PORT30_FN1), \ + PINMUX_DATA(PORT30_VIO_CKOR_MARK, PORT30_FN4), + PINMUX_DATA(SIM_D_MARK, PORT31_FN1), \ + PINMUX_DATA(PORT31_IROUT_MARK, PORT31_FN4), + PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2), + PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2), \ + PINMUX_DATA(XWUP_MARK, PORT33_FN3), + PINMUX_DATA(SCIFA4_RTS__MARK, PORT34_FN2), + PINMUX_DATA(SCIFA4_CTS__MARK, PORT35_FN2), + PINMUX_DATA(FSIBOBT_MARK, PORT36_FN1), \ + PINMUX_DATA(FSIBIBT_MARK, PORT36_FN2), + PINMUX_DATA(FSIBOLR_MARK, PORT37_FN1), \ + PINMUX_DATA(FSIBILR_MARK, PORT37_FN2), + PINMUX_DATA(FSIBOSLD_MARK, PORT38_FN1), + PINMUX_DATA(FSIBISLD_MARK, PORT39_FN1), + PINMUX_DATA(VACK_MARK, PORT40_FN1), + PINMUX_DATA(XTAL1L_MARK, PORT41_FN1), + PINMUX_DATA(SCIFA0_RTS__MARK, PORT42_FN2), \ + PINMUX_DATA(FSICOSLDT2_MARK, PORT42_FN3), + PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2), + PINMUX_DATA(SCIFA0_CTS__MARK, PORT44_FN2), \ + PINMUX_DATA(FSICOSLDT1_MARK, PORT44_FN3), + PINMUX_DATA(FSICOBT_MARK, PORT45_FN1), \ + PINMUX_DATA(FSICIBT_MARK, PORT45_FN2), \ + PINMUX_DATA(FSIDOBT_MARK, PORT45_FN3), \ + PINMUX_DATA(FSIDIBT_MARK, PORT45_FN4), + PINMUX_DATA(FSICOLR_MARK, PORT46_FN1), \ + PINMUX_DATA(FSICILR_MARK, PORT46_FN2), \ + PINMUX_DATA(FSIDOLR_MARK, PORT46_FN3), \ + PINMUX_DATA(FSIDILR_MARK, PORT46_FN4), + PINMUX_DATA(FSICOSLD_MARK, PORT47_FN1), \ + PINMUX_DATA(PORT47_FSICSPDIF_MARK, PORT47_FN2), + PINMUX_DATA(FSICISLD_MARK, PORT48_FN1), \ + PINMUX_DATA(FSIDISLD_MARK, PORT48_FN3), + PINMUX_DATA(FSIACK_MARK, PORT49_FN1), \ + PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2, MSEL4CR_MSEL19_1), \ + PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN4), \ + PINMUX_DATA(FSIAOMC_MARK, PORT49_FN5), + PINMUX_DATA(FSIAOLR_MARK, PORT50_FN1), \ + PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2), \ + PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3), \ + PINMUX_DATA(FSIAILR_MARK, PORT50_FN5), + + PINMUX_DATA(FSIAOBT_MARK, PORT51_FN1), \ + PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2), \ + PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3), \ + PINMUX_DATA(FSIAIBT_MARK, PORT51_FN5), + PINMUX_DATA(FSIAOSLD_MARK, PORT52_FN1), \ + PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2), + PINMUX_DATA(FSIASPDIF_MARK, PORT53_FN1), \ + PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2, MSEL4CR_MSEL19_1), \ + PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3), \ + PINMUX_DATA(FSIBSPDIF_MARK, PORT53_FN5), \ + PINMUX_DATA(PORT53_FSICSPDIF_MARK, PORT53_FN6), + PINMUX_DATA(FSIBCK_MARK, PORT54_FN1), \ + PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2, MSEL4CR_MSEL19_1), \ + PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3), \ + PINMUX_DATA(FSIBOMC_MARK, PORT54_FN5), \ + PINMUX_DATA(FSICCK_MARK, PORT54_FN6), \ + PINMUX_DATA(FSICOMC_MARK, PORT54_FN7), + PINMUX_DATA(FSIAISLD_MARK, PORT55_FN1), \ + PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3), + PINMUX_DATA(A0_MARK, PORT57_FN1), \ + PINMUX_DATA(BS__MARK, PORT57_FN2), + PINMUX_DATA(A12_MARK, PORT58_FN1), \ + PINMUX_DATA(PORT58_KEYOUT7_MARK, PORT58_FN2), \ + PINMUX_DATA(TPU4TO2_MARK, PORT58_FN4), + PINMUX_DATA(A13_MARK, PORT59_FN1), \ + PINMUX_DATA(PORT59_KEYOUT6_MARK, PORT59_FN2), \ + PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4), + PINMUX_DATA(A14_MARK, PORT60_FN1), \ + PINMUX_DATA(KEYOUT5_MARK, PORT60_FN2), + PINMUX_DATA(A15_MARK, PORT61_FN1), \ + PINMUX_DATA(KEYOUT4_MARK, PORT61_FN2), + PINMUX_DATA(A16_MARK, PORT62_FN1), \ + PINMUX_DATA(KEYOUT3_MARK, PORT62_FN2), \ + PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A17_MARK, PORT63_FN1), \ + PINMUX_DATA(KEYOUT2_MARK, PORT63_FN2), \ + PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A18_MARK, PORT64_FN1), \ + PINMUX_DATA(KEYOUT1_MARK, PORT64_FN2), \ + PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A19_MARK, PORT65_FN1), \ + PINMUX_DATA(KEYOUT0_MARK, PORT65_FN2), \ + PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A20_MARK, PORT66_FN1), \ + PINMUX_DATA(KEYIN0_MARK, PORT66_FN2), \ + PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A21_MARK, PORT67_FN1), \ + PINMUX_DATA(KEYIN1_MARK, PORT67_FN2), \ + PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A22_MARK, PORT68_FN1), \ + PINMUX_DATA(KEYIN2_MARK, PORT68_FN2), \ + PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A23_MARK, PORT69_FN1), \ + PINMUX_DATA(KEYIN3_MARK, PORT69_FN2), \ + PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A24_MARK, PORT70_FN1), \ + PINMUX_DATA(KEYIN4_MARK, PORT70_FN2), \ + PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A25_MARK, PORT71_FN1), \ + PINMUX_DATA(KEYIN5_MARK, PORT71_FN2), \ + PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN4, MSEL3CR_MSEL11_0), + PINMUX_DATA(A26_MARK, PORT72_FN1), \ + PINMUX_DATA(KEYIN6_MARK, PORT72_FN2), + PINMUX_DATA(KEYIN7_MARK, PORT73_FN2), + PINMUX_DATA(D0_NAF0_MARK, PORT74_FN1), + PINMUX_DATA(D1_NAF1_MARK, PORT75_FN1), + PINMUX_DATA(D2_NAF2_MARK, PORT76_FN1), + PINMUX_DATA(D3_NAF3_MARK, PORT77_FN1), + PINMUX_DATA(D4_NAF4_MARK, PORT78_FN1), + PINMUX_DATA(D5_NAF5_MARK, PORT79_FN1), + PINMUX_DATA(D6_NAF6_MARK, PORT80_FN1), + PINMUX_DATA(D7_NAF7_MARK, PORT81_FN1), + PINMUX_DATA(D8_NAF8_MARK, PORT82_FN1), + PINMUX_DATA(D9_NAF9_MARK, PORT83_FN1), + PINMUX_DATA(D10_NAF10_MARK, PORT84_FN1), + PINMUX_DATA(D11_NAF11_MARK, PORT85_FN1), + PINMUX_DATA(D12_NAF12_MARK, PORT86_FN1), + PINMUX_DATA(D13_NAF13_MARK, PORT87_FN1), + PINMUX_DATA(D14_NAF14_MARK, PORT88_FN1), + PINMUX_DATA(D15_NAF15_MARK, PORT89_FN1), + PINMUX_DATA(CS4__MARK, PORT90_FN1), + PINMUX_DATA(CS5A__MARK, PORT91_FN1), \ + PINMUX_DATA(PORT91_RDWR_MARK, PORT91_FN2), + PINMUX_DATA(CS5B__MARK, PORT92_FN1), \ + PINMUX_DATA(FCE1__MARK, PORT92_FN2), + PINMUX_DATA(CS6B__MARK, PORT93_FN1), \ + PINMUX_DATA(DACK0_MARK, PORT93_FN4), + PINMUX_DATA(FCE0__MARK, PORT94_FN1), \ + PINMUX_DATA(CS6A__MARK, PORT94_FN2), + PINMUX_DATA(WAIT__MARK, PORT95_FN1), \ + PINMUX_DATA(DREQ0_MARK, PORT95_FN2), + PINMUX_DATA(RD__FSC_MARK, PORT96_FN1), + PINMUX_DATA(WE0__FWE_MARK, PORT97_FN1), \ + PINMUX_DATA(RDWR_FWE_MARK, PORT97_FN2), + PINMUX_DATA(WE1__MARK, PORT98_FN1), + PINMUX_DATA(FRB_MARK, PORT99_FN1), + PINMUX_DATA(CKO_MARK, PORT100_FN1), + PINMUX_DATA(NBRSTOUT__MARK, PORT101_FN1), + PINMUX_DATA(NBRST__MARK, PORT102_FN1), + PINMUX_DATA(BBIF2_TXD_MARK, PORT103_FN3), + PINMUX_DATA(BBIF2_RXD_MARK, PORT104_FN3), + PINMUX_DATA(BBIF2_SYNC_MARK, PORT105_FN3), + PINMUX_DATA(BBIF2_SCK_MARK, PORT106_FN3), + PINMUX_DATA(SCIFA3_CTS__MARK, PORT107_FN3), \ + PINMUX_DATA(MFG3_IN2_MARK, PORT107_FN4), + PINMUX_DATA(SCIFA3_RXD_MARK, PORT108_FN3), \ + PINMUX_DATA(MFG3_IN1_MARK, PORT108_FN4), + PINMUX_DATA(BBIF1_SS2_MARK, PORT109_FN2), \ + PINMUX_DATA(SCIFA3_RTS__MARK, PORT109_FN3), \ + PINMUX_DATA(MFG3_OUT1_MARK, PORT109_FN4), + PINMUX_DATA(SCIFA3_TXD_MARK, PORT110_FN3), + PINMUX_DATA(HSI_RX_DATA_MARK, PORT111_FN1), \ + PINMUX_DATA(BBIF1_RXD_MARK, PORT111_FN3), + PINMUX_DATA(HSI_TX_WAKE_MARK, PORT112_FN1), \ + PINMUX_DATA(BBIF1_TSCK_MARK, PORT112_FN3), + PINMUX_DATA(HSI_TX_DATA_MARK, PORT113_FN1), \ + PINMUX_DATA(BBIF1_TSYNC_MARK, PORT113_FN3), + PINMUX_DATA(HSI_TX_READY_MARK, PORT114_FN1), \ + PINMUX_DATA(BBIF1_TXD_MARK, PORT114_FN3), + PINMUX_DATA(HSI_RX_READY_MARK, PORT115_FN1), \ + PINMUX_DATA(BBIF1_RSCK_MARK, PORT115_FN3), \ + PINMUX_DATA(PORT115_I2C_SCL2_MARK, PORT115_FN5, MSEL2CR_MSEL17_1), \ + PINMUX_DATA(PORT115_I2C_SCL3_MARK, PORT115_FN6, MSEL2CR_MSEL19_1), + PINMUX_DATA(HSI_RX_WAKE_MARK, PORT116_FN1), \ + PINMUX_DATA(BBIF1_RSYNC_MARK, PORT116_FN3), \ + PINMUX_DATA(PORT116_I2C_SDA2_MARK, PORT116_FN5, MSEL2CR_MSEL17_1), \ + PINMUX_DATA(PORT116_I2C_SDA3_MARK, PORT116_FN6, MSEL2CR_MSEL19_1), + PINMUX_DATA(HSI_RX_FLAG_MARK, PORT117_FN1), \ + PINMUX_DATA(BBIF1_SS1_MARK, PORT117_FN2), \ + PINMUX_DATA(BBIF1_FLOW_MARK, PORT117_FN3), + PINMUX_DATA(HSI_TX_FLAG_MARK, PORT118_FN1), + PINMUX_DATA(VIO_VD_MARK, PORT128_FN1), \ + PINMUX_DATA(PORT128_LCD2VSYN_MARK, PORT128_FN4, MSEL3CR_MSEL2_0), \ + PINMUX_DATA(VIO2_VD_MARK, PORT128_FN6, MSEL4CR_MSEL27_0), \ + PINMUX_DATA(LCD2D0_MARK, PORT128_FN7), + + PINMUX_DATA(VIO_HD_MARK, PORT129_FN1), \ + PINMUX_DATA(PORT129_LCD2HSYN_MARK, PORT129_FN4), \ + PINMUX_DATA(PORT129_LCD2CS__MARK, PORT129_FN5), \ + PINMUX_DATA(VIO2_HD_MARK, PORT129_FN6, MSEL4CR_MSEL27_0), \ + PINMUX_DATA(LCD2D1_MARK, PORT129_FN7), + PINMUX_DATA(VIO_D0_MARK, PORT130_FN1), \ + PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3, MSEL4CR_MSEL11_0, + MSEL4CR_MSEL10_1), \ + PINMUX_DATA(LCD2D10_MARK, PORT130_FN7), + PINMUX_DATA(VIO_D1_MARK, PORT131_FN1), \ + PINMUX_DATA(PORT131_KEYOUT6_MARK, PORT131_FN2), \ + PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3), \ + PINMUX_DATA(PORT131_KEYOUT11_MARK, PORT131_FN4), \ + PINMUX_DATA(LCD2D11_MARK, PORT131_FN7), + PINMUX_DATA(VIO_D2_MARK, PORT132_FN1), \ + PINMUX_DATA(PORT132_KEYOUT7_MARK, PORT132_FN2), \ + PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3), \ + PINMUX_DATA(PORT132_KEYOUT10_MARK, PORT132_FN4), \ + PINMUX_DATA(LCD2D12_MARK, PORT132_FN7), + PINMUX_DATA(VIO_D3_MARK, PORT133_FN1), \ + PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT133_FN3, MSEL4CR_MSEL11_0), \ + PINMUX_DATA(LCD2D13_MARK, PORT133_FN7), + PINMUX_DATA(VIO_D4_MARK, PORT134_FN1), \ + PINMUX_DATA(MSIOF2_TXD_MARK, PORT134_FN3, MSEL4CR_MSEL11_0), \ + PINMUX_DATA(LCD2D14_MARK, PORT134_FN7), + PINMUX_DATA(VIO_D5_MARK, PORT135_FN1), \ + PINMUX_DATA(MSIOF2_TSCK_MARK, PORT135_FN3, MSEL4CR_MSEL11_0), \ + PINMUX_DATA(LCD2D15_MARK, PORT135_FN7), + PINMUX_DATA(VIO_D6_MARK, PORT136_FN1), \ + PINMUX_DATA(PORT136_KEYOUT8_MARK, PORT136_FN2), \ + PINMUX_DATA(LCD2D16_MARK, PORT136_FN7), + PINMUX_DATA(VIO_D7_MARK, PORT137_FN1), \ + PINMUX_DATA(PORT137_KEYOUT9_MARK, PORT137_FN2), \ + PINMUX_DATA(LCD2D17_MARK, PORT137_FN7), + PINMUX_DATA(VIO_D8_MARK, PORT138_FN1), \ + PINMUX_DATA(PORT138_KEYOUT8_MARK, PORT138_FN2), \ + PINMUX_DATA(VIO2_D0_MARK, PORT138_FN6), \ + PINMUX_DATA(LCD2D6_MARK, PORT138_FN7), + PINMUX_DATA(VIO_D9_MARK, PORT139_FN1), \ + PINMUX_DATA(PORT139_KEYOUT9_MARK, PORT139_FN2), \ + PINMUX_DATA(VIO2_D1_MARK, PORT139_FN6), \ + PINMUX_DATA(LCD2D7_MARK, PORT139_FN7), + PINMUX_DATA(VIO_D10_MARK, PORT140_FN1), \ + PINMUX_DATA(TPU0TO2_MARK, PORT140_FN4), \ + PINMUX_DATA(VIO2_D2_MARK, PORT140_FN6), \ + PINMUX_DATA(LCD2D8_MARK, PORT140_FN7), + PINMUX_DATA(VIO_D11_MARK, PORT141_FN1), \ + PINMUX_DATA(TPU0TO3_MARK, PORT141_FN4), \ + PINMUX_DATA(VIO2_D3_MARK, PORT141_FN6), \ + PINMUX_DATA(LCD2D9_MARK, PORT141_FN7), + PINMUX_DATA(VIO_D12_MARK, PORT142_FN1), \ + PINMUX_DATA(PORT142_KEYOUT10_MARK, PORT142_FN2), \ + PINMUX_DATA(VIO2_D4_MARK, PORT142_FN6), \ + PINMUX_DATA(LCD2D2_MARK, PORT142_FN7), + PINMUX_DATA(VIO_D13_MARK, PORT143_FN1), \ + PINMUX_DATA(PORT143_KEYOUT11_MARK, PORT143_FN2), \ + PINMUX_DATA(PORT143_KEYOUT6_MARK, PORT143_FN3), \ + PINMUX_DATA(VIO2_D5_MARK, PORT143_FN6), \ + PINMUX_DATA(LCD2D3_MARK, PORT143_FN7), + PINMUX_DATA(VIO_D14_MARK, PORT144_FN1), \ + PINMUX_DATA(PORT144_KEYOUT7_MARK, PORT144_FN2), \ + PINMUX_DATA(VIO2_D6_MARK, PORT144_FN6), \ + PINMUX_DATA(LCD2D4_MARK, PORT144_FN7), + PINMUX_DATA(VIO_D15_MARK, PORT145_FN1), \ + PINMUX_DATA(TPU1TO3_MARK, PORT145_FN3), \ + PINMUX_DATA(PORT145_LCD2DISP_MARK, PORT145_FN4), \ + PINMUX_DATA(PORT145_LCD2RS_MARK, PORT145_FN5), \ + PINMUX_DATA(VIO2_D7_MARK, PORT145_FN6), \ + PINMUX_DATA(LCD2D5_MARK, PORT145_FN7), + PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1), \ + PINMUX_DATA(LCD2DCK_MARK, PORT146_FN4), \ + PINMUX_DATA(PORT146_LCD2WR__MARK, PORT146_FN5), \ + PINMUX_DATA(VIO2_CLK_MARK, PORT146_FN6, MSEL4CR_MSEL27_0), \ + PINMUX_DATA(LCD2D18_MARK, PORT146_FN7), + PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1), \ + PINMUX_DATA(LCD2RD__MARK, PORT147_FN4), \ + PINMUX_DATA(VIO2_FIELD_MARK, PORT147_FN6, MSEL4CR_MSEL27_0), \ + PINMUX_DATA(LCD2D19_MARK, PORT147_FN7), + PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1), + PINMUX_DATA(A27_MARK, PORT149_FN1), \ + PINMUX_DATA(PORT149_RDWR_MARK, PORT149_FN2), \ + PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3), \ + PINMUX_DATA(PORT149_KEYOUT9_MARK, PORT149_FN4), + PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN3), + PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN4), \ + PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN5), + PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN4), \ + PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN5), + PINMUX_DATA(TPU1TO2_MARK, PORT153_FN3), \ + PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN4), \ + PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN5), + PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2, MSEL3CR_MSEL9_0), \ + PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN5), + PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2, MSEL3CR_MSEL9_0), \ + PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN5), + PINMUX_DATA(SCIFA2_RTS1__MARK, PORT156_FN2, MSEL3CR_MSEL9_0), \ + PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN5), + PINMUX_DATA(SCIFA2_CTS1__MARK, PORT157_FN2, MSEL3CR_MSEL9_0), \ + PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN5, MSEL4CR_MSEL11_0, + MSEL4CR_MSEL10_0), + PINMUX_DATA(DINT__MARK, PORT158_FN1), \ + PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2, MSEL3CR_MSEL9_0), \ + PINMUX_DATA(TS_SCK3_MARK, PORT158_FN4), + PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1, MSEL4CR_MSEL22_0), \ + PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2, MSEL4CR_MSEL21_1), \ + PINMUX_DATA(NMI_MARK, PORT159_FN3), + PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1, MSEL4CR_MSEL22_0), \ + PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2, MSEL4CR_MSEL21_1), + PINMUX_DATA(PORT161_SCIFB_CTS__MARK, PORT161_FN1, MSEL4CR_MSEL22_0), \ + PINMUX_DATA(PORT161_SCIFA5_CTS__MARK, PORT161_FN2, MSEL4CR_MSEL21_1), + PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1, MSEL4CR_MSEL22_0), \ + PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2, MSEL4CR_MSEL21_1), + PINMUX_DATA(PORT163_SCIFB_RTS__MARK, PORT163_FN1, MSEL4CR_MSEL22_0), \ + PINMUX_DATA(PORT163_SCIFA5_RTS__MARK, PORT163_FN2, MSEL4CR_MSEL21_1), \ + PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5), + PINMUX_DATA(LCDD0_MARK, PORT192_FN1), + PINMUX_DATA(LCDD1_MARK, PORT193_FN1), \ + PINMUX_DATA(PORT193_SCIFA5_CTS__MARK, PORT193_FN3, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_1), \ + PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN5), + PINMUX_DATA(LCDD2_MARK, PORT194_FN1), \ + PINMUX_DATA(PORT194_SCIFA5_RTS__MARK, PORT194_FN3, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_1), \ + PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN5), + PINMUX_DATA(LCDD3_MARK, PORT195_FN1), \ + PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_1), \ + PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN5), + PINMUX_DATA(LCDD4_MARK, PORT196_FN1), \ + PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_1), + PINMUX_DATA(LCDD5_MARK, PORT197_FN1), \ + PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_1), \ + PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN5), \ + PINMUX_DATA(TPU2TO1_MARK, PORT197_FN7), + PINMUX_DATA(LCDD6_MARK, PORT198_FN1), + PINMUX_DATA(LCDD7_MARK, PORT199_FN1), \ + PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2), \ + PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN5), + PINMUX_DATA(LCDD8_MARK, PORT200_FN1), \ + PINMUX_DATA(D16_MARK, PORT200_FN6), + PINMUX_DATA(LCDD9_MARK, PORT201_FN1), \ + PINMUX_DATA(D17_MARK, PORT201_FN6), + PINMUX_DATA(LCDD10_MARK, PORT202_FN1), \ + PINMUX_DATA(D18_MARK, PORT202_FN6), + PINMUX_DATA(LCDD11_MARK, PORT203_FN1), \ + PINMUX_DATA(D19_MARK, PORT203_FN6), + PINMUX_DATA(LCDD12_MARK, PORT204_FN1), \ + PINMUX_DATA(D20_MARK, PORT204_FN6), + PINMUX_DATA(LCDD13_MARK, PORT205_FN1), \ + PINMUX_DATA(D21_MARK, PORT205_FN6), + PINMUX_DATA(LCDD14_MARK, PORT206_FN1), \ + PINMUX_DATA(D22_MARK, PORT206_FN6), + PINMUX_DATA(LCDD15_MARK, PORT207_FN1), \ + PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D23_MARK, PORT207_FN6), + PINMUX_DATA(LCDD16_MARK, PORT208_FN1), \ + PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D24_MARK, PORT208_FN6), + PINMUX_DATA(LCDD17_MARK, PORT209_FN1), \ + PINMUX_DATA(D25_MARK, PORT209_FN6), + PINMUX_DATA(LCDD18_MARK, PORT210_FN1), \ + PINMUX_DATA(DREQ2_MARK, PORT210_FN2), \ + PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D26_MARK, PORT210_FN6), + PINMUX_DATA(LCDD19_MARK, PORT211_FN1), \ + PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D27_MARK, PORT211_FN6), + PINMUX_DATA(LCDD20_MARK, PORT212_FN1), \ + PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2), \ + PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D28_MARK, PORT212_FN6), + PINMUX_DATA(LCDD21_MARK, PORT213_FN1), \ + PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2), \ + PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D29_MARK, PORT213_FN6), + PINMUX_DATA(LCDD22_MARK, PORT214_FN1), \ + PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2), \ + PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D30_MARK, PORT214_FN6), + PINMUX_DATA(LCDD23_MARK, PORT215_FN1), \ + PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2), \ + PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(D31_MARK, PORT215_FN6), + PINMUX_DATA(LCDDCK_MARK, PORT216_FN1), \ + PINMUX_DATA(LCDWR__MARK, PORT216_FN2), + PINMUX_DATA(LCDRD__MARK, PORT217_FN1), \ + PINMUX_DATA(DACK2_MARK, PORT217_FN2), \ + PINMUX_DATA(PORT217_LCD2RS_MARK, PORT217_FN3), \ + PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(VIO2_FIELD3_MARK, PORT217_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_1), \ + PINMUX_DATA(PORT217_LCD2DISP_MARK, PORT217_FN7), + PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1), \ + PINMUX_DATA(LCDCS__MARK, PORT218_FN2), \ + PINMUX_DATA(LCDCS2__MARK, PORT218_FN3), \ + PINMUX_DATA(DACK3_MARK, PORT218_FN4), \ + PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5), + PINMUX_DATA(LCDDISP_MARK, PORT219_FN1), \ + PINMUX_DATA(LCDRS_MARK, PORT219_FN2), \ + PINMUX_DATA(PORT219_LCD2WR__MARK, PORT219_FN3), \ + PINMUX_DATA(DREQ3_MARK, PORT219_FN4), \ + PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(VIO2_CLK3_MARK, PORT219_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_1), \ + PINMUX_DATA(LCD2DCK_2_MARK, PORT219_FN7), + PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1), \ + PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2), + PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1), \ + PINMUX_DATA(DREQ1_MARK, PORT221_FN2), \ + PINMUX_DATA(PORT221_LCD2CS__MARK, PORT221_FN3), \ + PINMUX_DATA(PWEN_MARK, PORT221_FN4), \ + PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(VIO2_HD3_MARK, PORT221_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_1), \ + PINMUX_DATA(PORT221_LCD2HSYN_MARK, PORT221_FN7), + PINMUX_DATA(LCDDON_MARK, PORT222_FN1), \ + PINMUX_DATA(LCDDON2_MARK, PORT222_FN2), \ + PINMUX_DATA(DACK1_MARK, PORT222_FN3), \ + PINMUX_DATA(OVCN_MARK, PORT222_FN4), \ + PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5, MSEL3CR_MSEL11_1), \ + PINMUX_DATA(VIO2_VD3_MARK, PORT222_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_1), \ + PINMUX_DATA(PORT222_LCD2VSYN_MARK, PORT222_FN7, MSEL3CR_MSEL2_1), + + PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN2), \ + PINMUX_DATA(OVCN2_MARK, PORT225_FN4), + PINMUX_DATA(EXTLP_MARK, PORT226_FN1), \ + PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2), \ + PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN5), + PINMUX_DATA(SCIFA1_RTS__MARK, PORT227_FN2), \ + PINMUX_DATA(IDIN_MARK, PORT227_FN4), + PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN2), + PINMUX_DATA(SCIFA1_CTS__MARK, PORT229_FN2), \ + PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN3), + PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1), \ + PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2, MSEL3CR_MSEL9_1), + PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1), \ + PINMUX_DATA(SCIFA2_CTS2__MARK, PORT231_FN2, MSEL3CR_MSEL9_1), + PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1), \ + PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2, MSEL3CR_MSEL9_1), + PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1), \ + PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2, MSEL3CR_MSEL9_1), + PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1), \ + PINMUX_DATA(SCIFA2_RTS2__MARK, PORT234_FN2, MSEL3CR_MSEL9_1), \ + PINMUX_DATA(VIO2_CLK2_MARK, PORT234_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0), \ + PINMUX_DATA(LCD2D20_MARK, PORT234_FN7), + PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1), \ + PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3), \ + PINMUX_DATA(VIO2_VD2_MARK, PORT235_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0), \ + PINMUX_DATA(LCD2D21_MARK, PORT235_FN7), + PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1), \ + PINMUX_DATA(PORT236_I2C_SDA2_MARK, PORT236_FN2, MSEL2CR_MSEL17_0, + MSEL2CR_MSEL16_0), + PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1), \ + PINMUX_DATA(PORT237_I2C_SCL2_MARK, PORT237_FN2, MSEL2CR_MSEL17_0, + MSEL2CR_MSEL16_0), + PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1), \ + PINMUX_DATA(VIO2_FIELD2_MARK, PORT238_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0), \ + PINMUX_DATA(LCD2D22_MARK, PORT238_FN7), + PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1), \ + PINMUX_DATA(VIO2_HD2_MARK, PORT239_FN6, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0), \ + PINMUX_DATA(LCD2D23_MARK, PORT239_FN7), + PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1), + PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1, MSEL4CR_MSEL19_0), \ + PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2), \ + PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3), \ + PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4), + PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1, MSEL4CR_MSEL19_0), \ + PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN3), + PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1, MSEL4CR_MSEL19_0), \ + PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2), + PINMUX_DATA(PORT244_SCIFA5_CTS__MARK, PORT244_FN1, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_0), \ + PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2), \ + PINMUX_DATA(PORT244_SCIFB_CTS__MARK, PORT244_FN3, MSEL4CR_MSEL22_1), \ + PINMUX_DATA(MSIOF2R_RXD_MARK, PORT244_FN7, MSEL4CR_MSEL11_1), + PINMUX_DATA(PORT245_SCIFA5_RTS__MARK, PORT245_FN1, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_0), \ + PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2), \ + PINMUX_DATA(PORT245_SCIFB_RTS__MARK, PORT245_FN3, MSEL4CR_MSEL22_1), \ + PINMUX_DATA(MSIOF2R_TXD_MARK, PORT245_FN7, MSEL4CR_MSEL11_1), + PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_0), \ + PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2), \ + PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3, MSEL4CR_MSEL22_1), \ + PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4), + PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_0), \ + PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2), \ + PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3, MSEL4CR_MSEL22_1), \ + PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4), + PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1, MSEL4CR_MSEL21_0, + MSEL4CR_MSEL20_0), \ + PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2), \ + PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3, MSEL4CR_MSEL22_1), \ + PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4), \ + PINMUX_DATA(PORT248_I2C_SCL3_MARK, PORT248_FN5, MSEL2CR_MSEL19_0, + MSEL2CR_MSEL18_0), \ + PINMUX_DATA(MSIOF2R_TSCK_MARK, PORT248_FN7, MSEL4CR_MSEL11_1), + PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1), \ + PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2), \ + PINMUX_DATA(PORT249_I2C_SDA3_MARK, PORT249_FN5, MSEL2CR_MSEL19_0, + MSEL2CR_MSEL18_0), \ + PINMUX_DATA(MSIOF2R_TSYNC_MARK, PORT249_FN7, MSEL4CR_MSEL11_1), + PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1), + PINMUX_DATA(SDHICD0_MARK, PORT251_FN1), + PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1), + PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1), + PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1), + PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1), + PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1), + PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1), + PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1), + PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1), \ + PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3), + PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1), \ + PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3), + PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1), \ + PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3), + PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1), \ + PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3), + PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1), + PINMUX_DATA(SDHICLK2_MARK, PORT264_FN1), + PINMUX_DATA(SDHID2_0_MARK, PORT265_FN1), \ + PINMUX_DATA(TS_SPSYNC4_MARK, PORT265_FN3), + PINMUX_DATA(SDHID2_1_MARK, PORT266_FN1), \ + PINMUX_DATA(TS_SDAT4_MARK, PORT266_FN3), + PINMUX_DATA(SDHID2_2_MARK, PORT267_FN1), \ + PINMUX_DATA(TS_SDEN4_MARK, PORT267_FN3), + PINMUX_DATA(SDHID2_3_MARK, PORT268_FN1), \ + PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3), + PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1), + PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, PORT271_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, PORT272_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, PORT273_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, PORT274_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, PORT275_IN_PU, + MSEL4CR_MSEL15_0), \ + PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3), + PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, PORT276_IN_PU, + MSEL4CR_MSEL15_0), \ + PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3), + PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, PORT277_IN_PU, + MSEL4CR_MSEL15_0), \ + PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3), + PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, PORT278_IN_PU, + MSEL4CR_MSEL15_0), \ + PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3), + PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, PORT279_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \ + PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2), + PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1), + PINMUX_DATA(MCP_CKO_MARK, PORT289_FN1), \ + PINMUX_DATA(MMCCLK1_MARK, PORT289_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D15_MCP_NAF15_MARK, PORT290_FN1), + PINMUX_DATA(MCP_D14_MCP_NAF14_MARK, PORT291_FN1), + PINMUX_DATA(MCP_D13_MCP_NAF13_MARK, PORT292_FN1), + PINMUX_DATA(MCP_D12_MCP_NAF12_MARK, PORT293_FN1), + PINMUX_DATA(MCP_D11_MCP_NAF11_MARK, PORT294_FN1), + PINMUX_DATA(MCP_D10_MCP_NAF10_MARK, PORT295_FN1), + PINMUX_DATA(MCP_D9_MCP_NAF9_MARK, PORT296_FN1), + PINMUX_DATA(MCP_D8_MCP_NAF8_MARK, PORT297_FN1), \ + PINMUX_DATA(MMCCMD1_MARK, PORT297_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D7_MCP_NAF7_MARK, PORT298_FN1), \ + PINMUX_DATA(MMCD1_7_MARK, PORT298_FN2, MSEL4CR_MSEL15_1), + + PINMUX_DATA(MCP_D6_MCP_NAF6_MARK, PORT299_FN1), \ + PINMUX_DATA(MMCD1_6_MARK, PORT299_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D5_MCP_NAF5_MARK, PORT300_FN1), \ + PINMUX_DATA(MMCD1_5_MARK, PORT300_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D4_MCP_NAF4_MARK, PORT301_FN1), \ + PINMUX_DATA(MMCD1_4_MARK, PORT301_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D3_MCP_NAF3_MARK, PORT302_FN1), \ + PINMUX_DATA(MMCD1_3_MARK, PORT302_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D2_MCP_NAF2_MARK, PORT303_FN1), \ + PINMUX_DATA(MMCD1_2_MARK, PORT303_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D1_MCP_NAF1_MARK, PORT304_FN1), \ + PINMUX_DATA(MMCD1_1_MARK, PORT304_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_D0_MCP_NAF0_MARK, PORT305_FN1), \ + PINMUX_DATA(MMCD1_0_MARK, PORT305_FN2, MSEL4CR_MSEL15_1), + PINMUX_DATA(MCP_NBRSTOUT__MARK, PORT306_FN1), + PINMUX_DATA(MCP_WE0__MCP_FWE_MARK, PORT309_FN1), \ + PINMUX_DATA(MCP_RDWR_MCP_FWE_MARK, PORT309_FN2), + + /* MSEL2 special cases */ + PINMUX_DATA(TSIF2_TS_XX1_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0, + MSEL2CR_MSEL12_0), + PINMUX_DATA(TSIF2_TS_XX2_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0, + MSEL2CR_MSEL12_1), + PINMUX_DATA(TSIF2_TS_XX3_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1, + MSEL2CR_MSEL12_0), + PINMUX_DATA(TSIF2_TS_XX4_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1, + MSEL2CR_MSEL12_1), + PINMUX_DATA(TSIF2_TS_XX5_MARK, MSEL2CR_MSEL14_1, MSEL2CR_MSEL13_0, + MSEL2CR_MSEL12_0), + PINMUX_DATA(TSIF1_TS_XX1_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0, + MSEL2CR_MSEL9_0), + PINMUX_DATA(TSIF1_TS_XX2_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0, + MSEL2CR_MSEL9_1), + PINMUX_DATA(TSIF1_TS_XX3_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1, + MSEL2CR_MSEL9_0), + PINMUX_DATA(TSIF1_TS_XX4_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1, + MSEL2CR_MSEL9_1), + PINMUX_DATA(TSIF1_TS_XX5_MARK, MSEL2CR_MSEL11_1, MSEL2CR_MSEL10_0, + MSEL2CR_MSEL9_0), + PINMUX_DATA(TSIF0_TS_XX1_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0, + MSEL2CR_MSEL6_0), + PINMUX_DATA(TSIF0_TS_XX2_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0, + MSEL2CR_MSEL6_1), + PINMUX_DATA(TSIF0_TS_XX3_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1, + MSEL2CR_MSEL6_0), + PINMUX_DATA(TSIF0_TS_XX4_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1, + MSEL2CR_MSEL6_1), + PINMUX_DATA(TSIF0_TS_XX5_MARK, MSEL2CR_MSEL8_1, MSEL2CR_MSEL7_0, + MSEL2CR_MSEL6_0), + PINMUX_DATA(MST1_TS_XX1_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0, + MSEL2CR_MSEL3_0), + PINMUX_DATA(MST1_TS_XX2_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0, + MSEL2CR_MSEL3_1), + PINMUX_DATA(MST1_TS_XX3_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1, + MSEL2CR_MSEL3_0), + PINMUX_DATA(MST1_TS_XX4_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1, + MSEL2CR_MSEL3_1), + PINMUX_DATA(MST1_TS_XX5_MARK, MSEL2CR_MSEL5_1, MSEL2CR_MSEL4_0, + MSEL2CR_MSEL3_0), + PINMUX_DATA(MST0_TS_XX1_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0, + MSEL2CR_MSEL0_0), + PINMUX_DATA(MST0_TS_XX2_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0, + MSEL2CR_MSEL0_1), + PINMUX_DATA(MST0_TS_XX3_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1, + MSEL2CR_MSEL0_0), + PINMUX_DATA(MST0_TS_XX4_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1, + MSEL2CR_MSEL0_1), + PINMUX_DATA(MST0_TS_XX5_MARK, MSEL2CR_MSEL2_1, MSEL2CR_MSEL1_0, + MSEL2CR_MSEL0_0), + + /* MSEL3 special cases */ + PINMUX_DATA(SDHI0_VCCQ_MC0_ON_MARK, MSEL3CR_MSEL28_1), + PINMUX_DATA(SDHI0_VCCQ_MC0_OFF_MARK, MSEL3CR_MSEL28_0), + PINMUX_DATA(DEBUG_MON_VIO_MARK, MSEL3CR_MSEL15_0), + PINMUX_DATA(DEBUG_MON_LCDD_MARK, MSEL3CR_MSEL15_1), + PINMUX_DATA(LCDC_LCDC0_MARK, MSEL3CR_MSEL6_0), + PINMUX_DATA(LCDC_LCDC1_MARK, MSEL3CR_MSEL6_1), + + /* MSEL4 special cases */ + PINMUX_DATA(IRQ9_MEM_INT_MARK, MSEL4CR_MSEL29_0), + PINMUX_DATA(IRQ9_MCP_INT_MARK, MSEL4CR_MSEL29_1), + PINMUX_DATA(A11_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_0), + PINMUX_DATA(KEYOUT8_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_1), + PINMUX_DATA(TPU4TO3_MARK, MSEL4CR_MSEL13_1, MSEL4CR_MSEL12_0), + PINMUX_DATA(RESETA_N_PU_ON_MARK, MSEL4CR_MSEL4_0), + PINMUX_DATA(RESETA_N_PU_OFF_MARK, MSEL4CR_MSEL4_1), + PINMUX_DATA(EDBGREQ_PD_MARK, MSEL4CR_MSEL1_0), + PINMUX_DATA(EDBGREQ_PU_MARK, MSEL4CR_MSEL1_1), + + /* Functions with pull-ups */ + PINMUX_DATA(KEYIN0_PU_MARK, PORT66_FN2, PORT66_IN_PU), + PINMUX_DATA(KEYIN1_PU_MARK, PORT67_FN2, PORT67_IN_PU), + PINMUX_DATA(KEYIN2_PU_MARK, PORT68_FN2, PORT68_IN_PU), + PINMUX_DATA(KEYIN3_PU_MARK, PORT69_FN2, PORT69_IN_PU), + PINMUX_DATA(KEYIN4_PU_MARK, PORT70_FN2, PORT70_IN_PU), + PINMUX_DATA(KEYIN5_PU_MARK, PORT71_FN2, PORT71_IN_PU), + PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU), + PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU), + + PINMUX_DATA(SDHICD0_PU_MARK, PORT251_FN1, PORT251_IN_PU), + PINMUX_DATA(SDHID0_0_PU_MARK, PORT252_FN1, PORT252_IN_PU), + PINMUX_DATA(SDHID0_1_PU_MARK, PORT253_FN1, PORT253_IN_PU), + PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU), + PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU), + PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU), + PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT256_IN_PU), + PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU), + PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU), + PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU), + PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_FN1, PORT262_IN_PU), + PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_FN1, PORT263_IN_PU), + PINMUX_DATA(SDHID2_0_PU_MARK, PORT265_FN1, PORT265_IN_PU), + PINMUX_DATA(SDHID2_1_PU_MARK, PORT266_FN1, PORT266_IN_PU), + PINMUX_DATA(SDHID2_2_PU_MARK, PORT267_FN1, PORT267_IN_PU), + PINMUX_DATA(SDHID2_3_PU_MARK, PORT268_FN1, PORT268_IN_PU), + PINMUX_DATA(SDHICMD2_PU_MARK, PORT269_FN1, PORT269_IN_PU), + + PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU, + MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU, + MSEL4CR_MSEL15_1), + + PINMUX_DATA(MMCD0_0_PU_MARK, + PORT271_FN1, PORT271_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_1_PU_MARK, + PORT272_FN1, PORT272_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_2_PU_MARK, + PORT273_FN1, PORT273_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_3_PU_MARK, + PORT274_FN1, PORT274_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_4_PU_MARK, + PORT275_FN1, PORT275_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_5_PU_MARK, + PORT276_FN1, PORT276_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_6_PU_MARK, + PORT277_FN1, PORT277_IN_PU, MSEL4CR_MSEL15_0), + PINMUX_DATA(MMCD0_7_PU_MARK, + PORT278_FN1, PORT278_IN_PU, MSEL4CR_MSEL15_0), + + PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU), + PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU), + PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU), + PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU), + PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU), +}; + +static struct pinmux_gpio pinmux_gpios[] = { + GPIO_PORT_ALL(), + + /* Table 25-1 (Functions 0-7) */ + GPIO_FN(VBUS_0), + GPIO_FN(GPI0), + GPIO_FN(GPI1), + GPIO_FN(GPI2), + GPIO_FN(GPI3), + GPIO_FN(GPI4), + GPIO_FN(GPI5), + GPIO_FN(GPI6), + GPIO_FN(GPI7), + GPIO_FN(SCIFA7_RXD), + GPIO_FN(SCIFA7_CTS_), + GPIO_FN(GPO7), \ + GPIO_FN(MFG0_OUT2), + GPIO_FN(GPO6), \ + GPIO_FN(MFG1_OUT2), + GPIO_FN(GPO5), \ + GPIO_FN(SCIFA0_SCK), \ + GPIO_FN(FSICOSLDT3), \ + GPIO_FN(PORT16_VIO_CKOR), + GPIO_FN(SCIFA0_TXD), + GPIO_FN(SCIFA7_TXD), + GPIO_FN(SCIFA7_RTS_), \ + GPIO_FN(PORT19_VIO_CKO2), + GPIO_FN(GPO0), + GPIO_FN(GPO1), + GPIO_FN(GPO2), \ + GPIO_FN(STATUS0), + GPIO_FN(GPO3), \ + GPIO_FN(STATUS1), + GPIO_FN(GPO4), \ + GPIO_FN(STATUS2), + GPIO_FN(VINT), + GPIO_FN(TCKON), + GPIO_FN(XDVFS1), \ + GPIO_FN(PORT27_I2C_SCL2), \ + GPIO_FN(PORT27_I2C_SCL3), \ + GPIO_FN(MFG0_OUT1), \ + GPIO_FN(PORT27_IROUT), + GPIO_FN(XDVFS2), \ + GPIO_FN(PORT28_I2C_SDA2), \ + GPIO_FN(PORT28_I2C_SDA3), \ + GPIO_FN(PORT28_TPU1TO1), + GPIO_FN(SIM_RST), \ + GPIO_FN(PORT29_TPU1TO1), + GPIO_FN(SIM_CLK), \ + GPIO_FN(PORT30_VIO_CKOR), + GPIO_FN(SIM_D), \ + GPIO_FN(PORT31_IROUT), + GPIO_FN(SCIFA4_TXD), + GPIO_FN(SCIFA4_RXD), \ + GPIO_FN(XWUP), + GPIO_FN(SCIFA4_RTS_), + GPIO_FN(SCIFA4_CTS_), + GPIO_FN(FSIBOBT), \ + GPIO_FN(FSIBIBT), + GPIO_FN(FSIBOLR), \ + GPIO_FN(FSIBILR), + GPIO_FN(FSIBOSLD), + GPIO_FN(FSIBISLD), + GPIO_FN(VACK), + GPIO_FN(XTAL1L), + GPIO_FN(SCIFA0_RTS_), \ + GPIO_FN(FSICOSLDT2), + GPIO_FN(SCIFA0_RXD), + GPIO_FN(SCIFA0_CTS_), \ + GPIO_FN(FSICOSLDT1), + GPIO_FN(FSICOBT), \ + GPIO_FN(FSICIBT), \ + GPIO_FN(FSIDOBT), \ + GPIO_FN(FSIDIBT), + GPIO_FN(FSICOLR), \ + GPIO_FN(FSICILR), \ + GPIO_FN(FSIDOLR), \ + GPIO_FN(FSIDILR), + GPIO_FN(FSICOSLD), \ + GPIO_FN(PORT47_FSICSPDIF), + GPIO_FN(FSICISLD), \ + GPIO_FN(FSIDISLD), + GPIO_FN(FSIACK), \ + GPIO_FN(PORT49_IRDA_OUT), \ + GPIO_FN(PORT49_IROUT), \ + GPIO_FN(FSIAOMC), + GPIO_FN(FSIAOLR), \ + GPIO_FN(BBIF2_TSYNC2), \ + GPIO_FN(TPU2TO2), \ + GPIO_FN(FSIAILR), + + GPIO_FN(FSIAOBT), \ + GPIO_FN(BBIF2_TSCK2), \ + GPIO_FN(TPU2TO3), \ + GPIO_FN(FSIAIBT), + GPIO_FN(FSIAOSLD), \ + GPIO_FN(BBIF2_TXD2), + GPIO_FN(FSIASPDIF), \ + GPIO_FN(PORT53_IRDA_IN), \ + GPIO_FN(TPU3TO3), \ + GPIO_FN(FSIBSPDIF), \ + GPIO_FN(PORT53_FSICSPDIF), + GPIO_FN(FSIBCK), \ + GPIO_FN(PORT54_IRDA_FIRSEL), \ + GPIO_FN(TPU3TO2), \ + GPIO_FN(FSIBOMC), \ + GPIO_FN(FSICCK), \ + GPIO_FN(FSICOMC), + GPIO_FN(FSIAISLD), \ + GPIO_FN(TPU0TO0), + GPIO_FN(A0), \ + GPIO_FN(BS_), + GPIO_FN(A12), \ + GPIO_FN(PORT58_KEYOUT7), \ + GPIO_FN(TPU4TO2), + GPIO_FN(A13), \ + GPIO_FN(PORT59_KEYOUT6), \ + GPIO_FN(TPU0TO1), + GPIO_FN(A14), \ + GPIO_FN(KEYOUT5), + GPIO_FN(A15), \ + GPIO_FN(KEYOUT4), + GPIO_FN(A16), \ + GPIO_FN(KEYOUT3), \ + GPIO_FN(MSIOF0_SS1), + GPIO_FN(A17), \ + GPIO_FN(KEYOUT2), \ + GPIO_FN(MSIOF0_TSYNC), + GPIO_FN(A18), \ + GPIO_FN(KEYOUT1), \ + GPIO_FN(MSIOF0_TSCK), + GPIO_FN(A19), \ + GPIO_FN(KEYOUT0), \ + GPIO_FN(MSIOF0_TXD), + GPIO_FN(A20), \ + GPIO_FN(KEYIN0), \ + GPIO_FN(MSIOF0_RSCK), + GPIO_FN(A21), \ + GPIO_FN(KEYIN1), \ + GPIO_FN(MSIOF0_RSYNC), + GPIO_FN(A22), \ + GPIO_FN(KEYIN2), \ + GPIO_FN(MSIOF0_MCK0), + GPIO_FN(A23), \ + GPIO_FN(KEYIN3), \ + GPIO_FN(MSIOF0_MCK1), + GPIO_FN(A24), \ + GPIO_FN(KEYIN4), \ + GPIO_FN(MSIOF0_RXD), + GPIO_FN(A25), \ + GPIO_FN(KEYIN5), \ + GPIO_FN(MSIOF0_SS2), + GPIO_FN(A26), \ + GPIO_FN(KEYIN6), + GPIO_FN(KEYIN7), + GPIO_FN(D0_NAF0), + GPIO_FN(D1_NAF1), + GPIO_FN(D2_NAF2), + GPIO_FN(D3_NAF3), + GPIO_FN(D4_NAF4), + GPIO_FN(D5_NAF5), + GPIO_FN(D6_NAF6), + GPIO_FN(D7_NAF7), + GPIO_FN(D8_NAF8), + GPIO_FN(D9_NAF9), + GPIO_FN(D10_NAF10), + GPIO_FN(D11_NAF11), + GPIO_FN(D12_NAF12), + GPIO_FN(D13_NAF13), + GPIO_FN(D14_NAF14), + GPIO_FN(D15_NAF15), + GPIO_FN(CS4_), + GPIO_FN(CS5A_), \ + GPIO_FN(PORT91_RDWR), + GPIO_FN(CS5B_), \ + GPIO_FN(FCE1_), + GPIO_FN(CS6B_), \ + GPIO_FN(DACK0), + GPIO_FN(FCE0_), \ + GPIO_FN(CS6A_), + GPIO_FN(WAIT_), \ + GPIO_FN(DREQ0), + GPIO_FN(RD__FSC), + GPIO_FN(WE0__FWE), \ + GPIO_FN(RDWR_FWE), + GPIO_FN(WE1_), + GPIO_FN(FRB), + GPIO_FN(CKO), + GPIO_FN(NBRSTOUT_), + GPIO_FN(NBRST_), + GPIO_FN(BBIF2_TXD), + GPIO_FN(BBIF2_RXD), + GPIO_FN(BBIF2_SYNC), + GPIO_FN(BBIF2_SCK), + GPIO_FN(SCIFA3_CTS_), \ + GPIO_FN(MFG3_IN2), + GPIO_FN(SCIFA3_RXD), \ + GPIO_FN(MFG3_IN1), + GPIO_FN(BBIF1_SS2), \ + GPIO_FN(SCIFA3_RTS_), \ + GPIO_FN(MFG3_OUT1), + GPIO_FN(SCIFA3_TXD), + GPIO_FN(HSI_RX_DATA), \ + GPIO_FN(BBIF1_RXD), + GPIO_FN(HSI_TX_WAKE), \ + GPIO_FN(BBIF1_TSCK), + GPIO_FN(HSI_TX_DATA), \ + GPIO_FN(BBIF1_TSYNC), + GPIO_FN(HSI_TX_READY), \ + GPIO_FN(BBIF1_TXD), + GPIO_FN(HSI_RX_READY), \ + GPIO_FN(BBIF1_RSCK), \ + GPIO_FN(PORT115_I2C_SCL2), \ + GPIO_FN(PORT115_I2C_SCL3), + GPIO_FN(HSI_RX_WAKE), \ + GPIO_FN(BBIF1_RSYNC), \ + GPIO_FN(PORT116_I2C_SDA2), \ + GPIO_FN(PORT116_I2C_SDA3), + GPIO_FN(HSI_RX_FLAG), \ + GPIO_FN(BBIF1_SS1), \ + GPIO_FN(BBIF1_FLOW), + GPIO_FN(HSI_TX_FLAG), + GPIO_FN(VIO_VD), \ + GPIO_FN(PORT128_LCD2VSYN), \ + GPIO_FN(VIO2_VD), \ + GPIO_FN(LCD2D0), + + GPIO_FN(VIO_HD), \ + GPIO_FN(PORT129_LCD2HSYN), \ + GPIO_FN(PORT129_LCD2CS_), \ + GPIO_FN(VIO2_HD), \ + GPIO_FN(LCD2D1), + GPIO_FN(VIO_D0), \ + GPIO_FN(PORT130_MSIOF2_RXD), \ + GPIO_FN(LCD2D10), + GPIO_FN(VIO_D1), \ + GPIO_FN(PORT131_KEYOUT6), \ + GPIO_FN(PORT131_MSIOF2_SS1), \ + GPIO_FN(PORT131_KEYOUT11), \ + GPIO_FN(LCD2D11), + GPIO_FN(VIO_D2), \ + GPIO_FN(PORT132_KEYOUT7), \ + GPIO_FN(PORT132_MSIOF2_SS2), \ + GPIO_FN(PORT132_KEYOUT10), \ + GPIO_FN(LCD2D12), + GPIO_FN(VIO_D3), \ + GPIO_FN(MSIOF2_TSYNC), \ + GPIO_FN(LCD2D13), + GPIO_FN(VIO_D4), \ + GPIO_FN(MSIOF2_TXD), \ + GPIO_FN(LCD2D14), + GPIO_FN(VIO_D5), \ + GPIO_FN(MSIOF2_TSCK), \ + GPIO_FN(LCD2D15), + GPIO_FN(VIO_D6), \ + GPIO_FN(PORT136_KEYOUT8), \ + GPIO_FN(LCD2D16), + GPIO_FN(VIO_D7), \ + GPIO_FN(PORT137_KEYOUT9), \ + GPIO_FN(LCD2D17), + GPIO_FN(VIO_D8), \ + GPIO_FN(PORT138_KEYOUT8), \ + GPIO_FN(VIO2_D0), \ + GPIO_FN(LCD2D6), + GPIO_FN(VIO_D9), \ + GPIO_FN(PORT139_KEYOUT9), \ + GPIO_FN(VIO2_D1), \ + GPIO_FN(LCD2D7), + GPIO_FN(VIO_D10), \ + GPIO_FN(TPU0TO2), \ + GPIO_FN(VIO2_D2), \ + GPIO_FN(LCD2D8), + GPIO_FN(VIO_D11), \ + GPIO_FN(TPU0TO3), \ + GPIO_FN(VIO2_D3), \ + GPIO_FN(LCD2D9), + GPIO_FN(VIO_D12), \ + GPIO_FN(PORT142_KEYOUT10), \ + GPIO_FN(VIO2_D4), \ + GPIO_FN(LCD2D2), + GPIO_FN(VIO_D13), \ + GPIO_FN(PORT143_KEYOUT11), \ + GPIO_FN(PORT143_KEYOUT6), \ + GPIO_FN(VIO2_D5), \ + GPIO_FN(LCD2D3), + GPIO_FN(VIO_D14), \ + GPIO_FN(PORT144_KEYOUT7), \ + GPIO_FN(VIO2_D6), \ + GPIO_FN(LCD2D4), + GPIO_FN(VIO_D15), \ + GPIO_FN(TPU1TO3), \ + GPIO_FN(PORT145_LCD2DISP), \ + GPIO_FN(PORT145_LCD2RS), \ + GPIO_FN(VIO2_D7), \ + GPIO_FN(LCD2D5), + GPIO_FN(VIO_CLK), \ + GPIO_FN(LCD2DCK), \ + GPIO_FN(PORT146_LCD2WR_), \ + GPIO_FN(VIO2_CLK), \ + GPIO_FN(LCD2D18), + GPIO_FN(VIO_FIELD), \ + GPIO_FN(LCD2RD_), \ + GPIO_FN(VIO2_FIELD), \ + GPIO_FN(LCD2D19), + GPIO_FN(VIO_CKO), + GPIO_FN(A27), \ + GPIO_FN(PORT149_RDWR), \ + GPIO_FN(MFG0_IN1), \ + GPIO_FN(PORT149_KEYOUT9), + GPIO_FN(MFG0_IN2), + GPIO_FN(TS_SPSYNC3), \ + GPIO_FN(MSIOF2_RSCK), + GPIO_FN(TS_SDAT3), \ + GPIO_FN(MSIOF2_RSYNC), + GPIO_FN(TPU1TO2), \ + GPIO_FN(TS_SDEN3), \ + GPIO_FN(PORT153_MSIOF2_SS1), + GPIO_FN(SCIFA2_TXD1), \ + GPIO_FN(MSIOF2_MCK0), + GPIO_FN(SCIFA2_RXD1), \ + GPIO_FN(MSIOF2_MCK1), + GPIO_FN(SCIFA2_RTS1_), \ + GPIO_FN(PORT156_MSIOF2_SS2), + GPIO_FN(SCIFA2_CTS1_), \ + GPIO_FN(PORT157_MSIOF2_RXD), + GPIO_FN(DINT_), \ + GPIO_FN(SCIFA2_SCK1), \ + GPIO_FN(TS_SCK3), + GPIO_FN(PORT159_SCIFB_SCK), \ + GPIO_FN(PORT159_SCIFA5_SCK), \ + GPIO_FN(NMI), + GPIO_FN(PORT160_SCIFB_TXD), \ + GPIO_FN(PORT160_SCIFA5_TXD), + GPIO_FN(PORT161_SCIFB_CTS_), \ + GPIO_FN(PORT161_SCIFA5_CTS_), + GPIO_FN(PORT162_SCIFB_RXD), \ + GPIO_FN(PORT162_SCIFA5_RXD), + GPIO_FN(PORT163_SCIFB_RTS_), \ + GPIO_FN(PORT163_SCIFA5_RTS_), \ + GPIO_FN(TPU3TO0), + GPIO_FN(LCDD0), + GPIO_FN(LCDD1), \ + GPIO_FN(PORT193_SCIFA5_CTS_), \ + GPIO_FN(BBIF2_TSYNC1), + GPIO_FN(LCDD2), \ + GPIO_FN(PORT194_SCIFA5_RTS_), \ + GPIO_FN(BBIF2_TSCK1), + GPIO_FN(LCDD3), \ + GPIO_FN(PORT195_SCIFA5_RXD), \ + GPIO_FN(BBIF2_TXD1), + GPIO_FN(LCDD4), \ + GPIO_FN(PORT196_SCIFA5_TXD), + GPIO_FN(LCDD5), \ + GPIO_FN(PORT197_SCIFA5_SCK), \ + GPIO_FN(MFG2_OUT2), \ + GPIO_FN(TPU2TO1), + GPIO_FN(LCDD6), + GPIO_FN(LCDD7), \ + GPIO_FN(TPU4TO1), \ + GPIO_FN(MFG4_OUT2), + GPIO_FN(LCDD8), \ + GPIO_FN(D16), + GPIO_FN(LCDD9), \ + GPIO_FN(D17), + GPIO_FN(LCDD10), \ + GPIO_FN(D18), + GPIO_FN(LCDD11), \ + GPIO_FN(D19), + GPIO_FN(LCDD12), \ + GPIO_FN(D20), + GPIO_FN(LCDD13), \ + GPIO_FN(D21), + GPIO_FN(LCDD14), \ + GPIO_FN(D22), + GPIO_FN(LCDD15), \ + GPIO_FN(PORT207_MSIOF0L_SS1), \ + GPIO_FN(D23), + GPIO_FN(LCDD16), \ + GPIO_FN(PORT208_MSIOF0L_SS2), \ + GPIO_FN(D24), + GPIO_FN(LCDD17), \ + GPIO_FN(D25), + GPIO_FN(LCDD18), \ + GPIO_FN(DREQ2), \ + GPIO_FN(PORT210_MSIOF0L_SS1), \ + GPIO_FN(D26), + GPIO_FN(LCDD19), \ + GPIO_FN(PORT211_MSIOF0L_SS2), \ + GPIO_FN(D27), + GPIO_FN(LCDD20), \ + GPIO_FN(TS_SPSYNC1), \ + GPIO_FN(MSIOF0L_MCK0), \ + GPIO_FN(D28), + GPIO_FN(LCDD21), \ + GPIO_FN(TS_SDAT1), \ + GPIO_FN(MSIOF0L_MCK1), \ + GPIO_FN(D29), + GPIO_FN(LCDD22), \ + GPIO_FN(TS_SDEN1), \ + GPIO_FN(MSIOF0L_RSCK), \ + GPIO_FN(D30), + GPIO_FN(LCDD23), \ + GPIO_FN(TS_SCK1), \ + GPIO_FN(MSIOF0L_RSYNC), \ + GPIO_FN(D31), + GPIO_FN(LCDDCK), \ + GPIO_FN(LCDWR_), + GPIO_FN(LCDRD_), \ + GPIO_FN(DACK2), \ + GPIO_FN(PORT217_LCD2RS), \ + GPIO_FN(MSIOF0L_TSYNC), \ + GPIO_FN(VIO2_FIELD3), \ + GPIO_FN(PORT217_LCD2DISP), + GPIO_FN(LCDHSYN), \ + GPIO_FN(LCDCS_), \ + GPIO_FN(LCDCS2_), \ + GPIO_FN(DACK3), \ + GPIO_FN(PORT218_VIO_CKOR), + GPIO_FN(LCDDISP), \ + GPIO_FN(LCDRS), \ + GPIO_FN(PORT219_LCD2WR_), \ + GPIO_FN(DREQ3), \ + GPIO_FN(MSIOF0L_TSCK), \ + GPIO_FN(VIO2_CLK3), \ + GPIO_FN(LCD2DCK_2), + GPIO_FN(LCDVSYN), \ + GPIO_FN(LCDVSYN2), + GPIO_FN(LCDLCLK), \ + GPIO_FN(DREQ1), \ + GPIO_FN(PORT221_LCD2CS_), \ + GPIO_FN(PWEN), \ + GPIO_FN(MSIOF0L_RXD), \ + GPIO_FN(VIO2_HD3), \ + GPIO_FN(PORT221_LCD2HSYN), + GPIO_FN(LCDDON), \ + GPIO_FN(LCDDON2), \ + GPIO_FN(DACK1), \ + GPIO_FN(OVCN), \ + GPIO_FN(MSIOF0L_TXD), \ + GPIO_FN(VIO2_VD3), \ + GPIO_FN(PORT222_LCD2VSYN), + + GPIO_FN(SCIFA1_TXD), \ + GPIO_FN(OVCN2), + GPIO_FN(EXTLP), \ + GPIO_FN(SCIFA1_SCK), \ + GPIO_FN(PORT226_VIO_CKO2), + GPIO_FN(SCIFA1_RTS_), \ + GPIO_FN(IDIN), + GPIO_FN(SCIFA1_RXD), + GPIO_FN(SCIFA1_CTS_), \ + GPIO_FN(MFG1_IN1), + GPIO_FN(MSIOF1_TXD), \ + GPIO_FN(SCIFA2_TXD2), + GPIO_FN(MSIOF1_TSYNC), \ + GPIO_FN(SCIFA2_CTS2_), + GPIO_FN(MSIOF1_TSCK), \ + GPIO_FN(SCIFA2_SCK2), + GPIO_FN(MSIOF1_RXD), \ + GPIO_FN(SCIFA2_RXD2), + GPIO_FN(MSIOF1_RSCK), \ + GPIO_FN(SCIFA2_RTS2_), \ + GPIO_FN(VIO2_CLK2), \ + GPIO_FN(LCD2D20), + GPIO_FN(MSIOF1_RSYNC), \ + GPIO_FN(MFG1_IN2), \ + GPIO_FN(VIO2_VD2), \ + GPIO_FN(LCD2D21), + GPIO_FN(MSIOF1_MCK0), \ + GPIO_FN(PORT236_I2C_SDA2), + GPIO_FN(MSIOF1_MCK1), \ + GPIO_FN(PORT237_I2C_SCL2), + GPIO_FN(MSIOF1_SS1), \ + GPIO_FN(VIO2_FIELD2), \ + GPIO_FN(LCD2D22), + GPIO_FN(MSIOF1_SS2), \ + GPIO_FN(VIO2_HD2), \ + GPIO_FN(LCD2D23), + GPIO_FN(SCIFA6_TXD), + GPIO_FN(PORT241_IRDA_OUT), \ + GPIO_FN(PORT241_IROUT), \ + GPIO_FN(MFG4_OUT1), \ + GPIO_FN(TPU4TO0), + GPIO_FN(PORT242_IRDA_IN), \ + GPIO_FN(MFG4_IN2), + GPIO_FN(PORT243_IRDA_FIRSEL), \ + GPIO_FN(PORT243_VIO_CKO2), + GPIO_FN(PORT244_SCIFA5_CTS_), \ + GPIO_FN(MFG2_IN1), \ + GPIO_FN(PORT244_SCIFB_CTS_), \ + GPIO_FN(MSIOF2R_RXD), + GPIO_FN(PORT245_SCIFA5_RTS_), \ + GPIO_FN(MFG2_IN2), \ + GPIO_FN(PORT245_SCIFB_RTS_), \ + GPIO_FN(MSIOF2R_TXD), + GPIO_FN(PORT246_SCIFA5_RXD), \ + GPIO_FN(MFG1_OUT1), \ + GPIO_FN(PORT246_SCIFB_RXD), \ + GPIO_FN(TPU1TO0), + GPIO_FN(PORT247_SCIFA5_TXD), \ + GPIO_FN(MFG3_OUT2), \ + GPIO_FN(PORT247_SCIFB_TXD), \ + GPIO_FN(TPU3TO1), + GPIO_FN(PORT248_SCIFA5_SCK), \ + GPIO_FN(MFG2_OUT1), \ + GPIO_FN(PORT248_SCIFB_SCK), \ + GPIO_FN(TPU2TO0), \ + GPIO_FN(PORT248_I2C_SCL3), \ + GPIO_FN(MSIOF2R_TSCK), + GPIO_FN(PORT249_IROUT), \ + GPIO_FN(MFG4_IN1), \ + GPIO_FN(PORT249_I2C_SDA3), \ + GPIO_FN(MSIOF2R_TSYNC), + GPIO_FN(SDHICLK0), + GPIO_FN(SDHICD0), + GPIO_FN(SDHID0_0), + GPIO_FN(SDHID0_1), + GPIO_FN(SDHID0_2), + GPIO_FN(SDHID0_3), + GPIO_FN(SDHICMD0), + GPIO_FN(SDHIWP0), + GPIO_FN(SDHICLK1), + GPIO_FN(SDHID1_0), \ + GPIO_FN(TS_SPSYNC2), + GPIO_FN(SDHID1_1), \ + GPIO_FN(TS_SDAT2), + GPIO_FN(SDHID1_2), \ + GPIO_FN(TS_SDEN2), + GPIO_FN(SDHID1_3), \ + GPIO_FN(TS_SCK2), + GPIO_FN(SDHICMD1), + GPIO_FN(SDHICLK2), + GPIO_FN(SDHID2_0), \ + GPIO_FN(TS_SPSYNC4), + GPIO_FN(SDHID2_1), \ + GPIO_FN(TS_SDAT4), + GPIO_FN(SDHID2_2), \ + GPIO_FN(TS_SDEN4), + GPIO_FN(SDHID2_3), \ + GPIO_FN(TS_SCK4), + GPIO_FN(SDHICMD2), + GPIO_FN(MMCCLK0), + GPIO_FN(MMCD0_0), + GPIO_FN(MMCD0_1), + GPIO_FN(MMCD0_2), + GPIO_FN(MMCD0_3), + GPIO_FN(MMCD0_4), \ + GPIO_FN(TS_SPSYNC5), + GPIO_FN(MMCD0_5), \ + GPIO_FN(TS_SDAT5), + GPIO_FN(MMCD0_6), \ + GPIO_FN(TS_SDEN5), + GPIO_FN(MMCD0_7), \ + GPIO_FN(TS_SCK5), + GPIO_FN(MMCCMD0), + GPIO_FN(RESETOUTS_), \ + GPIO_FN(EXTAL2OUT), + GPIO_FN(MCP_WAIT__MCP_FRB), + GPIO_FN(MCP_CKO), \ + GPIO_FN(MMCCLK1), + GPIO_FN(MCP_D15_MCP_NAF15), + GPIO_FN(MCP_D14_MCP_NAF14), + GPIO_FN(MCP_D13_MCP_NAF13), + GPIO_FN(MCP_D12_MCP_NAF12), + GPIO_FN(MCP_D11_MCP_NAF11), + GPIO_FN(MCP_D10_MCP_NAF10), + GPIO_FN(MCP_D9_MCP_NAF9), + GPIO_FN(MCP_D8_MCP_NAF8), \ + GPIO_FN(MMCCMD1), + GPIO_FN(MCP_D7_MCP_NAF7), \ + GPIO_FN(MMCD1_7), + + GPIO_FN(MCP_D6_MCP_NAF6), \ + GPIO_FN(MMCD1_6), + GPIO_FN(MCP_D5_MCP_NAF5), \ + GPIO_FN(MMCD1_5), + GPIO_FN(MCP_D4_MCP_NAF4), \ + GPIO_FN(MMCD1_4), + GPIO_FN(MCP_D3_MCP_NAF3), \ + GPIO_FN(MMCD1_3), + GPIO_FN(MCP_D2_MCP_NAF2), \ + GPIO_FN(MMCD1_2), + GPIO_FN(MCP_D1_MCP_NAF1), \ + GPIO_FN(MMCD1_1), + GPIO_FN(MCP_D0_MCP_NAF0), \ + GPIO_FN(MMCD1_0), + GPIO_FN(MCP_NBRSTOUT_), + GPIO_FN(MCP_WE0__MCP_FWE), \ + GPIO_FN(MCP_RDWR_MCP_FWE), + + /* MSEL2 special cases */ + GPIO_FN(TSIF2_TS_XX1), + GPIO_FN(TSIF2_TS_XX2), + GPIO_FN(TSIF2_TS_XX3), + GPIO_FN(TSIF2_TS_XX4), + GPIO_FN(TSIF2_TS_XX5), + GPIO_FN(TSIF1_TS_XX1), + GPIO_FN(TSIF1_TS_XX2), + GPIO_FN(TSIF1_TS_XX3), + GPIO_FN(TSIF1_TS_XX4), + GPIO_FN(TSIF1_TS_XX5), + GPIO_FN(TSIF0_TS_XX1), + GPIO_FN(TSIF0_TS_XX2), + GPIO_FN(TSIF0_TS_XX3), + GPIO_FN(TSIF0_TS_XX4), + GPIO_FN(TSIF0_TS_XX5), + GPIO_FN(MST1_TS_XX1), + GPIO_FN(MST1_TS_XX2), + GPIO_FN(MST1_TS_XX3), + GPIO_FN(MST1_TS_XX4), + GPIO_FN(MST1_TS_XX5), + GPIO_FN(MST0_TS_XX1), + GPIO_FN(MST0_TS_XX2), + GPIO_FN(MST0_TS_XX3), + GPIO_FN(MST0_TS_XX4), + GPIO_FN(MST0_TS_XX5), + + /* MSEL3 special cases */ + GPIO_FN(SDHI0_VCCQ_MC0_ON), + GPIO_FN(SDHI0_VCCQ_MC0_OFF), + GPIO_FN(DEBUG_MON_VIO), + GPIO_FN(DEBUG_MON_LCDD), + GPIO_FN(LCDC_LCDC0), + GPIO_FN(LCDC_LCDC1), + + /* MSEL4 special cases */ + GPIO_FN(IRQ9_MEM_INT), + GPIO_FN(IRQ9_MCP_INT), + GPIO_FN(A11), + GPIO_FN(KEYOUT8), + GPIO_FN(TPU4TO3), + GPIO_FN(RESETA_N_PU_ON), + GPIO_FN(RESETA_N_PU_OFF), + GPIO_FN(EDBGREQ_PD), + GPIO_FN(EDBGREQ_PU), + + /* Functions with pull-ups */ + GPIO_FN(KEYIN0_PU), + GPIO_FN(KEYIN1_PU), + GPIO_FN(KEYIN2_PU), + GPIO_FN(KEYIN3_PU), + GPIO_FN(KEYIN4_PU), + GPIO_FN(KEYIN5_PU), + GPIO_FN(KEYIN6_PU), + GPIO_FN(KEYIN7_PU), + GPIO_FN(SDHICD0_PU), + GPIO_FN(SDHID0_0_PU), + GPIO_FN(SDHID0_1_PU), + GPIO_FN(SDHID0_2_PU), + GPIO_FN(SDHID0_3_PU), + GPIO_FN(SDHICMD0_PU), + GPIO_FN(SDHIWP0_PU), + GPIO_FN(SDHID1_0_PU), + GPIO_FN(SDHID1_1_PU), + GPIO_FN(SDHID1_2_PU), + GPIO_FN(SDHID1_3_PU), + GPIO_FN(SDHICMD1_PU), + GPIO_FN(SDHID2_0_PU), + GPIO_FN(SDHID2_1_PU), + GPIO_FN(SDHID2_2_PU), + GPIO_FN(SDHID2_3_PU), + GPIO_FN(SDHICMD2_PU), + GPIO_FN(MMCCMD0_PU), + GPIO_FN(MMCCMD1_PU), + GPIO_FN(MMCD0_0_PU), + GPIO_FN(MMCD0_1_PU), + GPIO_FN(MMCD0_2_PU), + GPIO_FN(MMCD0_3_PU), + GPIO_FN(MMCD0_4_PU), + GPIO_FN(MMCD0_5_PU), + GPIO_FN(MMCD0_6_PU), + GPIO_FN(MMCD0_7_PU), + GPIO_FN(FSIACK_PU), + GPIO_FN(FSIAILR_PU), + GPIO_FN(FSIAIBT_PU), + GPIO_FN(FSIAISLD_PU), +}; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + PORTCR(0, 0xe6050000), /* PORT0CR */ + PORTCR(1, 0xe6050001), /* PORT1CR */ + PORTCR(2, 0xe6050002), /* PORT2CR */ + PORTCR(3, 0xe6050003), /* PORT3CR */ + PORTCR(4, 0xe6050004), /* PORT4CR */ + PORTCR(5, 0xe6050005), /* PORT5CR */ + PORTCR(6, 0xe6050006), /* PORT6CR */ + PORTCR(7, 0xe6050007), /* PORT7CR */ + PORTCR(8, 0xe6050008), /* PORT8CR */ + PORTCR(9, 0xe6050009), /* PORT9CR */ + + PORTCR(10, 0xe605000a), /* PORT10CR */ + PORTCR(11, 0xe605000b), /* PORT11CR */ + PORTCR(12, 0xe605000c), /* PORT12CR */ + PORTCR(13, 0xe605000d), /* PORT13CR */ + PORTCR(14, 0xe605000e), /* PORT14CR */ + PORTCR(15, 0xe605000f), /* PORT15CR */ + PORTCR(16, 0xe6050010), /* PORT16CR */ + PORTCR(17, 0xe6050011), /* PORT17CR */ + PORTCR(18, 0xe6050012), /* PORT18CR */ + PORTCR(19, 0xe6050013), /* PORT19CR */ + + PORTCR(20, 0xe6050014), /* PORT20CR */ + PORTCR(21, 0xe6050015), /* PORT21CR */ + PORTCR(22, 0xe6050016), /* PORT22CR */ + PORTCR(23, 0xe6050017), /* PORT23CR */ + PORTCR(24, 0xe6050018), /* PORT24CR */ + PORTCR(25, 0xe6050019), /* PORT25CR */ + PORTCR(26, 0xe605001a), /* PORT26CR */ + PORTCR(27, 0xe605001b), /* PORT27CR */ + PORTCR(28, 0xe605001c), /* PORT28CR */ + PORTCR(29, 0xe605001d), /* PORT29CR */ + + PORTCR(30, 0xe605001e), /* PORT30CR */ + PORTCR(31, 0xe605001f), /* PORT31CR */ + PORTCR(32, 0xe6051020), /* PORT32CR */ + PORTCR(33, 0xe6051021), /* PORT33CR */ + PORTCR(34, 0xe6051022), /* PORT34CR */ + PORTCR(35, 0xe6051023), /* PORT35CR */ + PORTCR(36, 0xe6051024), /* PORT36CR */ + PORTCR(37, 0xe6051025), /* PORT37CR */ + PORTCR(38, 0xe6051026), /* PORT38CR */ + PORTCR(39, 0xe6051027), /* PORT39CR */ + + PORTCR(40, 0xe6051028), /* PORT40CR */ + PORTCR(41, 0xe6051029), /* PORT41CR */ + PORTCR(42, 0xe605102a), /* PORT42CR */ + PORTCR(43, 0xe605102b), /* PORT43CR */ + PORTCR(44, 0xe605102c), /* PORT44CR */ + PORTCR(45, 0xe605102d), /* PORT45CR */ + PORTCR(46, 0xe605102e), /* PORT46CR */ + PORTCR(47, 0xe605102f), /* PORT47CR */ + PORTCR(48, 0xe6051030), /* PORT48CR */ + PORTCR(49, 0xe6051031), /* PORT49CR */ + + PORTCR(50, 0xe6051032), /* PORT50CR */ + PORTCR(51, 0xe6051033), /* PORT51CR */ + PORTCR(52, 0xe6051034), /* PORT52CR */ + PORTCR(53, 0xe6051035), /* PORT53CR */ + PORTCR(54, 0xe6051036), /* PORT54CR */ + PORTCR(55, 0xe6051037), /* PORT55CR */ + PORTCR(56, 0xe6051038), /* PORT56CR */ + PORTCR(57, 0xe6051039), /* PORT57CR */ + PORTCR(58, 0xe605103a), /* PORT58CR */ + PORTCR(59, 0xe605103b), /* PORT59CR */ + + PORTCR(60, 0xe605103c), /* PORT60CR */ + PORTCR(61, 0xe605103d), /* PORT61CR */ + PORTCR(62, 0xe605103e), /* PORT62CR */ + PORTCR(63, 0xe605103f), /* PORT63CR */ + PORTCR(64, 0xe6051040), /* PORT64CR */ + PORTCR(65, 0xe6051041), /* PORT65CR */ + PORTCR(66, 0xe6051042), /* PORT66CR */ + PORTCR(67, 0xe6051043), /* PORT67CR */ + PORTCR(68, 0xe6051044), /* PORT68CR */ + PORTCR(69, 0xe6051045), /* PORT69CR */ + + PORTCR(70, 0xe6051046), /* PORT70CR */ + PORTCR(71, 0xe6051047), /* PORT71CR */ + PORTCR(72, 0xe6051048), /* PORT72CR */ + PORTCR(73, 0xe6051049), /* PORT73CR */ + PORTCR(74, 0xe605104a), /* PORT74CR */ + PORTCR(75, 0xe605104b), /* PORT75CR */ + PORTCR(76, 0xe605104c), /* PORT76CR */ + PORTCR(77, 0xe605104d), /* PORT77CR */ + PORTCR(78, 0xe605104e), /* PORT78CR */ + PORTCR(79, 0xe605104f), /* PORT79CR */ + + PORTCR(80, 0xe6051050), /* PORT80CR */ + PORTCR(81, 0xe6051051), /* PORT81CR */ + PORTCR(82, 0xe6051052), /* PORT82CR */ + PORTCR(83, 0xe6051053), /* PORT83CR */ + PORTCR(84, 0xe6051054), /* PORT84CR */ + PORTCR(85, 0xe6051055), /* PORT85CR */ + PORTCR(86, 0xe6051056), /* PORT86CR */ + PORTCR(87, 0xe6051057), /* PORT87CR */ + PORTCR(88, 0xe6051058), /* PORT88CR */ + PORTCR(89, 0xe6051059), /* PORT89CR */ + + PORTCR(90, 0xe605105a), /* PORT90CR */ + PORTCR(91, 0xe605105b), /* PORT91CR */ + PORTCR(92, 0xe605105c), /* PORT92CR */ + PORTCR(93, 0xe605105d), /* PORT93CR */ + PORTCR(94, 0xe605105e), /* PORT94CR */ + PORTCR(95, 0xe605105f), /* PORT95CR */ + PORTCR(96, 0xe6052060), /* PORT96CR */ + PORTCR(97, 0xe6052061), /* PORT97CR */ + PORTCR(98, 0xe6052062), /* PORT98CR */ + PORTCR(99, 0xe6052063), /* PORT99CR */ + + PORTCR(100, 0xe6052064), /* PORT100CR */ + PORTCR(101, 0xe6052065), /* PORT101CR */ + PORTCR(102, 0xe6052066), /* PORT102CR */ + PORTCR(103, 0xe6052067), /* PORT103CR */ + PORTCR(104, 0xe6052068), /* PORT104CR */ + PORTCR(105, 0xe6052069), /* PORT105CR */ + PORTCR(106, 0xe605206a), /* PORT106CR */ + PORTCR(107, 0xe605206b), /* PORT107CR */ + PORTCR(108, 0xe605206c), /* PORT108CR */ + PORTCR(109, 0xe605206d), /* PORT109CR */ + + PORTCR(110, 0xe605206e), /* PORT110CR */ + PORTCR(111, 0xe605206f), /* PORT111CR */ + PORTCR(112, 0xe6052070), /* PORT112CR */ + PORTCR(113, 0xe6052071), /* PORT113CR */ + PORTCR(114, 0xe6052072), /* PORT114CR */ + PORTCR(115, 0xe6052073), /* PORT115CR */ + PORTCR(116, 0xe6052074), /* PORT116CR */ + PORTCR(117, 0xe6052075), /* PORT117CR */ + PORTCR(118, 0xe6052076), /* PORT118CR */ + + PORTCR(128, 0xe6052080), /* PORT128CR */ + PORTCR(129, 0xe6052081), /* PORT129CR */ + + PORTCR(130, 0xe6052082), /* PORT130CR */ + PORTCR(131, 0xe6052083), /* PORT131CR */ + PORTCR(132, 0xe6052084), /* PORT132CR */ + PORTCR(133, 0xe6052085), /* PORT133CR */ + PORTCR(134, 0xe6052086), /* PORT134CR */ + PORTCR(135, 0xe6052087), /* PORT135CR */ + PORTCR(136, 0xe6052088), /* PORT136CR */ + PORTCR(137, 0xe6052089), /* PORT137CR */ + PORTCR(138, 0xe605208a), /* PORT138CR */ + PORTCR(139, 0xe605208b), /* PORT139CR */ + + PORTCR(140, 0xe605208c), /* PORT140CR */ + PORTCR(141, 0xe605208d), /* PORT141CR */ + PORTCR(142, 0xe605208e), /* PORT142CR */ + PORTCR(143, 0xe605208f), /* PORT143CR */ + PORTCR(144, 0xe6052090), /* PORT144CR */ + PORTCR(145, 0xe6052091), /* PORT145CR */ + PORTCR(146, 0xe6052092), /* PORT146CR */ + PORTCR(147, 0xe6052093), /* PORT147CR */ + PORTCR(148, 0xe6052094), /* PORT148CR */ + PORTCR(149, 0xe6052095), /* PORT149CR */ + + PORTCR(150, 0xe6052096), /* PORT150CR */ + PORTCR(151, 0xe6052097), /* PORT151CR */ + PORTCR(152, 0xe6052098), /* PORT152CR */ + PORTCR(153, 0xe6052099), /* PORT153CR */ + PORTCR(154, 0xe605209a), /* PORT154CR */ + PORTCR(155, 0xe605209b), /* PORT155CR */ + PORTCR(156, 0xe605209c), /* PORT156CR */ + PORTCR(157, 0xe605209d), /* PORT157CR */ + PORTCR(158, 0xe605209e), /* PORT158CR */ + PORTCR(159, 0xe605209f), /* PORT159CR */ + + PORTCR(160, 0xe60520a0), /* PORT160CR */ + PORTCR(161, 0xe60520a1), /* PORT161CR */ + PORTCR(162, 0xe60520a2), /* PORT162CR */ + PORTCR(163, 0xe60520a3), /* PORT163CR */ + PORTCR(164, 0xe60520a4), /* PORT164CR */ + + PORTCR(192, 0xe60520c0), /* PORT192CR */ + PORTCR(193, 0xe60520c1), /* PORT193CR */ + PORTCR(194, 0xe60520c2), /* PORT194CR */ + PORTCR(195, 0xe60520c3), /* PORT195CR */ + PORTCR(196, 0xe60520c4), /* PORT196CR */ + PORTCR(197, 0xe60520c5), /* PORT197CR */ + PORTCR(198, 0xe60520c6), /* PORT198CR */ + PORTCR(199, 0xe60520c7), /* PORT199CR */ + + PORTCR(200, 0xe60520c8), /* PORT200CR */ + PORTCR(201, 0xe60520c9), /* PORT201CR */ + PORTCR(202, 0xe60520ca), /* PORT202CR */ + PORTCR(203, 0xe60520cb), /* PORT203CR */ + PORTCR(204, 0xe60520cc), /* PORT204CR */ + PORTCR(205, 0xe60520cd), /* PORT205CR */ + PORTCR(206, 0xe60520ce), /* PORT206CR */ + PORTCR(207, 0xe60520cf), /* PORT207CR */ + PORTCR(208, 0xe60520d0), /* PORT208CR */ + PORTCR(209, 0xe60520d1), /* PORT209CR */ + + PORTCR(210, 0xe60520d2), /* PORT210CR */ + PORTCR(211, 0xe60520d3), /* PORT211CR */ + PORTCR(212, 0xe60520d4), /* PORT212CR */ + PORTCR(213, 0xe60520d5), /* PORT213CR */ + PORTCR(214, 0xe60520d6), /* PORT214CR */ + PORTCR(215, 0xe60520d7), /* PORT215CR */ + PORTCR(216, 0xe60520d8), /* PORT216CR */ + PORTCR(217, 0xe60520d9), /* PORT217CR */ + PORTCR(218, 0xe60520da), /* PORT218CR */ + PORTCR(219, 0xe60520db), /* PORT219CR */ + + PORTCR(220, 0xe60520dc), /* PORT220CR */ + PORTCR(221, 0xe60520dd), /* PORT221CR */ + PORTCR(222, 0xe60520de), /* PORT222CR */ + PORTCR(223, 0xe60520df), /* PORT223CR */ + PORTCR(224, 0xe60530e0), /* PORT224CR */ + PORTCR(225, 0xe60530e1), /* PORT225CR */ + PORTCR(226, 0xe60530e2), /* PORT226CR */ + PORTCR(227, 0xe60530e3), /* PORT227CR */ + PORTCR(228, 0xe60530e4), /* PORT228CR */ + PORTCR(229, 0xe60530e5), /* PORT229CR */ + + PORTCR(230, 0xe60530e6), /* PORT230CR */ + PORTCR(231, 0xe60530e7), /* PORT231CR */ + PORTCR(232, 0xe60530e8), /* PORT232CR */ + PORTCR(233, 0xe60530e9), /* PORT233CR */ + PORTCR(234, 0xe60530ea), /* PORT234CR */ + PORTCR(235, 0xe60530eb), /* PORT235CR */ + PORTCR(236, 0xe60530ec), /* PORT236CR */ + PORTCR(237, 0xe60530ed), /* PORT237CR */ + PORTCR(238, 0xe60530ee), /* PORT238CR */ + PORTCR(239, 0xe60530ef), /* PORT239CR */ + + PORTCR(240, 0xe60530f0), /* PORT240CR */ + PORTCR(241, 0xe60530f1), /* PORT241CR */ + PORTCR(242, 0xe60530f2), /* PORT242CR */ + PORTCR(243, 0xe60530f3), /* PORT243CR */ + PORTCR(244, 0xe60530f4), /* PORT244CR */ + PORTCR(245, 0xe60530f5), /* PORT245CR */ + PORTCR(246, 0xe60530f6), /* PORT246CR */ + PORTCR(247, 0xe60530f7), /* PORT247CR */ + PORTCR(248, 0xe60530f8), /* PORT248CR */ + PORTCR(249, 0xe60530f9), /* PORT249CR */ + + PORTCR(250, 0xe60530fa), /* PORT250CR */ + PORTCR(251, 0xe60530fb), /* PORT251CR */ + PORTCR(252, 0xe60530fc), /* PORT252CR */ + PORTCR(253, 0xe60530fd), /* PORT253CR */ + PORTCR(254, 0xe60530fe), /* PORT254CR */ + PORTCR(255, 0xe60530ff), /* PORT255CR */ + PORTCR(256, 0xe6053100), /* PORT256CR */ + PORTCR(257, 0xe6053101), /* PORT257CR */ + PORTCR(258, 0xe6053102), /* PORT258CR */ + PORTCR(259, 0xe6053103), /* PORT259CR */ + + PORTCR(260, 0xe6053104), /* PORT260CR */ + PORTCR(261, 0xe6053105), /* PORT261CR */ + PORTCR(262, 0xe6053106), /* PORT262CR */ + PORTCR(263, 0xe6053107), /* PORT263CR */ + PORTCR(264, 0xe6053108), /* PORT264CR */ + PORTCR(265, 0xe6053109), /* PORT265CR */ + PORTCR(266, 0xe605310a), /* PORT266CR */ + PORTCR(267, 0xe605310b), /* PORT267CR */ + PORTCR(268, 0xe605310c), /* PORT268CR */ + PORTCR(269, 0xe605310d), /* PORT269CR */ + + PORTCR(270, 0xe605310e), /* PORT270CR */ + PORTCR(271, 0xe605310f), /* PORT271CR */ + PORTCR(272, 0xe6053110), /* PORT272CR */ + PORTCR(273, 0xe6053111), /* PORT273CR */ + PORTCR(274, 0xe6053112), /* PORT274CR */ + PORTCR(275, 0xe6053113), /* PORT275CR */ + PORTCR(276, 0xe6053114), /* PORT276CR */ + PORTCR(277, 0xe6053115), /* PORT277CR */ + PORTCR(278, 0xe6053116), /* PORT278CR */ + PORTCR(279, 0xe6053117), /* PORT279CR */ + + PORTCR(280, 0xe6053118), /* PORT280CR */ + PORTCR(281, 0xe6053119), /* PORT281CR */ + PORTCR(282, 0xe605311a), /* PORT282CR */ + + PORTCR(288, 0xe6052120), /* PORT288CR */ + PORTCR(289, 0xe6052121), /* PORT289CR */ + + PORTCR(290, 0xe6052122), /* PORT290CR */ + PORTCR(291, 0xe6052123), /* PORT291CR */ + PORTCR(292, 0xe6052124), /* PORT292CR */ + PORTCR(293, 0xe6052125), /* PORT293CR */ + PORTCR(294, 0xe6052126), /* PORT294CR */ + PORTCR(295, 0xe6052127), /* PORT295CR */ + PORTCR(296, 0xe6052128), /* PORT296CR */ + PORTCR(297, 0xe6052129), /* PORT297CR */ + PORTCR(298, 0xe605212a), /* PORT298CR */ + PORTCR(299, 0xe605212b), /* PORT299CR */ + + PORTCR(300, 0xe605212c), /* PORT300CR */ + PORTCR(301, 0xe605212d), /* PORT301CR */ + PORTCR(302, 0xe605212e), /* PORT302CR */ + PORTCR(303, 0xe605212f), /* PORT303CR */ + PORTCR(304, 0xe6052130), /* PORT304CR */ + PORTCR(305, 0xe6052131), /* PORT305CR */ + PORTCR(306, 0xe6052132), /* PORT306CR */ + PORTCR(307, 0xe6052133), /* PORT307CR */ + PORTCR(308, 0xe6052134), /* PORT308CR */ + PORTCR(309, 0xe6052135), /* PORT309CR */ + + { PINMUX_CFG_REG("MSEL2CR", 0xe605801c, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1, + MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1, + MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1, + MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1, + 0, 0, + MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1, + MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1, + MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1, + MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1, + MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1, + MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1, + MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1, + MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1, + MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1, + MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1, + MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1, + MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1, + MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1, + MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1, + MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1, + } + }, + { PINMUX_CFG_REG("MSEL3CR", 0xe6058020, 32, 1) { + 0, 0, + 0, 0, + 0, 0, + MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_1, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1, + 0, 0, + 0, 0, + 0, 0, + MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1, + 0, 0, + MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1, + 0, 0, + 0, 0, + MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1, + 0, 0, + 0, 0, + 0, 0, + MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1, + 0, 0, + 0, 0, + } + }, + { PINMUX_CFG_REG("MSEL4CR", 0xe6058024, 32, 1) { + 0, 0, + 0, 0, + MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1, + 0, 0, + MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1, + MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1, + 0, 0, + 0, 0, + 0, 0, + MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1, + MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1, + MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1, + MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1, + 0, 0, + 0, 0, + 0, 0, + MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1, + 0, 0, + MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1, + MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1, + MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1, + MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1, + MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1, + MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1, + MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1, + 0, 0, + 0, 0, + MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1, + 0, 0, + 0, 0, + MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1, + 0, 0, + } + }, + { }, +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) { + PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA, + PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA, + PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA, + PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA, + PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA, + PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA, + PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA, + PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA } + }, + { PINMUX_DATA_REG("PORTD063_032DR", 0xe6055000, 32) { + PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA, + PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA, + PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA, + PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA, + PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA, + PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA, + PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA, + PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA } + }, + { PINMUX_DATA_REG("PORTD095_064DR", 0xe6055004, 32) { + PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA, + PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA, + PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA, + PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA, + PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA, + PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA, + PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA, + PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA } + }, + { PINMUX_DATA_REG("PORTR127_096DR", 0xe6056000, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, PORT118_DATA, PORT117_DATA, PORT116_DATA, + PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA, + PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA, + PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA, + PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA, + PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA } + }, + { PINMUX_DATA_REG("PORTR159_128DR", 0xe6056004, 32) { + PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA, + PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA, + PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA, + PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA, + PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA, + PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA, + PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA, + PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA } + }, + { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056008, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, PORT164_DATA, + PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA } + }, + { PINMUX_DATA_REG("PORTR223_192DR", 0xe605600C, 32) { + PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA, + PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA, + PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA, + PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA, + PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA, + PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA, + PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA, + PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA } + }, + { PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) { + PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA, + PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA, + PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA, + PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA, + PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA, + PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA, + PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA, + PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA } + }, + { PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) { + 0, 0, 0, 0, + 0, PORT282_DATA, PORT281_DATA, PORT280_DATA, + PORT279_DATA, PORT278_DATA, PORT277_DATA, PORT276_DATA, + PORT275_DATA, PORT274_DATA, PORT273_DATA, PORT272_DATA, + PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA, + PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA, + PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA, + PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA } + }, + { PINMUX_DATA_REG("PORTR319_288DR", 0xe6056010, 32) { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, PORT309_DATA, PORT308_DATA, + PORT307_DATA, PORT306_DATA, PORT305_DATA, PORT304_DATA, + PORT303_DATA, PORT302_DATA, PORT301_DATA, PORT300_DATA, + PORT299_DATA, PORT298_DATA, PORT297_DATA, PORT296_DATA, + PORT295_DATA, PORT294_DATA, PORT293_DATA, PORT292_DATA, + PORT291_DATA, PORT290_DATA, PORT289_DATA, PORT288_DATA } + }, + { }, +}; + +#if 0 +/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */ +#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5)) +#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5)) +#else +#define EXT_IRQ16L(n) (n) +#define EXT_IRQ16H(n) (n) +#endif + +static struct pinmux_irq pinmux_irqs[] = { + PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0), + PINMUX_IRQ(EXT_IRQ16L(1), PORT10_FN0), + PINMUX_IRQ(EXT_IRQ16L(0), PORT11_FN0), + PINMUX_IRQ(EXT_IRQ16H(18), PORT13_FN0), + PINMUX_IRQ(EXT_IRQ16H(20), PORT14_FN0), + PINMUX_IRQ(EXT_IRQ16H(21), PORT15_FN0), + PINMUX_IRQ(EXT_IRQ16H(31), PORT26_FN0), + PINMUX_IRQ(EXT_IRQ16H(30), PORT27_FN0), + PINMUX_IRQ(EXT_IRQ16H(29), PORT28_FN0), + PINMUX_IRQ(EXT_IRQ16H(22), PORT40_FN0), + PINMUX_IRQ(EXT_IRQ16H(23), PORT53_FN0), + PINMUX_IRQ(EXT_IRQ16L(10), PORT54_FN0), + PINMUX_IRQ(EXT_IRQ16L(9), PORT56_FN0), + PINMUX_IRQ(EXT_IRQ16H(26), PORT115_FN0), + PINMUX_IRQ(EXT_IRQ16H(27), PORT116_FN0), + PINMUX_IRQ(EXT_IRQ16H(28), PORT117_FN0), + PINMUX_IRQ(EXT_IRQ16H(24), PORT118_FN0), + PINMUX_IRQ(EXT_IRQ16L(6), PORT147_FN0), + PINMUX_IRQ(EXT_IRQ16L(2), PORT149_FN0), + PINMUX_IRQ(EXT_IRQ16L(7), PORT150_FN0), + PINMUX_IRQ(EXT_IRQ16L(12), PORT156_FN0), + PINMUX_IRQ(EXT_IRQ16L(4), PORT159_FN0), + PINMUX_IRQ(EXT_IRQ16H(25), PORT164_FN0), + PINMUX_IRQ(EXT_IRQ16L(8), PORT223_FN0), + PINMUX_IRQ(EXT_IRQ16L(3), PORT224_FN0), + PINMUX_IRQ(EXT_IRQ16L(5), PORT227_FN0), + PINMUX_IRQ(EXT_IRQ16H(17), PORT234_FN0), + PINMUX_IRQ(EXT_IRQ16L(11), PORT238_FN0), + PINMUX_IRQ(EXT_IRQ16L(13), PORT239_FN0), + PINMUX_IRQ(EXT_IRQ16H(16), PORT249_FN0), + PINMUX_IRQ(EXT_IRQ16L(14), PORT251_FN0), + PINMUX_IRQ(EXT_IRQ16L(9), PORT308_FN0), +}; + +static struct pinmux_info sh73a0_pinmux_info = { + .name = "sh73a0_pfc", + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, + .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_PORT0, + .last_gpio = GPIO_FN_FSIAISLD_PU, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), + + .gpio_irq = pinmux_irqs, + .gpio_irq_size = ARRAY_SIZE(pinmux_irqs), +}; + +void sh73a0_pinmux_init(void) +{ + register_pinmux(&sh73a0_pinmux_info); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/rmobile/timer.c b/u-boot-imx/arch/arm/cpu/armv7/rmobile/timer.c new file mode 100644 index 0000000..04700e7 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/rmobile/timer.c
@@ -0,0 +1,85 @@ +/* + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/arch-armv7/globaltimer.h> +#include <asm/arch/rmobile.h> + +static struct globaltimer *global_timer = \ + (struct globaltimer *)GLOBAL_TIMER_BASE_ADDR; + +#define CLK2MHZ(clk) (clk / 1000 / 1000) +static u64 get_cpu_global_timer(void) +{ + u32 low, high; + u64 timer; + + u32 old = readl(&global_timer->cnt_h); + while (1) { + low = readl(&global_timer->cnt_l); + high = readl(&global_timer->cnt_h); + if (old == high) + break; + else + old = high; + } + + timer = high; + return (u64)((timer << 32) | low); +} + +static u64 get_time_us(void) +{ + u64 timer = get_cpu_global_timer(); + + timer = ((timer << 2) + (CLK2MHZ(CONFIG_SYS_CPU_CLK) >> 1)); + do_div(timer, CLK2MHZ(CONFIG_SYS_CPU_CLK)); + return timer; +} + +static ulong get_time_ms(void) +{ + u64 us = get_time_us(); + + do_div(us, 1000); + return us; +} + +int timer_init(void) +{ + writel(0x01, &global_timer->ctl); + return 0; +} + +void __udelay(unsigned long usec) +{ + u64 start, current; + u64 wait; + + start = get_cpu_global_timer(); + wait = (u64)((usec * CLK2MHZ(CONFIG_SYS_CPU_CLK)) >> 2); + do { + current = get_cpu_global_timer(); + } while ((current - start) < wait); +} + +ulong get_timer(ulong base) +{ + return get_time_ms() - base; +} + +unsigned long long get_ticks(void) +{ + return get_cpu_global_timer(); +} + +ulong get_tbclk(void) +{ + return (ulong)(CONFIG_SYS_CPU_CLK >> 2); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5p-common/Makefile b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/Makefile new file mode 100644 index 0000000..f571d8a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/Makefile
@@ -0,0 +1,13 @@ +# +# Copyright (C) 2009 Samsung Electronics +# Minkyu Kang <mk7.kang@samsung.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu_info.o +ifndef CONFIG_SPL_BUILD +obj-y += timer.o +obj-y += sromc.o +obj-$(CONFIG_PWM) += pwm.o +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5p-common/cpu_info.c b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/cpu_info.c new file mode 100644 index 0000000..a8d91e7 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/cpu_info.c
@@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang <mk7.kang@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> + +/* Default is s5pc100 */ +unsigned int s5p_cpu_id = 0xC100; +/* Default is EVT1 */ +unsigned int s5p_cpu_rev = 1; + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + s5p_set_cpu_id(); + + return 0; +} +#endif + +u32 get_device_type(void) +{ + return s5p_cpu_id; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU:\t%s%X@%sMHz\n", + s5p_get_cpu_name(), s5p_cpu_id, + strmhz(buf, get_arm_clk())); + + return 0; +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5p-common/pwm.c b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/pwm.c new file mode 100644 index 0000000..b8805c8 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/pwm.c
@@ -0,0 +1,171 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * Donghwa Lee <dh09.lee@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <pwm.h> +#include <asm/io.h> +#include <asm/arch/pwm.h> +#include <asm/arch/clk.h> + +int pwm_enable(int pwm_id) +{ + const struct s5p_timer *pwm = + (struct s5p_timer *)samsung_get_base_timer(); + unsigned long tcon; + + tcon = readl(&pwm->tcon); + tcon |= TCON_START(pwm_id); + + writel(tcon, &pwm->tcon); + + return 0; +} + +void pwm_disable(int pwm_id) +{ + const struct s5p_timer *pwm = + (struct s5p_timer *)samsung_get_base_timer(); + unsigned long tcon; + + tcon = readl(&pwm->tcon); + tcon &= ~TCON_START(pwm_id); + + writel(tcon, &pwm->tcon); +} + +static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq) +{ + unsigned long tin_parent_rate; + unsigned int div; + + tin_parent_rate = get_pwm_clk(); + + for (div = 2; div <= 16; div *= 2) { + if ((tin_parent_rate / (div << 16)) < freq) + return tin_parent_rate / div; + } + + return tin_parent_rate / 16; +} + +#define NS_IN_SEC 1000000000UL + +int pwm_config(int pwm_id, int duty_ns, int period_ns) +{ + const struct s5p_timer *pwm = + (struct s5p_timer *)samsung_get_base_timer(); + unsigned int offset; + unsigned long tin_rate; + unsigned long tin_ns; + unsigned long frequency; + unsigned long tcon; + unsigned long tcnt; + unsigned long tcmp; + + /* + * We currently avoid using 64bit arithmetic by using the + * fact that anything faster than 1GHz is easily representable + * by 32bits. + */ + if (period_ns > NS_IN_SEC || duty_ns > NS_IN_SEC || period_ns == 0) + return -ERANGE; + + if (duty_ns > period_ns) + return -EINVAL; + + frequency = NS_IN_SEC / period_ns; + + /* Check to see if we are changing the clock rate of the PWM */ + tin_rate = pwm_calc_tin(pwm_id, frequency); + + tin_ns = NS_IN_SEC / tin_rate; + tcnt = period_ns / tin_ns; + + /* Note, counters count down */ + tcmp = duty_ns / tin_ns; + tcmp = tcnt - tcmp; + + /* Update the PWM register block. */ + offset = pwm_id * 3; + if (pwm_id < 4) { + writel(tcnt, &pwm->tcntb0 + offset); + writel(tcmp, &pwm->tcmpb0 + offset); + } + + tcon = readl(&pwm->tcon); + tcon |= TCON_UPDATE(pwm_id); + if (pwm_id < 4) + tcon |= TCON_AUTO_RELOAD(pwm_id); + else + tcon |= TCON4_AUTO_RELOAD; + writel(tcon, &pwm->tcon); + + tcon &= ~TCON_UPDATE(pwm_id); + writel(tcon, &pwm->tcon); + + return 0; +} + +int pwm_init(int pwm_id, int div, int invert) +{ + u32 val; + const struct s5p_timer *pwm = + (struct s5p_timer *)samsung_get_base_timer(); + unsigned long ticks_per_period; + unsigned int offset, prescaler; + + /* + * Timer Freq(HZ) = + * PWM_CLK / { (prescaler_value + 1) * (divider_value) } + */ + + val = readl(&pwm->tcfg0); + if (pwm_id < 2) { + prescaler = PRESCALER_0; + val &= ~0xff; + val |= (prescaler & 0xff); + } else { + prescaler = PRESCALER_1; + val &= ~(0xff << 8); + val |= (prescaler & 0xff) << 8; + } + writel(val, &pwm->tcfg0); + val = readl(&pwm->tcfg1); + val &= ~(0xf << MUX_DIV_SHIFT(pwm_id)); + val |= (div & 0xf) << MUX_DIV_SHIFT(pwm_id); + writel(val, &pwm->tcfg1); + + if (pwm_id == 4) { + /* + * TODO(sjg): Use this as a countdown timer for now. We count + * down from the maximum value to 0, then reset. + */ + ticks_per_period = -1UL; + } else { + const unsigned long pwm_hz = 1000; + unsigned long timer_rate_hz = get_pwm_clk() / + ((prescaler + 1) * (1 << div)); + + ticks_per_period = timer_rate_hz / pwm_hz; + } + + /* set count value */ + offset = pwm_id * 3; + + writel(ticks_per_period, &pwm->tcntb0 + offset); + + val = readl(&pwm->tcon) & ~(0xf << TCON_OFFSET(pwm_id)); + if (invert && (pwm_id < 4)) + val |= TCON_INVERTER(pwm_id); + writel(val, &pwm->tcon); + + pwm_enable(pwm_id); + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5p-common/sromc.c b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/sromc.c new file mode 100644 index 0000000..806456f --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/sromc.c
@@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 Samsung Electronics + * Naveen Krishna Ch <ch.naveen@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sromc.h> + +/* + * s5p_config_sromc() - select the proper SROMC Bank and configure the + * band width control and bank control registers + * srom_bank - SROM + * srom_bw_conf - SMC Band witdh reg configuration value + * srom_bc_conf - SMC Bank Control reg configuration value + */ +void s5p_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf) +{ + u32 tmp; + struct s5p_sromc *srom = + (struct s5p_sromc *)samsung_get_base_sromc(); + + /* Configure SMC_BW register to handle proper SROMC bank */ + tmp = srom->bw; + tmp &= ~(0xF << (srom_bank * 4)); + tmp |= srom_bw_conf; + srom->bw = tmp; + + /* Configure SMC_BC register */ + srom->bc[srom_bank] = srom_bc_conf; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5p-common/timer.c b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/timer.c new file mode 100644 index 0000000..949abb1 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -0,0 +1,132 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Heungjun Kim <riverful.kim@samsung.com> + * Inki Dae <inki.dae@samsung.com> + * Minkyu Kang <mk7.kang@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/arch/pwm.h> +#include <asm/arch/clk.h> +#include <pwm.h> + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long get_current_tick(void); + +/* macro to read the 16 bit timer */ +static inline struct s5p_timer *s5p_get_base_timer(void) +{ + return (struct s5p_timer *)samsung_get_base_timer(); +} + +/** + * Read the countdown timer. + * + * This operates at 1MHz and counts downwards. It will wrap about every + * hour (2^32 microseconds). + * + * @return current value of timer + */ +static unsigned long timer_get_us_down(void) +{ + struct s5p_timer *const timer = s5p_get_base_timer(); + + return readl(&timer->tcnto4); +} + +int timer_init(void) +{ + /* PWM Timer 4 */ + pwm_init(4, MUX_DIV_4, 0); + pwm_config(4, 100000, 100000); + pwm_enable(4); + + /* Use this as the current monotonic time in us */ + gd->arch.timer_reset_value = 0; + + /* Use this as the last timer value we saw */ + gd->arch.lastinc = timer_get_us_down(); + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ +unsigned long get_timer(unsigned long base) +{ + unsigned long long time_ms; + + ulong now = timer_get_us_down(); + + /* + * Increment the time by the amount elapsed since the last read. + * The timer may have wrapped around, but it makes no difference to + * our arithmetic here. + */ + gd->arch.timer_reset_value += gd->arch.lastinc - now; + gd->arch.lastinc = now; + + /* Divide by 1000 to convert from us to ms */ + time_ms = gd->arch.timer_reset_value; + do_div(time_ms, 1000); + return time_ms - base; +} + +unsigned long __attribute__((no_instrument_function)) timer_get_us(void) +{ + static unsigned long base_time_us; + + struct s5p_timer *const timer = + (struct s5p_timer *)samsung_get_base_timer(); + unsigned long now_downward_us = readl(&timer->tcnto4); + + if (!base_time_us) + base_time_us = now_downward_us; + + /* Note that this timer counts downward. */ + return base_time_us - now_downward_us; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + unsigned long count_value; + + count_value = timer_get_us_down(); + while ((int)(count_value - timer_get_us_down()) < (int)usec) + ; +} + +void reset_timer_masked(void) +{ + struct s5p_timer *const timer = s5p_get_base_timer(); + + /* reset time */ + gd->arch.lastinc = readl(&timer->tcnto4); + gd->arch.tbl = 0; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Kconfig b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Kconfig new file mode 100644 index 0000000..bc73813 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Kconfig
@@ -0,0 +1,22 @@ +if ARCH_S5PC1XX + +choice + prompt "S5PC1XX board select" + +config TARGET_S5P_GONI + bool "S5P Goni board" + select OF_CONTROL + +config TARGET_SMDKC100 + bool "Support smdkc100 board" + select OF_CONTROL + +endchoice + +config SYS_SOC + default "s5pc1xx" + +source "board/samsung/goni/Kconfig" +source "board/samsung/smdkc100/Kconfig" + +endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Makefile b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Makefile new file mode 100644 index 0000000..9f43ded --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/Makefile
@@ -0,0 +1,14 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cache.o +obj-y += reset.o + +obj-y += clock.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/cache.c b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/cache.c new file mode 100644 index 0000000..51af299 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/cache.c
@@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Samsung Electronics + * Minkyu Kang <mk7.kang@samsung.com> + * Robert Baldyga <r.baldyga@samsung.com> + * + * based on arch/arm/cpu/armv7/omap3/cache.S + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#ifndef CONFIG_SYS_DCACHE_OFF +void enable_caches(void) +{ + dcache_enable(); +} + +void disable_caches(void) +{ + dcache_disable(); +} +#endif + +#ifndef CONFIG_SYS_L2CACHE_OFF +void v7_outer_cache_enable(void) +{ + __asm( + "push {r0, r1, r2, lr}\n\t" + "mrc 15, 0, r3, cr1, cr0, 1\n\t" + "orr r3, r3, #2\n\t" + "mcr 15, 0, r3, cr1, cr0, 1\n\t" + "pop {r1, r2, r3, pc}" + ); +} + +void v7_outer_cache_disable(void) +{ + __asm( + "push {r0, r1, r2, lr}\n\t" + "mrc 15, 0, r3, cr1, cr0, 1\n\t" + "bic r3, r3, #2\n\t" + "mcr 15, 0, r3, cr1, cr0, 1\n\t" + "pop {r1, r2, r3, pc}" + ); +} +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/clock.c b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/clock.c new file mode 100644 index 0000000..3da0071 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/clock.c
@@ -0,0 +1,327 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang <mk7.kang@samsung.com> + * Heungjun Kim <riverful.kim@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/clk.h> + +#define CLK_M 0 +#define CLK_D 1 +#define CLK_P 2 + +#ifndef CONFIG_SYS_CLK_FREQ_C100 +#define CONFIG_SYS_CLK_FREQ_C100 12000000 +#endif +#ifndef CONFIG_SYS_CLK_FREQ_C110 +#define CONFIG_SYS_CLK_FREQ_C110 24000000 +#endif + +/* s5pc110: return pll clock frequency */ +static unsigned long s5pc100_get_pll_clk(int pllreg) +{ + struct s5pc100_clock *clk = + (struct s5pc100_clock *)samsung_get_base_clock(); + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case HPLL: + r = readl(&clk->hpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [23:16] + * EPLL_CON: MIDV [23:16] + * HPLL_CON: MIDV [23:16] + */ + if (pllreg == APLL) + mask = 0x3ff; + else + mask = 0x0ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + freq = CONFIG_SYS_CLK_FREQ_C100; + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc100: return pll clock frequency */ +static unsigned long s5pc110_get_pll_clk(int pllreg) +{ + struct s5pc110_clock *clk = + (struct s5pc110_clock *)samsung_get_base_clock(); + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case VPLL: + r = readl(&clk->vpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + */ + if (pllreg == APLL || pllreg == MPLL) + mask = 0x3ff; + else + mask = 0x1ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ_C110; + if (pllreg == APLL) { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } else + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc110: return ARM clock frequency */ +static unsigned long s5pc110_get_arm_clk(void) +{ + struct s5pc110_clock *clk = + (struct s5pc110_clock *)samsung_get_base_clock(); + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio; + + div = readl(&clk->div0); + + /* APLL_RATIO: [2:0] */ + apll_ratio = div & 0x7; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll; + + return armclk; +} + +/* s5pc100: return ARM clock frequency */ +static unsigned long s5pc100_get_arm_clk(void) +{ + struct s5pc100_clock *clk = + (struct s5pc100_clock *)samsung_get_base_clock(); + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio, arm_ratio; + + div = readl(&clk->div0); + + /* ARM_RATIO: [6:4] */ + arm_ratio = (div >> 4) & 0x7; + /* APLL_RATIO: [0] */ + apll_ratio = div & 0x1; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll / (arm_ratio + 1); + + return armclk; +} + +/* s5pc100: return HCLKD0 frequency */ +static unsigned long get_hclk(void) +{ + struct s5pc100_clock *clk = + (struct s5pc100_clock *)samsung_get_base_clock(); + unsigned long hclkd0; + uint div, d0_bus_ratio; + + div = readl(&clk->div0); + /* D0_BUS_RATIO: [10:8] */ + d0_bus_ratio = (div >> 8) & 0x7; + + hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); + + return hclkd0; +} + +/* s5pc100: return PCLKD1 frequency */ +static unsigned long get_pclkd1(void) +{ + struct s5pc100_clock *clk = + (struct s5pc100_clock *)samsung_get_base_clock(); + unsigned long d1_bus, pclkd1; + uint div, d1_bus_ratio, pclkd1_ratio; + + div = readl(&clk->div0); + /* D1_BUS_RATIO: [14:12] */ + d1_bus_ratio = (div >> 12) & 0x7; + /* PCLKD1_RATIO: [18:16] */ + pclkd1_ratio = (div >> 16) & 0x7; + + /* ASYNC Mode */ + d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); + pclkd1 = d1_bus / (pclkd1_ratio + 1); + + return pclkd1; +} + +/* s5pc110: return HCLKs frequency */ +static unsigned long get_hclk_sys(int dom) +{ + struct s5pc110_clock *clk = + (struct s5pc110_clock *)samsung_get_base_clock(); + unsigned long hclk; + unsigned int div; + unsigned int offset; + unsigned int hclk_sys_ratio; + + if (dom == CLK_M) + return get_hclk(); + + div = readl(&clk->div0); + + /* + * HCLK_MSYS_RATIO: [10:8] + * HCLK_DSYS_RATIO: [19:16] + * HCLK_PSYS_RATIO: [27:24] + */ + offset = 8 + (dom << 0x3); + + hclk_sys_ratio = (div >> offset) & 0xf; + + hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); + + return hclk; +} + +/* s5pc110: return PCLKs frequency */ +static unsigned long get_pclk_sys(int dom) +{ + struct s5pc110_clock *clk = + (struct s5pc110_clock *)samsung_get_base_clock(); + unsigned long pclk; + unsigned int div; + unsigned int offset; + unsigned int pclk_sys_ratio; + + div = readl(&clk->div0); + + /* + * PCLK_MSYS_RATIO: [14:12] + * PCLK_DSYS_RATIO: [22:20] + * PCLK_PSYS_RATIO: [30:28] + */ + offset = 12 + (dom << 0x3); + + pclk_sys_ratio = (div >> offset) & 0x7; + + pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); + + return pclk; +} + +/* s5pc110: return peripheral clock frequency */ +static unsigned long s5pc110_get_pclk(void) +{ + return get_pclk_sys(CLK_P); +} + +/* s5pc100: return peripheral clock frequency */ +static unsigned long s5pc100_get_pclk(void) +{ + return get_pclkd1(); +} + +/* s5pc1xx: return uart clock frequency */ +static unsigned long s5pc1xx_get_uart_clk(int dev_index) +{ + if (cpu_is_s5pc110()) + return s5pc110_get_pclk(); + else + return s5pc100_get_pclk(); +} + +/* s5pc1xx: return pwm clock frequency */ +static unsigned long s5pc1xx_get_pwm_clk(void) +{ + if (cpu_is_s5pc110()) + return s5pc110_get_pclk(); + else + return s5pc100_get_pclk(); +} + +unsigned long get_pll_clk(int pllreg) +{ + if (cpu_is_s5pc110()) + return s5pc110_get_pll_clk(pllreg); + else + return s5pc100_get_pll_clk(pllreg); +} + +unsigned long get_arm_clk(void) +{ + if (cpu_is_s5pc110()) + return s5pc110_get_arm_clk(); + else + return s5pc100_get_arm_clk(); +} + +unsigned long get_pwm_clk(void) +{ + return s5pc1xx_get_pwm_clk(); +} + +unsigned long get_uart_clk(int dev_index) +{ + return s5pc1xx_get_uart_clk(dev_index); +} + +void set_mmc_clk(int dev_index, unsigned int div) +{ + /* Do NOTHING */ +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/reset.S b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/reset.S new file mode 100644 index 0000000..bd74f2b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/s5pc1xx/reset.S
@@ -0,0 +1,32 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang <mk7.kang@samsung.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/cpu.h> +#include <linux/linkage.h> + +#define S5PC100_SWRESET 0xE0200000 +#define S5PC110_SWRESET 0xE0102000 + +ENTRY(reset_cpu) + ldr r1, =S5PC100_PRO_ID + ldr r2, [r1] + ldr r4, =0x00010000 + and r4, r2, r4 + cmp r4, #0 + bne 110f + /* S5PC100 */ + ldr r1, =S5PC100_SWRESET + ldr r2, =0xC100 + b 200f +110: /* S5PC110 */ + ldr r1, =S5PC110_SWRESET + mov r2, #1 +200: + str r2, [r1] +_loop_forever: + b _loop_forever +ENDPROC(reset_cpu)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/Makefile b/u-boot-imx/arch/arm/cpu/armv7/socfpga/Makefile new file mode 100644 index 0000000..8b6e108 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/Makefile
@@ -0,0 +1,13 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2012 Altera Corporation <www.altera.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := lowlevel_init.o +obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ + fpga_manager.o +obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/clock_manager.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/clock_manager.c new file mode 100644 index 0000000..fa3b93a --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/clock_manager.c
@@ -0,0 +1,560 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_clock_manager *clock_manager_base = + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; + +static void cm_wait_for_lock(uint32_t mask) +{ + register uint32_t inter_val; + uint32_t retry = 0; + do { + inter_val = readl(&clock_manager_base->inter) & mask; + if (inter_val == mask) + retry++; + else + retry = 0; + if (retry >= 10) + break; + } while (1); +} + +/* function to poll in the fsm busy bit */ +static void cm_wait_for_fsm(void) +{ + while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) + ; +} + +/* + * function to write the bypass register which requires a poll of the + * busy bit + */ +static void cm_write_bypass(uint32_t val) +{ + writel(val, &clock_manager_base->bypass); + cm_wait_for_fsm(); +} + +/* function to write the ctrl register which requires a poll of the busy bit */ +static void cm_write_ctrl(uint32_t val) +{ + writel(val, &clock_manager_base->ctrl); + cm_wait_for_fsm(); +} + +/* function to write a clock register that has phase information */ +static void cm_write_with_phase(uint32_t value, + uint32_t reg_address, uint32_t mask) +{ + /* poll until phase is zero */ + while (readl(reg_address) & mask) + ; + + writel(value, reg_address); + + while (readl(reg_address) & mask) + ; +} + +/* + * Setup clocks while making no assumptions about previous state of the clocks. + * + * Start by being paranoid and gate all sw managed clocks + * Put all plls in bypass + * Put all plls VCO registers back to reset value (bandgap power down). + * Put peripheral and main pll src to reset value to avoid glitch. + * Delay 5 us. + * Deassert bandgap power down and set numerator and denominator + * Start 7 us timer. + * set internal dividers + * Wait for 7 us timer. + * Enable plls + * Set external dividers while plls are locking + * Wait for pll lock + * Assert/deassert outreset all. + * Take all pll's out of bypass + * Clear safe mode + * set source main and peripheral clocks + * Ungate clocks + */ + +void cm_basic_init(const cm_config_t *cfg) +{ + uint32_t start, timeout; + + /* Start by being paranoid and gate all sw managed clocks */ + + /* + * We need to disable nandclk + * and then do another apb access before disabling + * gatting off the rest of the periperal clocks. + */ + writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & + readl(&clock_manager_base->per_pll.en), + &clock_manager_base->per_pll.en); + + /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */ + writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK | + CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK | + CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK, + &clock_manager_base->main_pll.en); + + writel(0, &clock_manager_base->sdr_pll.en); + + /* now we can gate off the rest of the peripheral clocks */ + writel(0, &clock_manager_base->per_pll.en); + + /* Put all plls in bypass */ + cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL | + CLKMGR_BYPASS_MAINPLL); + + /* Put all plls VCO registers back to reset value. */ + writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->main_pll.vco); + writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->per_pll.vco); + writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->sdr_pll.vco); + + /* + * The clocks to the flash devices and the L4_MAIN clocks can + * glitch when coming out of safe mode if their source values + * are different from their reset value. So the trick it to + * put them back to their reset state, and change input + * after exiting safe mode but before ungating the clocks. + */ + writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE, + &clock_manager_base->per_pll.src); + writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, + &clock_manager_base->main_pll.l4src); + + /* read back for the required 5 us delay. */ + readl(&clock_manager_base->main_pll.vco); + readl(&clock_manager_base->per_pll.vco); + readl(&clock_manager_base->sdr_pll.vco); + + + /* + * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN + * with numerator and denominator. + */ + writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco); + writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco); + writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco); + + /* + * Time starts here + * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) + */ + start = get_timer(0); + /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ + timeout = 7; + + /* main mpu */ + writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); + + /* main main clock */ + writel(cfg->mainclk, &clock_manager_base->main_pll.mainclk); + + /* main for dbg */ + writel(cfg->dbgatclk, &clock_manager_base->main_pll.dbgatclk); + + /* main for cfgs2fuser0clk */ + writel(cfg->cfg2fuser0clk, + &clock_manager_base->main_pll.cfgs2fuser0clk); + + /* Peri emac0 50 MHz default to RMII */ + writel(cfg->emac0clk, &clock_manager_base->per_pll.emac0clk); + + /* Peri emac1 50 MHz default to RMII */ + writel(cfg->emac1clk, &clock_manager_base->per_pll.emac1clk); + + /* Peri QSPI */ + writel(cfg->mainqspiclk, &clock_manager_base->main_pll.mainqspiclk); + + writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk); + + /* Peri pernandsdmmcclk */ + writel(cfg->mainnandsdmmcclk, + &clock_manager_base->main_pll.mainnandsdmmcclk); + + writel(cfg->pernandsdmmcclk, + &clock_manager_base->per_pll.pernandsdmmcclk); + + /* Peri perbaseclk */ + writel(cfg->perbaseclk, &clock_manager_base->per_pll.perbaseclk); + + /* Peri s2fuser1clk */ + writel(cfg->s2fuser1clk, &clock_manager_base->per_pll.s2fuser1clk); + + /* 7 us must have elapsed before we can enable the VCO */ + while (get_timer(start) < timeout) + ; + + /* Enable vco */ + /* main pll vco */ + writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->main_pll.vco); + + /* periferal pll */ + writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->per_pll.vco); + + /* sdram pll vco */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->sdr_pll.vco); + + /* L3 MP and L3 SP */ + writel(cfg->maindiv, &clock_manager_base->main_pll.maindiv); + + writel(cfg->dbgdiv, &clock_manager_base->main_pll.dbgdiv); + + writel(cfg->tracediv, &clock_manager_base->main_pll.tracediv); + + /* L4 MP, L4 SP, can0, and can1 */ + writel(cfg->perdiv, &clock_manager_base->per_pll.div); + + writel(cfg->gpiodiv, &clock_manager_base->per_pll.gpiodiv); + +#define LOCKED_MASK \ + (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ + CLKMGR_INTER_PERPLLLOCKED_MASK | \ + CLKMGR_INTER_MAINPLLLOCKED_MASK) + + cm_wait_for_lock(LOCKED_MASK); + + /* write the sdram clock counters before toggling outreset all */ + writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddrdqsclk); + + writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddr2xdqsclk); + + writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddrdqclk); + + writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, + &clock_manager_base->sdr_pll.s2fuser2clk); + + /* + * after locking, but before taking out of bypass + * assert/deassert outresetall + */ + uint32_t mainvco = readl(&clock_manager_base->main_pll.vco); + + /* assert main outresetall */ + writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll.vco); + + uint32_t periphvco = readl(&clock_manager_base->per_pll.vco); + + /* assert pheriph outresetall */ + writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll.vco); + + /* assert sdram outresetall */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN| + CLKMGR_SDRPLLGRP_VCO_OUTRESETALL, + &clock_manager_base->sdr_pll.vco); + + /* deassert main outresetall */ + writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll.vco); + + /* deassert pheriph outresetall */ + writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll.vco); + + /* deassert sdram outresetall */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->sdr_pll.vco); + + /* + * now that we've toggled outreset all, all the clocks + * are aligned nicely; so we can change any phase. + */ + cm_write_with_phase(cfg->ddrdqsclk, + (uint32_t)&clock_manager_base->sdr_pll.ddrdqsclk, + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); + + /* SDRAM DDR2XDQSCLK */ + cm_write_with_phase(cfg->ddr2xdqsclk, + (uint32_t)&clock_manager_base->sdr_pll.ddr2xdqsclk, + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); + + cm_write_with_phase(cfg->ddrdqclk, + (uint32_t)&clock_manager_base->sdr_pll.ddrdqclk, + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); + + cm_write_with_phase(cfg->s2fuser2clk, + (uint32_t)&clock_manager_base->sdr_pll.s2fuser2clk, + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); + + /* Take all three PLLs out of bypass when safe mode is cleared. */ + cm_write_bypass(0); + + /* clear safe mode */ + cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE); + + /* + * now that safe mode is clear with clocks gated + * it safe to change the source mux for the flashes the the L4_MAIN + */ + writel(cfg->persrc, &clock_manager_base->per_pll.src); + writel(cfg->l4src, &clock_manager_base->main_pll.l4src); + + /* Now ungate non-hw-managed clocks */ + writel(~0, &clock_manager_base->main_pll.en); + writel(~0, &clock_manager_base->per_pll.en); + writel(~0, &clock_manager_base->sdr_pll.en); + + /* Clear the loss of lock bits (write 1 to clear) */ + writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK | + CLKMGR_INTER_MAINPLLLOST_MASK, + &clock_manager_base->inter); +} + +static unsigned int cm_get_main_vco_clk_hz(void) +{ + uint32_t reg, clock; + + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ; + clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1; + + return clock; +} + +static unsigned int cm_get_per_vco_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> + CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1; + + return clock; +} + +unsigned long cm_get_mpu_clk_hz(void) +{ + uint32_t reg, clock; + + clock = cm_get_main_vco_clk_hz(); + + /* get the MPU clock */ + reg = readl(&clock_manager_base->altera.mpuclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mpuclk); + clock /= (reg + 1); + return clock; +} + +unsigned long cm_get_sdram_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify SDRAM PLL clock source */ + reg = readl(&clock_manager_base->sdr_pll.vco); + reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >> + CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET; + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ; + + /* get the SDRAM VCO clock */ + reg = readl(&clock_manager_base->sdr_pll.vco); + clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1; + + /* get the SDRAM (DDR_DQS) clock */ + reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk); + reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >> + CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET; + clock /= (reg + 1); + + return clock; +} + +unsigned int cm_get_l4_sp_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of L4 SP clock */ + reg = readl(&clock_manager_base->main_pll.l4src); + reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >> + CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET; + + if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { + clock = cm_get_main_vco_clk_hz(); + + /* get the clock prior L4 SP divider (main clk) */ + reg = readl(&clock_manager_base->altera.mainclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mainclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { + clock = cm_get_per_vco_clk_hz(); + + /* get the clock prior L4 SP divider (periph_base_clk) */ + reg = readl(&clock_manager_base->per_pll.perbaseclk); + clock /= (reg + 1); + } + + /* get the L4 SP clock which supplied to UART */ + reg = readl(&clock_manager_base->main_pll.maindiv); + reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >> + CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET; + clock = clock / (1 << reg); + + return clock; +} + +unsigned int cm_get_mmc_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of MMC clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> + CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; + + if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { + clock = cm_get_main_vco_clk_hz(); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { + clock = cm_get_per_vco_clk_hz(); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); + clock /= (reg + 1); + } + + /* further divide by 4 as we have fixed divider at wrapper */ + clock /= 4; + return clock; +} + +unsigned int cm_get_qspi_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of QSPI clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> + CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; + + if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { + clock = cm_get_main_vco_clk_hz(); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->main_pll.mainqspiclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { + clock = cm_get_per_vco_clk_hz(); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->per_pll.perqspiclk); + clock /= (reg + 1); + } + + return clock; +} + +unsigned int cm_get_spi_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + clock = cm_get_per_vco_clk_hz(); + + /* get the clock prior L4 SP divider (periph_base_clk) */ + reg = readl(&clock_manager_base->per_pll.perbaseclk); + clock /= (reg + 1); + + return clock; +} + +static void cm_print_clock_quick_summary(void) +{ + printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); + printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); + printf("EOSC1 %8d kHz\n", CONFIG_HPS_CLK_OSC1_HZ / 1000); + printf("EOSC2 %8d kHz\n", CONFIG_HPS_CLK_OSC2_HZ / 1000); + printf("F2S_SDR_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000); + printf("F2S_PER_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000); + printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); + printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); + printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); + printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); +} + +int set_cpu_clk_info(void) +{ + /* Calculate the clock frequencies required for drivers */ + cm_get_l4_sp_clk_hz(); + cm_get_mmc_controller_clk_hz(); + + gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; + gd->bd->bi_dsp_freq = 0; + gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; + + return 0; +} + +int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cm_print_clock_quick_summary(); + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks, + "display clocks", + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/config.mk b/u-boot-imx/arch/arm/cpu/armv7/socfpga/config.mk new file mode 100644 index 0000000..2a99c72 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/config.mk
@@ -0,0 +1,11 @@ +# +# Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier: GPL-2.0+ +# +ifndef CONFIG_SPL_BUILD +ALL-y += u-boot.img +endif + +# Added for handoff support +PLATFORM_RELFLAGS += -Iboard/$(VENDOR)/$(BOARD)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/fpga_manager.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/fpga_manager.c new file mode 100644 index 0000000..43fd2fe --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/fpga_manager.c
@@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * All rights reserved. + * + * This file contains only support functions used also by the SoCFPGA + * platform code, the real meat is located in drivers/fpga/socfpga.c . + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Timeout count */ +#define FPGA_TIMEOUT_CNT 0x1000000 + +static struct socfpga_fpga_manager *fpgamgr_regs = + (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; + +/* Check whether FPGA Init_Done signal is high */ +static int is_fpgamgr_initdone_high(void) +{ + unsigned long val; + + val = readl(&fpgamgr_regs->gpio_ext_porta); + return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK; +} + +/* Get the FPGA mode */ +int fpgamgr_get_mode(void) +{ + unsigned long val; + + val = readl(&fpgamgr_regs->stat); + return val & FPGAMGRREGS_STAT_MODE_MASK; +} + +/* Check whether FPGA is ready to be accessed */ +int fpgamgr_test_fpga_ready(void) +{ + /* Check for init done signal */ + if (!is_fpgamgr_initdone_high()) + return 0; + + /* Check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + return 0; + + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) + return 0; + + return 1; +} + +/* Poll until FPGA is ready to be accessed or timeout occurred */ +int fpgamgr_poll_fpga_ready(void) +{ + unsigned long i; + + /* If FPGA is blank, wait till WD invoke warm reset */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + /* check for init done signal */ + if (!is_fpgamgr_initdone_high()) + continue; + /* check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + continue; + return 1; + } + + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/freeze_controller.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/freeze_controller.c new file mode 100644 index 0000000..0be643c --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/freeze_controller.c
@@ -0,0 +1,213 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/freeze_controller.h> +#include <asm/arch/timer.h> +#include <asm/errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_freeze_controller *freeze_controller_base = + (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); + +/* + * Default state from cold reset is FREEZE_ALL; the global + * flag is set to TRUE to indicate the IO banks are frozen + */ +static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM] + = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN, + FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN}; + +/* Freeze HPS IOs */ +void sys_mgr_frzctrl_freeze_req(void) +{ + u32 ioctrl_reg_offset; + u32 reg_value; + u32 reg_cfg_mask; + u32 channel_id; + + /* select software FSM */ + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); + + /* Freeze channel 0 to 2 */ + for (channel_id = 0; channel_id <= 2; channel_id++) { + ioctrl_reg_offset = (u32)( + &freeze_controller_base->vioctrl + channel_id); + + /* + * Assert active low enrnsl, plniotri + * and niotri signals + */ + reg_cfg_mask = + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK + | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * Assert active low bhniotri signal and de-assert + * active high csrdone + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* Set global flag to indicate channel is frozen */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; + } + + /* Freeze channel 3 */ + /* + * Assert active low enrnsl, plniotri and + * niotri signals + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK + | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; + clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); + + /* + * assert active low bhniotri & nfrzdrv signals, + * de-assert active high csrdone and assert + * active high frzreg and nfrzdrv signals + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; + reg_value + = (reg_value & ~reg_cfg_mask) + | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK + | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* + * assert active high reinit signal and de-assert + * active high pllbiasen signals + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_value + = (reg_value & + ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK) + | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* Set global flag to indicate channel is frozen */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; +} + +/* Unfreeze/Thaw HPS IOs */ +void sys_mgr_frzctrl_thaw_req(void) +{ + u32 ioctrl_reg_offset; + u32 reg_cfg_mask; + u32 reg_value; + u32 channel_id; + + /* select software FSM */ + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); + + /* Thaw channel 0 to 2 */ + for (channel_id = 0; channel_id <= 2; channel_id++) { + ioctrl_reg_offset + = (u32)(&freeze_controller_base->vioctrl + channel_id); + + /* + * Assert active low bhniotri signal and + * de-assert active high csrdone + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * de-assert active low plniotri and niotri signals + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * de-assert active low enrnsl signal + */ + setbits_le32(ioctrl_reg_offset, + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); + + /* Set global flag to indicate channel is thawed */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; + } + + /* Thaw channel 3 */ + /* de-assert active high reinit signal */ + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); + + /* + * Note: Delay for 40ns at min + * assert active high pllbiasen signals + */ + setbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK); + + /* + * Delay 1000 intosc. intosc is based on eosc1 + * Use worst case which is fatest eosc1=50MHz, delay required + * is 1/50MHz * 1000 = 20us + */ + udelay(20); + + /* + * de-assert active low bhniotri signals, + * assert active high csrdone and nfrzdrv signal + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_value = (reg_value + | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK) + & ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* + * Delay 33 intosc + * Use worst case which is fatest eosc1=50MHz, delay required + * is 1/50MHz * 33 = 660ns ~= 1us + */ + udelay(1); + + /* de-assert active low plniotri and niotri signals */ + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; + + setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); + + /* + * Note: Delay for 40ns at min + * de-assert active high frzreg signal + */ + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK); + + /* + * Note: Delay for 40ns at min + * de-assert active low enrnsl signal + */ + setbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK); + + /* Set global flag to indicate channel is thawed */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/lowlevel_init.S b/u-boot-imx/arch/arm/cpu/armv7/socfpga/lowlevel_init.S new file mode 100644 index 0000000..b4d0627 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/lowlevel_init.S
@@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> + +/* Set up the platform, once the cpu has been initialized */ +.globl lowlevel_init +lowlevel_init: + + /* Remap */ +#ifdef CONFIG_SPL_BUILD + /* + * SPL : configure the remap (L3 NIC-301 GPV) + * so the on-chip RAM at lower memory instead ROM. + */ + ldr r0, =SOCFPGA_L3REGS_ADDRESS + mov r1, #0x19 + str r1, [r0] +#else + /* + * U-Boot : configure the remap (L3 NIC-301 GPV) + * so the SDRAM at lower memory instead on-chip RAM. + */ + ldr r0, =SOCFPGA_L3REGS_ADDRESS + mov r1, #0x2 + str r1, [r0] + + /* Private components security */ + + /* + * U-Boot : configure private timer, global timer and cpu + * component access as non secure for kernel stage (as required + * by kernel) + */ + mrc p15,4,r0,c15,c0,0 + add r1, r0, #0x54 + ldr r2, [r1] + orr r2, r2, #0xff + orr r2, r2, #0xf00 + str r2, [r1] +#endif /* #ifdef CONFIG_SPL_BUILD */ + mov pc, lr
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/misc.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/misc.c new file mode 100644 index 0000000..7873c38 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/misc.c
@@ -0,0 +1,289 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <altera.h> +#include <miiphy.h> +#include <netdev.h> +#include <watchdog.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/dwmmc.h> +#include <asm/arch/nic301.h> +#include <asm/arch/scu.h> +#include <asm/pl310.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; +static struct socfpga_reset_manager *reset_manager_base = + (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; +static struct nic301_registers *nic301_regs = + (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; +static struct scu_registers *scu_regs = + (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); + return 0; +} + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_DESIGNWARE_ETH +int cpu_eth_init(bd_t *bis) +{ +#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; +#elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; +#else +#error "Incorrect CONFIG_EMAC_BASE value!" +#endif + + /* Initialize EMAC. This needs to be done at least once per boot. */ + + /* + * Putting the EMAC controller to reset when configuring the PHY + * interface select at System Manager + */ + socfpga_emac_reset(1); + + /* Clearing emac0 PHY interface select to 0 */ + clrbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); + + /* configure to PHY interface select choosed */ + setbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); + + /* Release the EMAC controller from reset */ + socfpga_emac_reset(0); + + /* initialize and register the emac */ + return designware_initialize(CONFIG_EMAC_BASE, + CONFIG_PHY_INTERFACE_MODE); +} +#endif + +#ifdef CONFIG_DWMMC +/* + * Initializes MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, + CONFIG_HPS_SDMMC_BUSWIDTH, 0); +} +#endif + +#if defined(CONFIG_DISPLAY_CPUINFO) +/* + * Print CPU information + */ +int print_cpuinfo(void) +{ + puts("CPU: Altera SoCFPGA Platform\n"); + return 0; +} +#endif + +#if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ +defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) +int overwrite_console(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_FPGA +/* + * FPGA programming support for SoC FPGA Cyclone V + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_SoCFPGA, + /* Interface type */ + fast_passive_parallel, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + +/* add device descriptor to FPGA device table */ +static void socfpga_fpga_add(void) +{ + int i; + fpga_init(); + for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) + fpga_add(fpga_altera, &altera_fpga[i]); +} +#else +static inline void socfpga_fpga_add(void) {} +#endif + +int arch_cpu_init(void) +{ +#ifdef CONFIG_HW_WATCHDOG + /* + * In case the watchdog is enabled, make sure to (re-)configure it + * so that the defined timeout is valid. Otherwise the SPL (Perloader) + * timeout value is still active which might too short for Linux + * booting. + */ + hw_watchdog_init(); +#else + /* + * If the HW watchdog is NOT enabled, make sure it is not running, + * for example because it was enabled in the preloader. This might + * trigger a watchdog-triggered reboot of Linux kernel later. + */ + socfpga_watchdog_reset(); +#endif + + return 0; +} + +/* + * Convert all NIC-301 AMBA slaves from secure to non-secure + */ +static void socfpga_nic301_slave_ns(void) +{ + writel(0x1, &nic301_regs->lwhps2fpgaregs); + writel(0x1, &nic301_regs->hps2fpgaregs); + writel(0x1, &nic301_regs->acp); + writel(0x1, &nic301_regs->rom); + writel(0x1, &nic301_regs->ocram); + writel(0x1, &nic301_regs->sdrdata); +} + +static uint32_t iswgrp_handoff[8]; + +int arch_early_init_r(void) +{ + int i; + for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ + iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); + + socfpga_bridges_reset(1); + socfpga_nic301_slave_ns(); + + /* + * Private components security: + * U-Boot : configure private timer, global timer and cpu component + * access as non secure for kernel stage (as required by Linux) + */ + setbits_le32(&scu_regs->sacr, 0xfff); + + /* Configure the L2 controller to make SDRAM start at 0 */ +#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET + writel(0x2, &nic301_regs->remap); +#else + writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ + writel(0x1, &pl310->pl310_addr_filter_start); +#endif + + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + +#ifdef CONFIG_DESIGNWARE_SPI + /* Get Designware SPI controller out of reset */ + socfpga_spim_enable(); +#endif + + return 0; +} + +static void socfpga_sdram_apply_static_cfg(void) +{ + const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; + const uint32_t applymask = 0x8; + uint32_t val = readl(staticcfg) | applymask; + + /* + * SDRAM staticcfg register specific: + * When applying the register setting, the CPU must not access + * SDRAM. Luckily for us, we can abuse i-cache here to help us + * circumvent the SDRAM access issue. The idea is to make sure + * that the code is in one full i-cache line by branching past + * it and back. Once it is in the i-cache, we execute the core + * of the code and apply the register settings. + * + * The code below uses 7 instructions, while the Cortex-A9 has + * 32-byte cachelines, thus the limit is 8 instructions total. + */ + asm volatile( + ".align 5 \n" + " b 2f \n" + "1: str %0, [%1] \n" + " dsb \n" + " isb \n" + " b 3f \n" + "2: b 1b \n" + "3: nop \n" + : : "r"(val), "r"(staticcfg) : "memory", "cc"); +} + +int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc != 2) + return CMD_RET_USAGE; + + argv++; + + switch (*argv[0]) { + case 'e': /* Enable */ + writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); + socfpga_sdram_apply_static_cfg(); + writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); + writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); + writel(iswgrp_handoff[1], &nic301_regs->remap); + break; + case 'd': /* Disable */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); + socfpga_sdram_apply_static_cfg(); + writel(0, &reset_manager_base->brg_mod_reset); + writel(1, &nic301_regs->remap); + break; + default: + return CMD_RET_USAGE; + } + + return 0; +} + +U_BOOT_CMD( + bridge, 2, 1, do_bridge, + "SoCFPGA HPS FPGA bridge control", + "enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" + "bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n" + "" +);
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/reset_manager.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/reset_manager.c new file mode 100644 index 0000000..25921e7 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/reset_manager.c
@@ -0,0 +1,115 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/fpga_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_reset_manager *reset_manager_base = + (void *)SOCFPGA_RSTMGR_ADDRESS; + +/* Toggle reset signal to watchdog (WDT is disabled after this operation!) */ +void socfpga_watchdog_reset(void) +{ + /* assert reset for watchdog */ + setbits_le32(&reset_manager_base->per_mod_reset, + 1 << RSTMGR_PERMODRST_L4WD0_LSB); + + /* deassert watchdog from reset (watchdog in not running state) */ + clrbits_le32(&reset_manager_base->per_mod_reset, + 1 << RSTMGR_PERMODRST_L4WD0_LSB); +} + +/* + * Write the reset manager register to cause reset + */ +void reset_cpu(ulong addr) +{ + /* request a warm reset */ + writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB), + &reset_manager_base->ctrl); + /* + * infinite loop here as watchdog will trigger and reset + * the processor + */ + while (1) + ; +} + +/* + * Release peripherals from reset based on handoff + */ +void reset_deassert_peripherals_handoff(void) +{ + writel(0, &reset_manager_base->per_mod_reset); +} + +#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) +void socfpga_bridges_reset(int enable) +{ + /* For SoCFPGA-VT, this is NOP. */ +} +#else + +#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x10 +#define L3REGS_REMAP_HPS2FPGA_MASK 0x08 +#define L3REGS_REMAP_OCRAM_MASK 0x01 + +void socfpga_bridges_reset(int enable) +{ + const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK | + L3REGS_REMAP_HPS2FPGA_MASK | + L3REGS_REMAP_OCRAM_MASK; + + if (enable) { + /* brdmodrst */ + writel(0xffffffff, &reset_manager_base->brg_mod_reset); + } else { + /* Check signal from FPGA. */ + if (fpgamgr_poll_fpga_ready()) { + /* FPGA not ready. Wait for watchdog timeout. */ + printf("%s: fpga not ready, hanging.\n", __func__); + hang(); + } + + /* brdmodrst */ + writel(0, &reset_manager_base->brg_mod_reset); + + /* Remap the bridges into memory map */ + writel(l3mask, SOCFPGA_L3REGS_ADDRESS); + } +} +#endif + +/* Change the reset state for EMAC 0 and EMAC 1 */ +void socfpga_emac_reset(int enable) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + if (enable) { + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); + } else { +#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); +#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); +#endif + } +} + +/* SPI Master enable (its held in reset by the preloader) */ +void socfpga_spim_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, (1 << RSTMGR_PERMODRST_SPIM0_LSB) | + (1 << RSTMGR_PERMODRST_SPIM1_LSB)); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/scan_manager.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/scan_manager.c new file mode 100644 index 0000000..a820b1b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/scan_manager.c
@@ -0,0 +1,209 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/freeze_controller.h> +#include <asm/arch/scan_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_scan_manager *scan_manager_base = + (void *)(SOCFPGA_SCANMGR_ADDRESS); +static const struct socfpga_freeze_controller *freeze_controller_base = + (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); + +/* + * Function to check IO scan chain engine status and wait if the engine is + * is active. Poll the IO scan chain engine till maximum iteration reached. + */ +static inline uint32_t scan_chain_engine_is_idle(uint32_t max_iter) +{ + uint32_t scanmgr_status; + + scanmgr_status = readl(&scan_manager_base->stat); + + /* Poll the engine until the scan engine is inactive */ + while (SCANMGR_STAT_ACTIVE_GET(scanmgr_status) || + (SCANMGR_STAT_WFIFOCNT_GET(scanmgr_status) > 0)) { + max_iter--; + if (max_iter > 0) + scanmgr_status = readl(&scan_manager_base->stat); + else + return 0; + } + return 1; +} + +/* Program HPS IO Scan Chain */ +uint32_t scan_mgr_io_scan_chain_prg( + uint32_t io_scan_chain_id, + uint32_t io_scan_chain_len_in_bits, + const uint32_t *iocsr_scan_chain) +{ + uint16_t tdi_tdo_header; + uint32_t io_program_iter; + uint32_t io_scan_chain_data_residual; + uint32_t residual; + uint32_t i; + uint32_t index = 0; + + /* + * De-assert reinit if the IO scan chain is intended for HIO. In + * this, its the chain 3. + */ + if (io_scan_chain_id == 3) + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); + + /* + * Check if the scan chain engine is inactive and the + * WFIFO is empty before enabling the IO scan chain + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + return 1; + + /* + * Enable IO Scan chain based on scan chain id + * Note: only one chain can be enabled at a time + */ + setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + + /* + * Calculate number of iteration needed for full 128-bit (4 x32-bits) + * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits + */ + io_program_iter = io_scan_chain_len_in_bits >> + IO_SCAN_CHAIN_128BIT_SHIFT; + io_scan_chain_data_residual = io_scan_chain_len_in_bits & + IO_SCAN_CHAIN_128BIT_MASK; + + /* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */ + tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | + (TDI_TDO_MAX_PAYLOAD << TDI_TDO_HEADER_SECOND_BYTE_SHIFT); + + /* Program IO scan chain in 128-bit iteration */ + for (i = 0; i < io_program_iter; i++) { + /* write TDI_TDO packet header to scan manager */ + writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); + + /* calculate array index. Multiply by 4 as write 4 x 32bits */ + index = i * 4; + + /* write 4 successive 32-bit IO scan chain data into WFIFO */ + writel(iocsr_scan_chain[index], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 1], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 2], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 3], + &scan_manager_base->fifo_quad_byte); + + /* + * Check if the scan chain engine has completed the + * IO scan chain data shifting + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + goto error; + } + + /* Calculate array index for final TDI_TDO packet */ + index = io_program_iter * 4; + + /* Final TDI_TDO packet if any */ + if (io_scan_chain_data_residual) { + /* + * Calculate number of quad bytes FIFO write + * needed for the final TDI_TDO packet + */ + io_program_iter = io_scan_chain_data_residual >> + IO_SCAN_CHAIN_32BIT_SHIFT; + + /* + * Construct TDI_TDO packet for remaining IO + * scan chain (2 bytes) + */ + tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | + ((io_scan_chain_data_residual - 1) << + TDI_TDO_HEADER_SECOND_BYTE_SHIFT); + + /* + * Program the last part of IO scan chain write TDI_TDO packet + * header (2 bytes) to scan manager + */ + writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); + + for (i = 0; i < io_program_iter; i++) { + /* + * write remaining scan chain data into scan + * manager WFIFO with 4 bytes write + */ + writel(iocsr_scan_chain[index + i], + &scan_manager_base->fifo_quad_byte); + } + + index += io_program_iter; + residual = io_scan_chain_data_residual & + IO_SCAN_CHAIN_32BIT_MASK; + + if (IO_SCAN_CHAIN_PAYLOAD_24BIT < residual) { + /* + * write the last 4B scan chain data + * into scan manager WFIFO + */ + writel(iocsr_scan_chain[index], + &scan_manager_base->fifo_quad_byte); + } else { + /* + * write the remaining 1 - 3 bytes scan chain + * data into scan manager WFIFO byte by byte + * to prevent JTAG engine shifting unused data + * from the FIFO and mistaken the data as a + * valid command (even though unused bits are + * set to 0, but just to prevent hardware + * glitch) + */ + for (i = 0; i < residual; i += 8) { + writel(((iocsr_scan_chain[index] >> i) + & IO_SCAN_CHAIN_BYTE_MASK), + &scan_manager_base->fifo_single_byte); + } + } + + /* + * Check if the scan chain engine has completed the + * IO scan chain data shifting + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + goto error; + } + + /* Disable IO Scan chain when configuration done*/ + clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + return 0; + +error: + /* Disable IO Scan chain when error detected */ + clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + return 1; +} + +int scan_mgr_configure_iocsr(void) +{ + int status = 0; + + /* configure the IOCSR through scan chain */ + status |= scan_mgr_io_scan_chain_prg(0, + CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH, iocsr_scan_chain0_table); + status |= scan_mgr_io_scan_chain_prg(1, + CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH, iocsr_scan_chain1_table); + status |= scan_mgr_io_scan_chain_prg(2, + CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH, iocsr_scan_chain2_table); + status |= scan_mgr_io_scan_chain_prg(3, + CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH, iocsr_scan_chain3_table); + return status; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/spl.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/spl.c new file mode 100644 index 0000000..6a8c15d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/spl.c
@@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <image.h> +#include <asm/arch/reset_manager.h> +#include <spl.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/freeze_controller.h> +#include <asm/arch/clock_manager.h> +#include <asm/arch/scan_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MAIN_VCO_BASE ( \ + (CONFIG_HPS_MAINPLLGRP_VCO_DENOM << \ + CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_MAINPLLGRP_VCO_NUMER << \ + CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) \ + ) + +#define PERI_VCO_BASE ( \ + (CONFIG_HPS_PERPLLGRP_VCO_PSRC << \ + CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET) | \ + (CONFIG_HPS_PERPLLGRP_VCO_DENOM << \ + CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_PERPLLGRP_VCO_NUMER << \ + CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) \ + ) + +#define SDR_VCO_BASE ( \ + (CONFIG_HPS_SDRPLLGRP_VCO_SSRC << \ + CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET) | \ + (CONFIG_HPS_SDRPLLGRP_VCO_DENOM << \ + CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_SDRPLLGRP_VCO_NUMER << \ + CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) \ + ) + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_RAM; +} + +/* + * Board initialization after bss clearance + */ +void spl_board_init(void) +{ +#ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET + cm_config_t cm_default_cfg = { + /* main group */ + MAIN_VCO_BASE, + (CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT << + CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT << + CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT << + CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT << + CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT << + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT << + CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK << + CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK << + CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK << + CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP << + CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP << + CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET), + + /* peripheral group */ + PERI_VCO_BASE, + (CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT << + CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT << + CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT << + CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT << + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT << + CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT << + CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_DIV_USBCLK << + CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK << + CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK << + CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK << + CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET), + (CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK << + CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET), + (CONFIG_HPS_PERPLLGRP_SRC_QSPI << + CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET) | + (CONFIG_HPS_PERPLLGRP_SRC_NAND << + CLKMGR_PERPLLGRP_SRC_NAND_OFFSET) | + (CONFIG_HPS_PERPLLGRP_SRC_SDMMC << + CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET), + + /* sdram pll group */ + SDR_VCO_BASE, + (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE << + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT << + CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE << + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT << + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE << + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT << + CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE << + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT << + CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET), + + }; + + debug("Freezing all I/O banks\n"); + /* freeze all IO banks */ + sys_mgr_frzctrl_freeze_req(); + + debug("Reconfigure Clock Manager\n"); + /* reconfigure the PLLs */ + cm_basic_init(&cm_default_cfg); + + /* configure the IOCSR / IO buffer settings */ + if (scan_mgr_configure_iocsr()) + hang(); + + /* configure the pin muxing through system manager */ + sysmgr_pinmux_init(); +#endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */ + + /* de-assert reset for peripherals and bridges based on handoff */ + reset_deassert_peripherals_handoff(); + + debug("Unfreezing/Thaw all I/O banks\n"); + /* unfreeze / thaw all IO banks */ + sys_mgr_frzctrl_thaw_req(); + + /* enable console uart printing */ + preloader_console_init(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/system_manager.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/system_manager.c new file mode 100644 index 0000000..11f7bad --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/system_manager.c
@@ -0,0 +1,68 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/fpga_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* + * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting. + * The value is not wrote to SYSMGR.FPGAINTF.MODULE but + * CONFIG_SYSMGR_ISWGRP_HANDOFF. + */ +static void populate_sysmgr_fpgaintf_module(void) +{ + uint32_t handoff_val = 0; + + /* ISWGRP_HANDOFF_FPGAINTF */ + writel(0, &sysmgr_regs->iswgrp_handoff[2]); + + /* Enable the signal for those HPS peripherals that use FPGA. */ + if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_NAND; + if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC1; + if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SDMMC; + if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC0; + if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM0; + if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM1; + + /* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE + based on pinmux setting */ + setbits_le32(&sysmgr_regs->iswgrp_handoff[2], handoff_val); + + handoff_val = readl(&sysmgr_regs->iswgrp_handoff[2]); + if (fpgamgr_test_fpga_ready()) { + /* Enable the required signals only */ + writel(handoff_val, &sysmgr_regs->fpgaintfgrp_module); + } +} + +/* + * Configure all the pin muxes + */ +void sysmgr_pinmux_init(void) +{ + uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0]; + int i; + + for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); i++) { + writel(sys_mgr_init_table[i], regs); + regs += sizeof(regs); + } + + populate_sysmgr_fpgaintf_module(); +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/timer.c b/u-boot-imx/arch/arm/cpu/armv7/socfpga/timer.c new file mode 100644 index 0000000..253cde3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/timer.c
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/timer.h> + +#define TIMER_LOAD_VAL 0xFFFFFFFF + +static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE; + +/* + * Timer initialization + */ +int timer_init(void) +{ + writel(TIMER_LOAD_VAL, &timer_base->load_val); + writel(TIMER_LOAD_VAL, &timer_base->curr_val); + writel(readl(&timer_base->ctrl) | 0x3, &timer_base->ctrl); + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds b/u-boot-imx/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds new file mode 100644 index 0000000..569fa41 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds
@@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sdram : ORIGIN = (0), LENGTH = (0xffffffff) } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.vectors) + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sdram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } >.sdram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sdram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/start.S b/u-boot-imx/arch/arm/cpu/armv7/start.S new file mode 100644 index 0000000..db77adb --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/start.S
@@ -0,0 +1,256 @@ +/* + * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core + * + * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com> + * + * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> + * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> + * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> + * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> + * Copyright (c) 2003 Kshitij <kshitij@ti.com> + * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/system.h> +#include <linux/linkage.h> + +/************************************************************************* + * + * 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 + * + *************************************************************************/ + + .globl reset + .globl save_boot_params_ret + +reset: + /* Allow the board to save important registers */ + b save_boot_params +save_boot_params_ret: + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + +/* + * Setup vector: + * (OMAP4 spl TEXT_BASE is not 32 byte aligned. + * Continue to use ROM code vector only in OMAP4 spl) + */ +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) + /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ + mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register + bic r0, #CR_V @ V = 0 + mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register + + /* Set vector address in CP15 VBAR register */ + ldr r0, =_start + mcr p15, 0, r0, c12, c0, 0 @Set VBAR +#endif + + /* the mask ROM code should have PLL and others stable */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl cpu_init_cp15 + bl cpu_init_crit +#endif + + bl _main + +/*------------------------------------------------------------------------------*/ + +ENTRY(c_runtime_cpu_setup) +/* + * If I-cache is enabled invalidate it + */ +#ifndef CONFIG_SYS_ICACHE_OFF + mcr p15, 0, r0, c7, c5, 0 @ invalidate icache + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB +#endif + + bx lr + +ENDPROC(c_runtime_cpu_setup) + +/************************************************************************* + * + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) + * __attribute__((weak)); + * + * Stack pointer is not yet initialized at this moment + * Don't save anything to stack even if compiled with -O0 + * + *************************************************************************/ +ENTRY(save_boot_params) + b save_boot_params_ret @ back to my caller +ENDPROC(save_boot_params) + .weak save_boot_params + +/************************************************************************* + * + * cpu_init_cp15 + * + * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless + * CONFIG_SYS_ICACHE_OFF is defined. + * + *************************************************************************/ +ENTRY(cpu_init_cp15) + /* + * 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, 0 @ invalidate icache + mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c5, 4 @ ISB + + /* + * 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 + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB +#ifdef CONFIG_SYS_ICACHE_OFF + bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache +#else + orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache +#endif + mcr p15, 0, r0, c1, c0, 0 + +#ifdef CONFIG_ARM_ERRATA_716044 + mrc p15, 0, r0, c1, c0, 0 @ read system control register + orr r0, r0, #1 << 11 @ set bit #11 + mcr p15, 0, r0, c1, c0, 0 @ write system control register +#endif + +#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 4 @ set bit #4 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif + +#ifdef CONFIG_ARM_ERRATA_743622 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 6 @ set bit #6 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif + +#ifdef CONFIG_ARM_ERRATA_751472 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 11 @ set bit #11 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif +#ifdef CONFIG_ARM_ERRATA_761320 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 21 @ set bit #21 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif +#ifdef CONFIG_ARM_ERRATA_845369 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 22 @ set bit #22 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif + + mov r5, lr @ Store my Caller + mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) + mov r3, r1, lsr #20 @ get variant field + and r3, r3, #0xf @ r3 has CPU variant + and r4, r1, #0xf @ r4 has CPU revision + mov r2, r3, lsl #4 @ shift variant field for combined value + orr r2, r4, r2 @ r2 has combined CPU variant + revision + +#ifdef CONFIG_ARM_ERRATA_798870 + cmp r2, #0x30 @ Applies to lower than R3p0 + bge skip_errata_798870 @ skip if not affected rev + cmp r2, #0x20 @ Applies to including and above R2p0 + blt skip_errata_798870 @ skip if not affected rev + + mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg + orr r0, r0, #1 << 7 @ Enable hazard-detect timeout + push {r1-r5} @ Save the cpu info registers + bl v7_arch_cp15_set_l2aux_ctrl + isb @ Recommended ISB after l2actlr update + pop {r1-r5} @ Restore the cpu info - fall through +skip_errata_798870: +#endif + +#ifdef CONFIG_ARM_ERRATA_454179 + cmp r2, #0x21 @ Only on < r2p1 + bge skip_errata_454179 + + mrc p15, 0, r0, c1, c0, 1 @ Read ACR + orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits + push {r1-r5} @ Save the cpu info registers + bl v7_arch_cp15_set_acr + pop {r1-r5} @ Restore the cpu info - fall through + +skip_errata_454179: +#endif + +#ifdef CONFIG_ARM_ERRATA_430973 + cmp r2, #0x21 @ Only on < r2p1 + bge skip_errata_430973 + + mrc p15, 0, r0, c1, c0, 1 @ Read ACR + orr r0, r0, #(0x1 << 6) @ Set IBE bit + push {r1-r5} @ Save the cpu info registers + bl v7_arch_cp15_set_acr + pop {r1-r5} @ Restore the cpu info - fall through + +skip_errata_430973: +#endif + +#ifdef CONFIG_ARM_ERRATA_621766 + cmp r2, #0x21 @ Only on < r2p1 + bge skip_errata_621766 + + mrc p15, 0, r0, c1, c0, 1 @ Read ACR + orr r0, r0, #(0x1 << 5) @ Set L1NEON bit + push {r1-r5} @ Save the cpu info registers + bl v7_arch_cp15_set_acr + pop {r1-r5} @ Restore the cpu info - fall through + +skip_errata_621766: +#endif + + mov pc, r5 @ back to my caller +ENDPROC(cpu_init_cp15) + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT +/************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + *************************************************************************/ +ENTRY(cpu_init_crit) + /* + * 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. + */ + b lowlevel_init @ go setup pll,mux,memory +ENDPROC(cpu_init_crit) +#endif
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/Makefile b/u-boot-imx/arch/arm/cpu/armv7/stv0991/Makefile new file mode 100644 index 0000000..95641d3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/Makefile
@@ -0,0 +1,9 @@ +# +# (C) Copyright 2014 +# Vikas Manocha, ST Microelectronics, vikas.manocha@stcom +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := timer.o clock.o pinmux.o reset.o +obj-y += lowlevel.o
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/clock.c b/u-boot-imx/arch/arm/cpu/armv7/stv0991/clock.c new file mode 100644 index 0000000..70b8a8d --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/clock.c
@@ -0,0 +1,41 @@ +/* + * (C) Copyright 2014 + * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/stv0991_cgu.h> +#include<asm/arch/stv0991_periph.h> + +static struct stv0991_cgu_regs *const stv0991_cgu_regs = \ + (struct stv0991_cgu_regs *) (CGU_BASE_ADDR); + +void enable_pll1(void) +{ + /* pll1 already configured for 1000Mhz, just need to enable it */ + writel(readl(&stv0991_cgu_regs->pll1_ctrl) & ~(0x01), + &stv0991_cgu_regs->pll1_ctrl); +} + +void clock_setup(int peripheral) +{ + switch (peripheral) { + case UART_CLOCK_CFG: + writel(UART_CLK_CFG, &stv0991_cgu_regs->uart_freq); + break; + case ETH_CLOCK_CFG: + enable_pll1(); + writel(ETH_CLK_CFG, &stv0991_cgu_regs->eth_freq); + + /* Clock selection for ethernet tx_clk & rx_clk*/ + writel((readl(&stv0991_cgu_regs->eth_ctrl) & ETH_CLK_MASK) + | ETH_CLK_CTRL, &stv0991_cgu_regs->eth_ctrl); + + break; + default: + break; + } +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/lowlevel.S b/u-boot-imx/arch/arm/cpu/armv7/stv0991/lowlevel.S new file mode 100644 index 0000000..6dafba3 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/lowlevel.S
@@ -0,0 +1,12 @@ +/* + * (C) Copyright 2014 stmicroelectronics + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + mov pc, lr +ENDPROC(lowlevel_init)
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/pinmux.c b/u-boot-imx/arch/arm/cpu/armv7/stv0991/pinmux.c new file mode 100644 index 0000000..1d086a2 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/pinmux.c
@@ -0,0 +1,62 @@ +/* + * (C) Copyright 2014 + * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <asm/arch/stv0991_creg.h> +#include <asm/arch/stv0991_periph.h> +#include <asm/arch/hardware.h> + +static struct stv0991_creg *const stv0991_creg = \ + (struct stv0991_creg *)CREG_BASE_ADDR; + +int stv0991_pinmux_config(int peripheral) +{ + switch (peripheral) { + case UART_GPIOC_30_31: + /* SSDA/SSCL pad muxing to UART Rx/Dx */ + writel((readl(&stv0991_creg->mux12) & GPIOC_31_MUX_MASK) | + CFG_GPIOC_31_UART_RX, + &stv0991_creg->mux12); + writel((readl(&stv0991_creg->mux12) & GPIOC_30_MUX_MASK) | + CFG_GPIOC_30_UART_TX, + &stv0991_creg->mux12); + /* SSDA/SSCL pad config to push pull*/ + writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_31_MODE_MASK) | + CFG_GPIOC_31_MODE_PP, + &stv0991_creg->cfg_pad6); + writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_30_MODE_MASK) | + CFG_GPIOC_30_MODE_HIGH, + &stv0991_creg->cfg_pad6); + break; + case UART_GPIOB_16_17: + /* ethernet rx_6/7 to UART Rx/Dx */ + writel((readl(&stv0991_creg->mux7) & GPIOB_17_MUX_MASK) | + CFG_GPIOB_17_UART_RX, + &stv0991_creg->mux7); + writel((readl(&stv0991_creg->mux7) & GPIOB_16_MUX_MASK) | + CFG_GPIOB_16_UART_TX, + &stv0991_creg->mux7); + break; + case ETH_GPIOB_10_31_C_0_4: + writel(readl(&stv0991_creg->mux6) & 0x000000FF, + &stv0991_creg->mux6); + writel(0x00000000, &stv0991_creg->mux7); + writel(0x00000000, &stv0991_creg->mux8); + writel(readl(&stv0991_creg->mux9) & 0xFFF00000, + &stv0991_creg->mux9); + /* Ethernet Voltage configuration to 1.8V*/ + writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) | + ETH_VDD_CFG, &stv0991_creg->vdd_pad1); + writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) | + ETH_M_VDD_CFG, &stv0991_creg->vdd_pad1); + + break; + default: + break; + } + return 0; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/reset.c b/u-boot-imx/arch/arm/cpu/armv7/stv0991/reset.c new file mode 100644 index 0000000..3384b32 --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/reset.c
@@ -0,0 +1,26 @@ +/* + * (C) Copyright 2014 + * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/stv0991_wdru.h> +void reset_cpu(ulong ignored) +{ + puts("System is going to reboot ...\n"); + /* + * This 1 second delay will allow the above message + * to be printed before reset + */ + udelay((1000 * 1000)); + + /* Setting bit 1 of the WDRU unit will reset the SoC */ + writel(WDRU_RST_SYS, &stv0991_wd_ru_ptr->wdru_ctrl1); + + /* system will restart */ + while (1) + ; +}
diff --git a/u-boot-imx/arch/arm/cpu/armv7/stv0991/timer.c b/u-boot-imx/arch/arm/cpu/armv7/stv0991/timer.c new file mode 100644 index 0000000..8654b8b --- /dev/null +++ b/u-boot-imx/arch/arm/cpu/armv7/stv0991/timer.c
@@ -0,0 +1,114 @@ +/* + * (C) Copyright 2014 + * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch-stv0991/hardware.h> +#include <asm/arch-stv0991/stv0991_cgu.h> +#include <asm/arch-stv0991/stv0991_gpt.h> + +static struct stv0991_cgu_regs *const stv0991_cgu_regs = \ + (struct stv0991_cgu_regs *) (CGU_BASE_ADDR); + +#define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING) +#define GPT_RESOLUTION (CONFIG_STV0991_HZ_CLOCK / CONFIG_STV0991_HZ) + +DECLARE_GLOBAL_DATA_PTR; + +#define timestamp gd->arch.tbl +#define lastdec gd->arch.lastinc + +int timer_init(void) +{ + /* Timer1 clock configuration */ + writel(TIMER1_CLK_CFG, &stv0991_cgu_regs->tim_freq); + writel(readl(&stv0991_cgu_regs->cgu_enable_2) | + TIMER1_CLK_EN, &stv0991_cgu_regs->cgu_enable_2); + + /* Stop the timer */ + writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1); + writel(GPT_PRESCALER_128, &gpt1_regs_ptr->psc); + /* Configure timer for auto-reload */ + writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD, + &gpt1_regs_ptr->cr1); + + /* load value for free running */ + writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr); + + /* start timer */ + writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN, + &gpt1_regs_ptr->cr1); + + /* Reset the timer */ + lastdec = READ_TIMER(); + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +ulong get_timer(ulong base) +{ + return (get_timer_masked() / GPT_RESOLUTION) - base; +} + +void __udelay(unsigned long usec) +{ + ulong tmo; + ulong start = get_timer_masked(); + ulong tenudelcnt = CONFIG_STV0991_HZ_CLOCK / (1000 * 100); + ulong rndoff; + + rndoff = (usec % 10) ? 1 : 0; +