#
- # (C) Copyright 2000-2012
+ # (C) Copyright 2000-2013
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
- # See file CREDITS for list of people who contributed to this
- # project.
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as
- # published by the Free Software Foundatio; 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
+ # SPDX-License-Identifier: GPL-2.0+
#
VERSION = 2013
- PATCHLEVEL = 01
+ PATCHLEVEL = 07
SUBLEVEL =
EXTRAVERSION =
ifneq "$(SUBLEVEL)" ""
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
sed -e 's/\(cygwin\).*/cygwin/')
- # Set shell to bash if possible, otherwise fall back to sh
- SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
- else if [ -x /bin/bash ]; then echo /bin/bash; \
- else echo sh; fi; fi)
-
- export HOSTARCH HOSTOS SHELL
+ export HOSTARCH HOSTOS
# Deal with colliding definitions from tcsh etc.
VENDOR=
# load other configuration
include $(TOPDIR)/config.mk
+ # Targets which don't build the source code
+ NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig
+
+ # Only do the generic board check when actually building, not configuring
+ ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),)
+ ifeq ($(findstring _config,$(MAKECMDGOALS)),)
+ $(CHECK_GENERIC_BOARD)
+ 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.
# U-Boot objects....order is important (i.e. start must be first)
OBJS = $(CPUDIR)/start.o
- ifeq ($(CPU),x86)
- RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/start16.o
- RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += $(CPUDIR)/resetvec.o
- endif
ifeq ($(CPU),ppc4xx)
OBJS += $(CPUDIR)/resetvec.o
endif
OBJS += $(CPUDIR)/resetvec.o
endif
- OBJS := $(addprefix $(obj),$(OBJS) $(RESET_OBJS-))
+ OBJS := $(addprefix $(obj),$(OBJS))
HAVE_VENDOR_COMMON_LIB = $(if $(wildcard board/$(VENDOR)/common/Makefile),y,n)
LIBS-y += lib/libgeneric.o
+ LIBS-y += lib/rsa/librsa.o
LIBS-y += lib/lzma/liblzma.o
LIBS-y += lib/lzo/liblzo.o
LIBS-y += lib/zlib/libz.o
fs/fdos/libfdos.o \
fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o \
+ fs/sandbox/libsandboxfs.o \
fs/ubifs/libubifs.o \
fs/yaffs2/libyaffs2.o \
fs/zfs/libzfs.o
LIBS-y += drivers/bios_emulator/libatibiosemu.o
LIBS-y += drivers/block/libblock.o
LIBS-$(CONFIG_BOOTCOUNT_LIMIT) += drivers/bootcount/libbootcount.o
+ LIBS-y += drivers/crypto/libcrypto.o
LIBS-y += drivers/dma/libdma.o
LIBS-y += drivers/fpga/libfpga.o
LIBS-y += drivers/gpio/libgpio.o
LIBS-y += drivers/rtc/librtc.o
LIBS-y += drivers/serial/libserial.o
LIBS-y += drivers/sound/libsound.o
- LIBS-$(CONFIG_GENERIC_LPC_TPM) += drivers/tpm/libtpm.o
+ LIBS-y += drivers/tpm/libtpm.o
LIBS-y += drivers/twserial/libtws.o
LIBS-y += drivers/usb/eth/libusb_eth.o
LIBS-y += drivers/usb/gadget/libusb_gadget.o
LIBS-y += post/libpost.o
LIBS-y += test/libtest.o
- ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TI814X),)
LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
endif
- ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx31 mx35))
+ ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx31 mx35 mxs vf610))
LIBS-y += arch/$(ARCH)/imx-common/libimx-common.o
endif
ifeq ($(SOC),exynos)
LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o
endif
- ifeq ($(SOC),tegra20)
+ ifneq ($(CONFIG_TEGRA),)
LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o
LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o
LIBS-y += $(CPUDIR)/tegra-common/libtegra-common.o
ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin
ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
- ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin
+ ifneq ($(CONFIG_SPL_TARGET),)
+ ALL-$(CONFIG_SPL) += $(obj)$(subst ",,$(CONFIG_SPL_TARGET))
+ endif
# enable combined SPL/u-boot/dtb rules for tegra
- ifeq ($(SOC),tegra20)
+ ifneq ($(CONFIG_TEGRA),)
ifeq ($(CONFIG_OF_SEPARATE),y)
ALL-y += $(obj)u-boot-dtb-tegra.bin
else
all: $(ALL-y) $(SUBDIR_EXAMPLES)
- $(obj)u-boot.dtb: $(obj)u-boot
+ $(obj)u-boot.dtb: checkdtc $(obj)u-boot
$(MAKE) -C dts binary
mv $(obj)dts/dt.dtb $@
sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
-d $< $@
- $(obj)u-boot.imx: $(obj)u-boot.bin
- $(obj)tools/mkimage -n $(CONFIG_IMX_CONFIG) -T imximage \
- -e $(CONFIG_SYS_TEXT_BASE) -d $< $@
+ $(obj)u-boot.imx: $(obj)u-boot.bin depend
+ $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
$(obj)u-boot.kwb: $(obj)u-boot.bin
$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
$(obj)u-boot-with-spl.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
- $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(or $(CONFIG_SPL_PAD_TO),0) \
- -O binary $(obj)spl/u-boot-spl \
- $(obj)spl/u-boot-spl-pad.bin
+ $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SPL_PAD_TO) \
+ -I binary -O binary $< $(obj)spl/u-boot-spl-pad.bin
cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
rm $(obj)spl/u-boot-spl-pad.bin
+ $(obj)u-boot-with-spl.imx: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
+ $(MAKE) -C $(SRCTREE)/arch/arm/imx-common \
+ $(OBJTREE)/u-boot-with-spl.imx
+
+ $(obj)u-boot-with-nand-spl.imx: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
+ $(MAKE) -C $(SRCTREE)/arch/arm/imx-common \
+ $(OBJTREE)/u-boot-with-nand-spl.imx
+
$(obj)u-boot.ubl: $(obj)u-boot-with-spl.bin
$(obj)tools/mkimage -n $(UBL_CONFIG) -T ublimage \
-e $(CONFIG_SYS_TEXT_BASE) -d $< $(obj)u-boot.ubl
cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.img > \
$(obj)u-boot.ais
- # Specify the target for use in elftosb call
- ELFTOSB_TARGET-$(CONFIG_MX28) = imx28
-$(obj)u-boot.sb: $(obj)u-boot $(obj)spl/u-boot-spl.bin elftosb
+$(obj)u-boot.sb: $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin elftosb
- cd $(OBJTREE); \
- $(TOPDIR)/$(SUBDIR_TOOLS)/elftosb/bld/linux/elftosb -zdf $(ELFTOSB_TARGET-y) -c $(TOPDIR)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd \
- -o $(obj)u-boot.sb
+ $(MAKE) -C $(SRCTREE)/$(CPUDIR)/$(SOC)/ $(OBJTREE)/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
conv=notrunc 2>/dev/null
cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
- ifeq ($(SOC),tegra20)
- ifeq ($(CONFIG_OF_SEPARATE),y)
- nodtb=dtb
- dtbfile=$(obj)u-boot.dtb
- else
- nodtb=nodtb
- dtbfile=
- endif
-
- $(obj)u-boot-$(nodtb)-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(dtbfile)
+ ifneq ($(CONFIG_TEGRA),)
+ $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
- cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin $(dtbfile) > $@
+ cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot.bin > $@
rm $(obj)spl/u-boot-spl-pad.bin
+
+ ifeq ($(CONFIG_OF_SEPARATE),y)
+ $(obj)u-boot-dtb-tegra.bin: $(obj)u-boot-nodtb-tegra.bin $(obj)u-boot.dtb
+ cat $(obj)u-boot-nodtb-tegra.bin $(obj)u-boot.dtb > $@
+ endif
endif
$(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
+ # 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.
+ $(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+ tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \
+ of=$(obj)u-boot-pad.img 2>/dev/null
+ dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \
+ conv=notrunc 2>/dev/null
+ cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
+
ifeq ($(CONFIG_SANDBOX),y)
GEN_UBOOT = \
cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map -o u-boot
else
GEN_UBOOT = \
- UNDEF_LST=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
- sed -n -e 's/.*\($(SYM_PREFIX)_u_boot_list_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
- $$UNDEF_LST $(__OBJS) \
+ $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
endif
$(LDSCRIPT): depend
$(MAKE) -C $(dir $@) $(notdir $@)
- # The following line expands into whole rule which generates u-boot.lst,
- # the file containing u-boots LG-array linker section. This is included into
- # $(LDSCRIPT). The function make_u_boot_list is defined in helper.mk file.
- $(eval $(call make_u_boot_list, $(obj)include/u-boot.lst, $(LIBBOARD) $(LIBS)))
- $(obj)u-boot.lds: $(LDSCRIPT) $(obj)include/u-boot.lst
+ $(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$< >$@
nand_spl: $(TIMESTAMP_FILE) $(VERSION_FILE) depend
false; \
fi
+ 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
+
#
# Auto-generate the autoconf.mk file (which is included by all makefiles)
#
$(MAKE) -C $@ all
endif # config.mk
+ # ARM relocations should all be R_ARM_RELATIVE.
+ checkarmreloc: $(obj)u-boot
+ @if test "R_ARM_RELATIVE" != \
+ "`$(CROSS_COMPILE)readelf -r $< | cut -d ' ' -f 4 | grep R_ARM | sort -u`"; \
+ then echo "$< contains relocations other than \
+ R_ARM_RELATIVE"; false; fi
+
$(VERSION_FILE):
@mkdir -p $(dir $(VERSION_FILE))
@( localvers='$(shell $(TOPDIR)/tools/setlocalversion $(TOPDIR))' ; \
lcname = $(shell echo $(1) | sed -e 's/\(.*\)_config/\L\1/')
ucname = $(shell echo $(1) | sed -e 's/\(.*\)_config/\U\1/')
- #########################################################################
- ## ARM1176 Systems
- #########################################################################
- smdk6400_noUSB_config \
- smdk6400_config : unconfig
- @mkdir -p $(obj)include $(obj)board/samsung/smdk6400
- @mkdir -p $(obj)nand_spl/board/samsung/smdk6400
- @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
- @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
- @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \
- echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
- else \
- echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
- fi
- @$(MKCONFIG) smdk6400 arm arm1176 smdk6400 samsung s3c64xx
- @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
-
#########################################################################
#########################################################################
$(obj)tools/mk{smdk5250,}spl \
$(obj)tools/mxsboot \
$(obj)tools/ncb $(obj)tools/ubsha1 \
- $(obj)tools/kernel-doc/docproc
+ $(obj)tools/kernel-doc/docproc \
+ $(obj)tools/proftool
@rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \
$(obj)board/matrix_vision/*/bootscript.img \
$(obj)board/voiceblue/eeprom \
$(obj)u-boot.lds \
- $(obj)include/u-boot.lst \
$(obj)arch/blackfin/cpu/bootrom-asm-offsets.[chs] \
$(obj)arch/blackfin/cpu/init.{lds,elf}
@rm -f $(obj)include/bmp_logo.h
@$(MAKE) -s -C doc/DocBook/ cleandocs
@find $(OBJTREE) -type f \
\( -name 'core' -o -name '*.bak' -o -name '*~' -o -name '*.su' \
- -o -name '*.o' -o -name '*.a' -o -name '*.exe' \) -print \
+ -o -name '*.o' -o -name '*.a' -o -name '*.exe' \
+ -o -name '*.cfgtmp' \) -print \
| xargs rm -f
# Removes everything not needed for testing u-boot
@rm -f $(obj)u-boot.kwb
@rm -f $(obj)u-boot.pbl
@rm -f $(obj)u-boot.imx
+ @rm -f $(obj)u-boot-with-spl.imx
+ @rm -f $(obj)u-boot-with-nand-spl.imx
@rm -f $(obj)u-boot.ubl
@rm -f $(obj)u-boot.ais
@rm -f $(obj)u-boot.dtb
@rm -f $(obj)u-boot.sb
+ @rm -f $(obj)u-boot.bd
@rm -f $(obj)u-boot.spr
@rm -f $(obj)nand_spl/{u-boot.{lds,lst},System.map}
@rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map}
@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map}
- @rm -f $(obj)spl/{u-boot-spl.lds,u-boot.lst}
+ @rm -f $(obj)spl/u-boot-spl.lds
@rm -f $(obj)MLO MLO.byteswap
@rm -f $(obj)SPL
@rm -f $(obj)tools/xway-swap-bytes
/*
- * Freescale i.MX28 clock setup code
+ * 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 Freescale Semiconductor, Inc.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
- /* The PLL frequency is always 480MHz, see section 10.2 in iMX28 datasheet. */
+ /*
+ * 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
- /* The XTAL frequency is always 24MHz, see section 10.2 in iMX28 datasheet. */
#define XTAL_FREQ_KHZ 24000
#define PLL_FREQ_MHZ (PLL_FREQ_KHZ / 1000)
#define XTAL_FREQ_MHZ (XTAL_FREQ_KHZ / 1000)
-static uint32_t mxs_get_pclk(void)
+ #if defined(CONFIG_MX23)
+ #define MXC_SSPCLK_MAX MXC_SSPCLK0
+ #elif defined(CONFIG_MX28)
+ #define MXC_SSPCLK_MAX MXC_SSPCLK3
+ #endif
+
+static struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+
+static uint32_t get_frac_clk(uint32_t refclk, uint32_t div, uint32_t _mask)
{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t mask = (_mask + 1) >> 1;
+ uint32_t acc = div;
+ int period = 0;
+ int mult = 0;
+
+ if (div & mask)
+ return 0;
+
+ do {
+ acc += div;
+ if (acc & mask) {
+ acc &= ~mask;
+ mult++;
+ }
+ period++;
+ } while (acc != div);
- static uint32_t mx28_get_pclk(void)
+ return refclk * mult / period;
+}
+
++static uint32_t mxs_get_pclk(void)
+{
uint32_t clkctrl, clkseq, div;
uint8_t clkfrac, frac;
clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu);
- /* No support of fractional divider calculation */
+ div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
+ clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+ frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+
if (clkctrl &
(CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) {
- return 0;
+ uint32_t refclk, mask;
+
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
+ refclk = XTAL_FREQ_MHZ;
+ mask = CLKCTRL_CPU_DIV_XTAL_MASK >>
+ CLKCTRL_CPU_DIV_XTAL_OFFSET;
+ div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
+ CLKCTRL_CPU_DIV_XTAL_OFFSET;
+ } else {
+ refclk = PLL_FREQ_MHZ * PLL_FREQ_COEF / frac;
+ mask = CLKCTRL_CPU_DIV_CPU_MASK;
+ }
+ return get_frac_clk(refclk, div, mask);
}
- clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
-
/* XTAL Path */
if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
}
/* 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 mx28_get_hclk(void)
+ 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;
- uint32_t refclk = mx28_get_pclk();
++ uint32_t refclk = mxs_get_pclk();
clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus);
+ div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
- /* No support of fractional divider calculation */
if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN)
- return 0;
+ return get_frac_clk(refclk, div, CLKCTRL_HBUS_DIV_MASK);
- div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
- return mxs_get_pclk() / div;
+ return refclk / div;
}
- static uint32_t mx28_get_emiclk(void)
+ 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;
return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
}
- static uint32_t mx28_get_gpmiclk(void)
+ 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;
}
/* REF Path */
- clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac1[CLKCTRL_FRAC1_GPMI]);
+ 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 mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq)
+ 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;
/*
* Get IO clock, returns IO clock in kHz
*/
- static uint32_t mx28_get_ioclk(enum mxs_ioclock io)
+ 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))
+ if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) {
+ printf("%s: IO clock selector %u out of range %u..%u\n",
+ __func__, io, MXC_IOCLK0, MXC_IOCLK1);
return 0;
-
+ }
io_reg = CLKCTRL_FRAC0_IO0 - io; /* Register order is reversed */
ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) &
/*
* Configure SSP clock frequency, in kHz
*/
- void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
+ 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_SSPCLK3)
+ if (ssp > MXC_SSPCLK_MAX)
return;
clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
if (xtal)
clk = XTAL_FREQ_KHZ;
else
- clk = mx28_get_ioclk(ssp >> 1);
+ clk = mxs_get_ioclk(ssp >> 1);
if (freq > clk)
return;
/*
* Return SSP frequency, in kHz
*/
- static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
+ 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 *clkreg;
uint32_t clk, tmp;
- if (ssp > MXC_SSPCLK3)
+ 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));
+ clkreg = &clkctrl_regs->hw_clkctrl_ssp0 +
+ ssp * sizeof(struct mxs_register_32);
tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
-
if (tmp == 0)
return 0;
- clk = mx28_get_ioclk(ssp >> 1);
+ clk = mxs_get_ioclk(ssp >> 1);
+
return clk / tmp;
}
/*
* Set SSP/MMC bus frequency, in kHz)
*/
- void mx28_set_ssp_busclock(unsigned int bus, uint32_t freq)
+ void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq)
{
struct mxs_ssp_regs *ssp_regs;
- const uint32_t sspclk = mx28_get_sspclk(bus);
+ 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 = (struct mxs_ssp_regs *)(MXS_SSP0_BASE + (bus * 0x2000));
+ ssp_regs = mxs_ssp_regs_by_bus(bus);
/*
* SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)),
bus, tgtclk, freq);
}
- static uint32_t mx28_get_xbus_clk(void)
+ void mxs_set_lcdclk(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
+ }
+
++static uint32_t mxs_get_xbus_clk(void)
+{
- struct mxs_clkctrl_regs *clkctrl_regs =
- (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t div;
+ uint32_t clkctrl;
- uint32_t refclk = mx28_get_pclk();
++ uint32_t refclk = mxs_get_pclk();
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_xbus);
+ div = clkctrl & CLKCTRL_XBUS_DIV_MASK;
+
+ if (clkctrl & CLKCTRL_XBUS_DIV_FRAC_EN)
+ return get_frac_clk(refclk, div, CLKCTRL_XBUS_DIV_MASK);
+
+ return refclk / div;
+}
+
uint32_t mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
case MXC_ARM_CLK:
- return mx28_get_pclk() * 1000000;
+ return mxs_get_pclk() * 1000000;
case MXC_GPMI_CLK:
- return mx28_get_gpmiclk() * 1000000;
+ return mxs_get_gpmiclk() * 1000000;
case MXC_AHB_CLK:
case MXC_IPG_CLK:
- return mx28_get_hclk() * 1000000;
+ return mxs_get_hclk() * 1000000;
case MXC_EMI_CLK:
- return mx28_get_emiclk();
+ return mxs_get_emiclk();
case MXC_IO0_CLK:
- return mx28_get_ioclk(MXC_IOCLK0);
+ return mxs_get_ioclk(MXC_IOCLK0);
case MXC_IO1_CLK:
- return mx28_get_ioclk(MXC_IOCLK1);
+ return mxs_get_ioclk(MXC_IOCLK1);
+ case MXC_XTAL_CLK:
+ return XTAL_FREQ_KHZ * 1000;
case MXC_SSP0_CLK:
- return mx28_get_sspclk(MXC_SSPCLK0);
+ return mxs_get_sspclk(MXC_SSPCLK0);
+ #ifdef CONFIG_MX28
case MXC_SSP1_CLK:
- return mx28_get_sspclk(MXC_SSPCLK1);
+ return mxs_get_sspclk(MXC_SSPCLK1);
case MXC_SSP2_CLK:
- return mx28_get_sspclk(MXC_SSPCLK2);
+ return mxs_get_sspclk(MXC_SSPCLK2);
case MXC_SSP3_CLK:
- return mx28_get_sspclk(MXC_SSPCLK3);
- case MXC_XTAL_CLK:
- return XTAL_FREQ_KHZ * 1000;
+ return mxs_get_sspclk(MXC_SSPCLK3);
+ #endif
+ case MXC_XBUS_CLK:
- return mx28_get_xbus_clk() * 1000000;
++ return mxs_get_xbus_clk() * 1000000;
+ default:
+ printf("Invalid clock selector %u\n", clk);
}
return 0;
/*
- * Freescale i.MX28 common code
+ * 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.
*
- * 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
+ * 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/dma.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;
- /* 1 second delay should be plenty of time for block reset. */
- #define RESET_MAX_TIMEOUT 1000000
-
- #define MXS_BLOCK_SFTRST (1 << 31)
- #define MXS_BLOCK_CLKGATE (1 << 30)
-
/* Lowlevel init isn't used on i.MX28, so just have a dummy here */
inline void lowlevel_init(void) {}
#endif
}
- #define MX28_HW_DIGCTL_MICROSECONDS (void *)0x8001c0c0
-
- int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
- int timeout)
- {
- uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
-
- /* Wait for at least one microsecond for the bit mask to be set */
- while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
- if ((readl(®->reg) & mask) == mask) {
- while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
- ;
- return 0;
- }
- udelay(1);
- }
-
- return !timeout;
- }
-
- int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
- int timeout)
- {
- uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
-
- /* Wait for at least one microsecond for the bit mask to be cleared */
- while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
- if ((readl(®->reg) & mask) == 0) {
- while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
- ;
- return 0;
- }
- udelay(1);
- }
-
- return !timeout;
- }
-
- int mxs_reset_block(struct mxs_register_32 *reg)
- {
- /* Clear SFTRST */
- writel(MXS_BLOCK_SFTRST, ®->reg_clr);
-
- if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
- printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
- reg, readl(®->reg));
- return 1;
- }
-
- /* Clear CLKGATE */
- writel(MXS_BLOCK_CLKGATE, ®->reg_clr);
-
- /* Set SFTRST */
- writel(MXS_BLOCK_SFTRST, ®->reg_set);
-
- /* Wait for CLKGATE being set */
- if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
- printf("TIMEOUT waiting for CLKGATE[%p] to set: %08x\n",
- reg, readl(®->reg));
- return 1;
- }
-
- /* Clear SFTRST */
- writel(MXS_BLOCK_SFTRST, ®->reg_clr);
-
- if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
- printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
- reg, readl(®->reg));
- return 1;
- }
-
- /* Clear CLKGATE */
- writel(MXS_BLOCK_CLKGATE, ®->reg_clr);
-
- if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
- printf("TIMEOUT waiting for CLKGATE[%p] to clear: %08x\n",
- reg, readl(®->reg));
- return 1;
- }
-
- return 0;
- }
-
+ /*
+ * 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)
{
- uint32_t *vt = (uint32_t *)0x20;
+ /* 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++)
- vt[i] = start_addr + (4 * i);
+ for (i = 0; i < 8; i++) {
+ vt[i] = ldr_pc;
+ vt[i + 8] = start_addr + (4 * i);
+ }
}
#ifdef CONFIG_ARCH_MISC_INIT
}
#endif
- #ifdef CONFIG_ARCH_CPU_INIT
+ #ifdef CONFIG_ARCH_CPU_INIT
int arch_cpu_init(void)
{
struct mxs_clkctrl_regs *clkctrl_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:
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:
}
#endif
+#define pr_clk(n, c) { \
+ unsigned long clk = c; \
+ printf("%-5s %3lu.%03lu MHz\n", #n ":", clk / 1000000, \
+ clk / 1000 % 1000); \
+}
+
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);
+ pr_clk(CPU, mxc_get_clock(MXC_ARM_CLK));
+ pr_clk(APBH, mxc_get_clock(MXC_AHB_CLK));
+ pr_clk(APBX, mxc_get_clock(MXC_XBUS_CLK));
+ pr_clk(IO0, mxc_get_clock(MXC_IO0_CLK) * 1000);
+ pr_clk(IO1, mxc_get_clock(MXC_IO1_CLK) * 1000);
+ pr_clk(EMI, mxc_get_clock(MXC_EMI_CLK) * 1000000);
+ pr_clk(GPMI, mxc_get_clock(MXC_GPMI_CLK));
return 0;
}
}
#endif
- static void __mx28_adjust_mac(int dev_id, unsigned char *mac)
+ __weak void mx28_adjust_mac(int dev_id, unsigned char *mac)
{
mac[0] = 0x00;
mac[1] = 0x04; /* Use FSL vendor MAC address by default */
mac[5] += 1;
}
- void mx28_adjust_mac(int dev_id, unsigned char *mac)
- __attribute__((weak, alias("__mx28_adjust_mac")));
-
#ifdef CONFIG_MX28_FEC_MAC_IN_OCOTP
#define MXS_OCOTP_MAX_TIMEOUT 1000000
* Based on code from LTIB:
* (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
/* Maximum fixed count */
- #define TIMER_LOAD_VAL 0xffffffff
+ #if defined(CONFIG_MX23)
+ #define TIMER_LOAD_VAL 0xffff
+ #elif defined(CONFIG_MX28)
+ #define TIMER_LOAD_VAL 0xffffffff
+ #endif
DECLARE_GLOBAL_DATA_PTR;
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 */
++ /* Set fixed_count to maximum 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
+
#ifndef DEBUG_TIMER_WRAP
/* Set fixed_count to maximum value */
writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
writel(20 * MXS_INCREMENTER_HZ,
&timrot_regs->hw_timrot_fixed_count0);
gd->arch.lastinc = TIMER_LOAD_VAL - 20 * MXS_INCREMENTER_HZ;
--#endif
--#ifdef DEBUG_TIMER_WRAP
++
/* Make the usec counter roll over 30 seconds after startup */
writel(-30000000, MXS_HW_DIGCTL_MICROSECONDS);
#endif
{
struct mxs_timrot_regs *timrot_regs =
(struct mxs_timrot_regs *)MXS_TIMROT_BASE;
+ unsigned long now;
+ #if defined(CONFIG_MX23)
+ /* Upper bits are the valid ones. */
+ now = readl(&timrot_regs->hw_timrot_timcount0) >>
+ TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET;
+ #else
/* The timer is counting down, so subtract the register value from
- * the counter period length to get an incrementing timestamp
+ * the counter period length (implicitly 2^32) to get an incrementing
+ * timestamp
*/
- unsigned long now = -readl(&timrot_regs->hw_timrot_running_count0);
+ now = -readl(&timrot_regs->hw_timrot_running_count0);
+ #endif
ulong inc = now - gd->arch.lastinc;
+ if (gd->arch.tbl + inc < gd->arch.tbl)
+ gd->arch.tbu++;
gd->arch.tbl += inc;
gd->arch.lastinc = now;
- /* Since the get_timer() function only uses a 32bit value
- * it doesn't make sense to return a real 64 bit value here.
- */
- return gd->arch.tbl;
+ return ((unsigned long long)gd->arch.tbu << 32) | gd->arch.tbl;
}
ulong get_timer_masked(void)
*
* 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; 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
- /*
- * This is used to verify if the configuration header
- * was executed by rom code prior to control of transfer
- * to the bootloader. SPL is responsible for saving and
- * passing the boot_params pointer to the u-boot.
- */
- struct omap_boot_parameters boot_params __attribute__ ((section(".data")));
+ DECLARE_GLOBAL_DATA_PTR;
- #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 omap_bootmode __attribute__ ((section(".data"))) = MMCSD_MODE_UNDEFINED;
+ 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.
+ */
+ gd->arch.omap_boot_params.omap_bootdevice = boot_device =
+ *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
+
+ 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)
+ 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));
+ }
+ }
+ }
+
+ #ifdef CONFIG_SPL_BUILD
u32 spl_boot_device(void)
{
- return boot_params.omap_bootdevice;
- return (u32) (gd->arch.omap_boot_params.omap_bootdevice);
++ return gd->arch.omap_boot_params.omap_bootdevice;
}
u32 spl_boot_mode(void)
{
- return omap_bootmode;
+ return gd->arch.omap_boot_params.omap_bootmode;
}
void spl_board_init(void)
#ifdef CONFIG_SPL_NAND_SUPPORT
gpmc_init();
#endif
+ #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
+ arch_misc_init();
+ #endif
}
int board_mmc_init(bd_t *bis)
{
switch (spl_boot_device()) {
case BOOT_DEVICE_MMC1:
- omap_mmc_init(0, 0, 0);
+ omap_mmc_init(0, 0, 0, -1, -1);
break;
case BOOT_DEVICE_MMC2:
case BOOT_DEVICE_MMC2_2:
- omap_mmc_init(1, 0, 0);
+ 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
*
* (C) Copyright 2009 Freescale Semiconductor, Inc.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
- #define DEBUG_TIMER_WRAP
-
/* General purpose timers registers */
struct mxc_gpt {
unsigned int control;
/* General purpose timers bitfields */
#define GPTCR_SWR (1 << 15) /* Software reset */
#define GPTCR_FRR (1 << 9) /* Freerun / restart */
- #define GPTCR_CLKSOURCE_IPG (1 << 6) /* Clock source */
- #define GPTCR_CLKSOURCE_CKIH (2 << 6)
- #define GPTCR_CLKSOURCE_32kHz (4 << 6)
- #if defined(CONFIG_MX6Q)
- #define GPTCR_CLKSOURCE_OSCDIV8 (5 << 6)
- #define GPTCR_CLKSOURCE_OSC (7 << 6)
- #elif defined(CONFIG_MX6DL)
- #define GPTCR_M24EN (1 << 10)
- #define GPTCR_CLKSOURCE_OSC ((5 << 6) | GPTCR_M24EN)
- #else
- #define GPTCR_CLKSOURCE_OSC (5 << 6)
- #endif
- #define GPTCR_CLKSOURCE_MASK (7 << 6)
+ #define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
#define GPTCR_TEN 1 /* Timer enable */
- #if 1
- #define GPT_CLKSOURCE GPTCR_CLKSOURCE_OSC
- #define GPT_REFCLK 24000000
- #define GPT_PRESCALER 24
- #else
- #define GPT_CLKSOURCE GPTCR_CLKSOURCE_32kHz
- #define GPT_REFCLK 32768
- #define GPT_PRESCALER 1
- #endif
- #define GPT_CLK (GPT_REFCLK / GPT_PRESCALER)
-
- #ifdef DEBUG_TIMER_WRAP
- /*
- * Let the timer wrap 30 seconds after start to catch misbehaving
- * timer related code early
- */
- #define TIMER_START (-time_to_tick(30 * CONFIG_SYS_HZ))
- #else
- #define TIMER_START 0UL
- #endif
-
DECLARE_GLOBAL_DATA_PTR;
- static inline unsigned long tick_to_time(unsigned long tick)
+ static inline unsigned long long tick_to_time(unsigned long long tick)
{
- unsigned long long t = (unsigned long long)tick * CONFIG_SYS_HZ;
- do_div(t, GPT_CLK);
- return t;
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, MXC_CLK32);
-
+ return tick;
}
- ticks *= GPT_CLK;
+static inline unsigned long time_to_tick(unsigned long time)
+{
+ unsigned long long ticks = (unsigned long long)time;
+
- static inline unsigned long us_to_tick(unsigned long usec)
++ ticks *= MXC_CLK32;
+ do_div(ticks, CONFIG_SYS_HZ);
+ return ticks;
+}
+
+ static inline unsigned long long us_to_tick(unsigned long long usec)
{
- unsigned long long ticks = (unsigned long long)usec;
+ usec = usec * MXC_CLK32 + 999999;
+ do_div(usec, 1000000);
- ticks *= GPT_CLK;
- do_div(ticks, 1000 * CONFIG_SYS_HZ);
- return ticks;
+ return usec;
}
int timer_init(void)
for (i = 0; i < 100; i++)
__raw_writel(0, &cur_gpt->control);
- __raw_writel(GPT_PRESCALER - 1, &cur_gpt->prescaler);
+ __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
/* Freerun Mode, PERCLK1 input */
i = __raw_readl(&cur_gpt->control);
- i &= ~GPTCR_CLKSOURCE_MASK;
- __raw_writel(i | GPT_CLKSOURCE | GPTCR_TEN, &cur_gpt->control);
+ __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
- gd->arch.lastinc = __raw_readl(&cur_gpt->counter);
+ gd->arch.tbl = __raw_readl(&cur_gpt->counter);
gd->arch.tbu = 0;
- gd->arch.tbl = TIMER_START;
- gd->arch.timer_rate_hz = GPT_CLK;
+ gd->arch.timer_rate_hz = MXC_CLK32;
return 0;
}
unsigned long long get_ticks(void)
{
ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */
- ulong inc = now - gd->arch.lastinc;
- gd->arch.tbl += inc;
- gd->arch.lastinc = now;
- return gd->arch.tbl;
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
}
ulong get_timer_masked(void)
* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
* 5 * 10^6 days - long enough.
*/
+ /*
+ * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
+ * Thus the calculation above is not true.
+ * A 64bit timer value would only make sense if it was
+ * consistently used throughout the code. Thus also the parameter
+ * to get_timer() and its return value would need to be 64bit wide!
+ */
return tick_to_time(get_ticks());
}
ulong get_timer(ulong base)
{
- return get_timer_masked() - base;
+ return tick_to_time(get_ticks() - time_to_tick(base));
}
- #include <asm/gpio.h>
-
/* delay x useconds AND preserve advance timstamp value */
void __udelay(unsigned long usec)
{
- unsigned long long tmp;
- ulong tmo;
+ unsigned long start = __raw_readl(&cur_gpt->counter);
+ unsigned long ticks;
+
+ if (usec == 0)
+ return;
- tmo = us_to_tick(usec);
- tmp = get_ticks() + tmo; /* get current timestamp */
+ ticks = us_to_tick(usec);
+ if (ticks == 0)
+ ticks++;
- while (get_ticks() < tmp) /* loop till event */
- /*NOP*/;
+ while (__raw_readl(&cur_gpt->counter) - start < ticks)
+ /* loop till event */;
}
/*
/*
- * Freescale i.MX28 Clock
+ * Freescale i.MX23/i.MX28 Clock
*
* Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
* on behalf of DENX Software Engineering GmbH
*
- * 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
- *
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __CLOCK_H__
MXC_GPMI_CLK,
MXC_IO0_CLK,
MXC_IO1_CLK,
+ MXC_XTAL_CLK,
MXC_SSP0_CLK,
+ #ifdef CONFIG_MX28
MXC_SSP1_CLK,
MXC_SSP2_CLK,
MXC_SSP3_CLK,
- MXC_XTAL_CLK,
+ #endif
+ MXC_XBUS_CLK,
};
enum mxs_ioclock {
enum mxs_sspclock {
MXC_SSPCLK0 = 0,
+ #ifdef CONFIG_MX28
MXC_SSPCLK1,
MXC_SSPCLK2,
MXC_SSPCLK3,
+ #endif
};
uint32_t mxc_get_clock(enum mxc_clock clk);
- void mx28_set_ioclk(enum mxs_ioclock io, uint32_t freq);
- void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal);
- void mx28_set_ssp_busclock(unsigned int bus, uint32_t freq);
+ void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq);
+ void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal);
+ void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq);
+ void mxs_set_lcdclk(uint32_t freq);
/* Compatibility with the FEC Ethernet driver */
#define imx_get_fecclk() mxc_get_clock(MXC_AHB_CLK)
* Based on code from LTIB:
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*
- * 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
- *
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __MX28_REGS_SSP_H__
#define __MX28_REGS_SSP_H__
- #include <asm/arch/regs-common.h>
+ #include <asm/imx-common/regs-common.h>
#ifndef __ASSEMBLY__
- mxs_reg_32(hw_ssp_ctrl0)
- mxs_reg_32(hw_ssp_cmd0)
- mxs_reg_32(hw_ssp_cmd1)
- mxs_reg_32(hw_ssp_compref)
- mxs_reg_32(hw_ssp_compmask)
- mxs_reg_32(hw_ssp_timing)
- mxs_reg_32(hw_ssp_ctrl1)
- mxs_reg_32(hw_ssp_data)
- mxs_reg_32(hw_ssp_sdresp0)
- mxs_reg_32(hw_ssp_sdresp1)
- mxs_reg_32(hw_ssp_sdresp2)
- mxs_reg_32(hw_ssp_sdresp3)
- mxs_reg_32(hw_ssp_status)
-
- uint32_t reserved1[12];
-
- mxs_reg_32(hw_ssp_debug)
- mxs_reg_32(hw_ssp_version)
+ #if defined(CONFIG_MX23)
+ struct mxs_ssp_regs {
++ mxs_reg_32(hw_ssp_ctrl0);
++ mxs_reg_32(hw_ssp_cmd0);
++ mxs_reg_32(hw_ssp_cmd1);
++ mxs_reg_32(hw_ssp_compref);
++ mxs_reg_32(hw_ssp_compmask);
++ mxs_reg_32(hw_ssp_timing);
++ mxs_reg_32(hw_ssp_ctrl1);
++ mxs_reg_32(hw_ssp_data);
++ mxs_reg_32(hw_ssp_sdresp0);
++ mxs_reg_32(hw_ssp_sdresp1);
++ mxs_reg_32(hw_ssp_sdresp2);
++ mxs_reg_32(hw_ssp_sdresp3);
++ mxs_reg_32(hw_ssp_status);
++ reg_32(reserved[3]);
++ mxs_reg_32(hw_ssp_debug);
++ mxs_reg_32(hw_ssp_version);
+ };
+ #elif defined(CONFIG_MX28)
struct mxs_ssp_regs {
mxs_reg_32(hw_ssp_ctrl0);
mxs_reg_32(hw_ssp_cmd0);
};
#endif
+ static inline int mxs_ssp_bus_id_valid(int bus)
+ {
+ #if defined(CONFIG_MX23)
+ const unsigned int mxs_ssp_chan_count = 2;
+ #elif defined(CONFIG_MX28)
+ const unsigned int mxs_ssp_chan_count = 4;
+ #endif
+
+ if (bus >= mxs_ssp_chan_count)
+ return 0;
+
+ if (bus < 0)
+ return 0;
+
+ return 1;
+ }
+
+ static inline int mxs_ssp_clock_by_bus(unsigned int clock)
+ {
+ #if defined(CONFIG_MX23)
+ return 0;
+ #elif defined(CONFIG_MX28)
+ return clock;
+ #endif
+ }
+
+ static inline struct mxs_ssp_regs *mxs_ssp_regs_by_bus(unsigned int port)
+ {
+ switch (port) {
+ case 0:
+ return (struct mxs_ssp_regs *)MXS_SSP0_BASE;
+ case 1:
+ return (struct mxs_ssp_regs *)MXS_SSP1_BASE;
+ #ifdef CONFIG_MX28
+ case 2:
+ return (struct mxs_ssp_regs *)MXS_SSP2_BASE;
+ case 3:
+ return (struct mxs_ssp_regs *)MXS_SSP3_BASE;
+ #endif
+ default:
+ return NULL;
+ }
+ }
+ #endif
+
#define SSP_CTRL0_SFTRST (1 << 31)
#define SSP_CTRL0_CLKGATE (1 << 30)
#define SSP_CTRL0_RUN (1 << 29)
#define SSP_CTRL0_GET_RESP (1 << 17)
#define SSP_CTRL0_ENABLE (1 << 16)
+ #ifdef CONFIG_MX23
+ #define SSP_CTRL0_XFER_COUNT_OFFSET 0
+ #define SSP_CTRL0_XFER_COUNT_MASK 0xffff
+ #endif
+
#define SSP_CMD0_SOFT_TERMINATE (1 << 26)
#define SSP_CMD0_DBL_DATA_RATE_EN (1 << 25)
#define SSP_CMD0_PRIM_BOOT_OP_EN (1 << 24)
#define SSP_CMD0_SLOW_CLKING_EN (1 << 22)
#define SSP_CMD0_CONT_CLKING_EN (1 << 21)
#define SSP_CMD0_APPEND_8CYC (1 << 20)
+ #if defined(CONFIG_MX23)
+ #define SSP_CMD0_BLOCK_SIZE_MASK (0xf << 16)
+ #define SSP_CMD0_BLOCK_SIZE_OFFSET 16
+ #define SSP_CMD0_BLOCK_COUNT_MASK (0xff << 8)
+ #define SSP_CMD0_BLOCK_COUNT_OFFSET 8
+ #endif
#define SSP_CMD0_CMD_MASK 0xff
#define SSP_CMD0_CMD_OFFSET 0
#define SSP_CMD0_CMD_MMC_GO_IDLE_STATE 0x00
#define SSP_CMD1_CMD_ARG_MASK 0xffffffff
#define SSP_CMD1_CMD_ARG_OFFSET 0
+ #if defined(CONFIG_MX28)
#define SSP_XFER_SIZE_XFER_COUNT_MASK 0xffffffff
#define SSP_XFER_SIZE_XFER_COUNT_OFFSET 0
#define SSP_BLOCK_SIZE_BLOCK_COUNT_OFFSET 4
#define SSP_BLOCK_SIZE_BLOCK_SIZE_MASK 0xf
#define SSP_BLOCK_SIZE_BLOCK_SIZE_OFFSET 0
+ #endif
#define SSP_COMPREF_REFERENCE_MASK 0xffffffff
#define SSP_COMPREF_REFERENCE_OFFSET 0
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
/*
#include <fdtdec.h>
#include <post.h>
#include <logbuff.h>
+ #include <asm/sections.h>
#ifdef CONFIG_BITBANGMII
#include <miiphy.h>
#endif
#if defined(CONFIG_HARD_I2C) || \
- defined(CONFIG_SOFT_I2C)
+ defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
* has the disadvantage that you either get nothing, or everything.
* On PowerPC, you might see "DRAM: " before the system hangs - which
* gives a simple yet clear indication which part of the
- * initialization is failing.
+ * initialization if failing.
*/
static int display_dram_config(void)
{
return (0);
}
- #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+ #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
static int init_func_i2c(void)
{
puts("I2C: ");
+ #ifdef CONFIG_SYS_I2C
+ i2c_init_all();
+ #else
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ #endif
puts("ready\n");
return (0);
}
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
- #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+ #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
gd->relocaddr = addr;
gd->start_addr_sp = addr_sp;
gd->reloc_off = addr - _TEXT_BASE;
+
debug("relocation Offset is: %08lx\n", gd->reloc_off);
if (new_fdt) {
memcpy(new_fdt, gd->fdt_blob, fdt_size);
debug("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */
/*
- * TODO: printing of the clock inforamtion of the board is now
+ * TODO: printing of the clock information of the board is now
* implemented as part of bdinfo command. Currently only support for
* davinci SOC's is added. Remove this check once all the board
* implement this.
/* NOTREACHED - no way out of command loop except booting */
}
-
- void hang(void)
- {
- puts("### ERROR ### Please RESET the board ###\n");
- for (;;);
- }
int off;
int ret;
const uint32_t *ph;
+ int disable_otg = 0;
+ int disable_phy_pins = 1;
debug("OTG mode is '%s'\n", otg_mode ? otg_mode : "<UNSET>");
if (otg_mode && (strcmp(otg_mode, "device") == 0 ||
strcmp(otg_mode, "gadget") == 0)) {
+ debug("Setting dr_mode to 'peripheral'\n");
ret = fdt_setprop_string(blob, off, "dr_mode", "peripheral");
- phy = NULL;
} else if (otg_mode && strcmp(otg_mode, "host") == 0) {
+ debug("Setting dr_mode to 'host'\n");
ret = fdt_setprop_string(blob, off, "dr_mode", "host");
- phy = NULL;
+ disable_phy_pins = 0;
+ } else if (otg_mode && strcmp(otg_mode, "otg") == 0) {
+ debug("Setting dr_mode to 'host'\n");
+ ret = fdt_setprop_string(blob, off, "dr_mode", "otg");
} else {
if (otg_mode && strcmp(otg_mode, "none") != 0)
printf("Invalid 'otg_mode' setting '%s'; disabling usbotg port\n",
otg_mode);
- ret = fdt_setprop_string(blob, off, "status", "disabled");
+ disable_otg = 1;
+ ret = 0;
}
- if (ret)
- goto out;
- if (phy == NULL)
+ if ((!disable_phy_pins && !disable_otg) || ret)
goto out;
+ if (disable_otg) {
+ ret = fdt_setprop_string(blob, off, "status", "disabled");
+ if (ret)
+ goto out;
+ }
+
ph = fdt_getprop(blob, off, phy, NULL);
if (ph == NULL) {
printf("Failed to find '%s' phandle in node '%s'\n", phy,
phy, fdt32_to_cpu(*ph));
goto out;
}
- ret = fdt_setprop_string(blob, off, "status", "disabled");
+ if (disable_otg) {
+ debug("Disabling usbphy\n");
+ ret = fdt_setprop_string(blob, off, "status", "disabled");
+ } else {
+ debug("Removing host pins from usbphy\n");
+ ret = fdt_delprop(blob, off, "pinctrl-0");
+ }
out:
if (ret)
printf("Failed to update usbotg: %d\n", ret);
- printf("node '%s' updated\n", node);
+ else
+ debug("node '%s' updated\n", node);
karo_set_fdtsize(blob);
}
const char *subnode = "display-timings";
if (off < 0) {
- printf("Could not find node 'display' in FDT: %d\n", off);
+ debug("Could not find node 'display' in FDT: %d\n", off);
return off;
}
off = fdt_subnode_offset(blob, off, subnode);
if (off < 0) {
- printf("Could not find node '%s' in FDT: %d\n", subnode, off);
+ debug("Could not find node '%s' in FDT: %d\n", subnode, off);
}
return off;
}
off = fdt_next_node(blob, off, &d);
if (d > 2) {
- printf("Skipping node @ %04x %s depth %d\n", off, fdt_get_name(blob, off, NULL), d);
+ debug("Skipping node @ %04x %s depth %d\n", off, fdt_get_name(blob, off, NULL), d);
continue;
}
debug("parsing subnode @ %04x %s depth %d\n", off, fdt_get_name(blob, off, NULL), d);
off = fdt_subnode_offset(blob, off, subnode);
if (off < 0) {
- printf("Could not find node '%s' in FDT: %d\n", subnode, off);
+ debug("Could not find node '%s' in FDT: %d\n", subnode, off);
}
do {
const char *n, *endp;
int do_del;
if (d > 2) {
- printf("Skipping node @ %04x %s depth %d\n", node, fdt_get_name(blob, node, NULL), d);
+ debug("Skipping node @ %04x %s depth %d\n", node, fdt_get_name(blob, node, NULL), d);
continue;
}
debug("parsing subnode @ %04x %s depth %d\n", node, fdt_get_name(blob, node, NULL), d);
struct mtd_device *dev;
struct part_info *part_info;
u8 part_num;
+ size_t actual;
debug("Initializing mtd_parts\n");
ret = mtdparts_init();
len = part_info->size;
}
debug("Reading NAND partition '%s' to %p\n", part, addr);
- ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len, addr);
+ ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len,
+ &actual, len, addr);
if (ret) {
printf("Failed to load partition '%s' to %p\n", part, addr);
return ret;
}
+ if (actual < len)
+ printf("Read only %u of %u bytes due to bad blocks\n",
+ actual, len);
+
debug("Read %u byte from partition '%s' @ offset %08x\n",
len, part, part_info->offset);
return 0;
* 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 <lcd.h>
#include <netdev.h>
#include <mmc.h>
- #include <imx_ssp_mmc.h>
#include <linux/list.h>
#include <linux/fb.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/iomux-mx28.h>
#include <asm/arch/clock.h>
- #include <asm/arch/mxsfb.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
}
}
+#define RTC_PERSISTENT0_CLK32_MASK (RTC_PERSISTENT0_CLOCKSOURCE | \
+ RTC_PERSISTENT0_XTAL32KHZ_PWRUP)
+static u32 boot_cause __attribute__((section("data")));
+
int board_early_init_f(void)
{
+ struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+ u32 rtc_stat;
+ int timeout = 5000;
+
random_init();
/* IO0 clock at 480MHz */
- mx28_set_ioclk(MXC_IOCLK0, 480000);
+ mxs_set_ioclk(MXC_IOCLK0, 480000);
/* IO1 clock at 480MHz */
- mx28_set_ioclk(MXC_IOCLK1, 480000);
+ mxs_set_ioclk(MXC_IOCLK1, 480000);
/* SSP0 clock at 96MHz */
- mx28_set_sspclk(MXC_SSPCLK0, 96000, 0);
+ mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
/* SSP2 clock at 96MHz */
- mx28_set_sspclk(MXC_SSPCLK2, 96000, 0);
+ mxs_set_sspclk(MXC_SSPCLK2, 96000, 0);
gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
mxs_iomux_setup_multiple_pads(tx28_pads, ARRAY_SIZE(tx28_pads));
+
+ while ((rtc_stat = readl(&rtc_regs->hw_rtc_stat)) &
+ RTC_STAT_STALE_REGS_PERSISTENT0) {
+ if (timeout-- < 0)
+ return 0;
+ udelay(1);
+ }
+ boot_cause = readl(&rtc_regs->hw_rtc_persistent0);
+ if ((boot_cause & RTC_PERSISTENT0_CLK32_MASK) !=
+ RTC_PERSISTENT0_CLK32_MASK) {
+ if (boot_cause & RTC_PERSISTENT0_CLOCKSOURCE)
+ goto rtc_err;
+ writel(RTC_PERSISTENT0_CLK32_MASK,
+ &rtc_regs->hw_rtc_persistent0_set);
+ }
+ return 0;
+
+rtc_err:
+ serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
return 0;
}
int board_mmc_init(bd_t *bis)
{
- return mxsmmc_initialize(bis, 0, tx28_mmc_wp);
+ return mxsmmc_initialize(bis, 0, tx28_mmc_wp, NULL);
}
#endif /* CONFIG_CMD_MMC */
#else
#define FEC_MAX_IDX 0
#endif
+ #ifndef ETH_ALEN
+ #define ETH_ALEN 6
+ #endif
static int fec_get_mac_addr(int index)
{
- u32 val1, val2;
int timeout = 1000;
struct mxs_ocotp_regs *ocotp_regs =
(struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
u32 *cust = &ocotp_regs->hw_ocotp_cust0;
- char mac[6 * 3];
+ u8 mac[ETH_ALEN];
char env_name[] = "eth.addr";
+ u32 val = 0;
+ int i;
if (index < 0 || index > FEC_MAX_IDX)
return -EINVAL;
udelay(100);
}
- val1 = readl(&cust[index * 8]);
- val2 = readl(&cust[index * 8 + 4]);
- if ((val1 | val2) == 0)
+ for (i = 0; i < sizeof(mac); i++) {
+ int shift = 24 - i % 4 * 8;
+
+ if (i % 4 == 0)
+ val = readl(&cust[index * 8 + i]);
+ mac[i] = val >> shift;
+ }
+ if (!is_valid_ether_addr(mac))
return 0;
- snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
- (val1 >> 24) & 0xFF, (val1 >> 16) & 0xFF,
- (val1 >> 8) & 0xFF, (val1 >> 0) & 0xFF,
- (val2 >> 24) & 0xFF, (val2 >> 16) & 0xFF);
+
if (index == 0)
snprintf(env_name, sizeof(env_name), "ethaddr");
else
snprintf(env_name, sizeof(env_name), "eth%daddr", index);
- setenv(env_name, mac);
+ eth_setenv_enetaddr(env_name, mac);
return 0;
}
#endif /* CONFIG_GET_FEC_MAC_ADDR_FROM_IIM */
};
#ifdef CONFIG_LCD
+ static ushort tx28_cmap[256];
+ vidinfo_t panel_info = {
+ /* set to max. size supported by SoC */
+ .vl_col = 1600,
+ .vl_row = 1200,
+
+ .vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+ .cmap = tx28_cmap,
+ };
+
static struct fb_videomode tx28_fb_modes[] = {
{
/* Standard VGA timing */
.upper_margin = 31,
.vsync_len = 2,
.lower_margin = 12,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 32,
.vsync_len = 3,
.lower_margin = 10,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 18 - 3,
.vsync_len = 3,
.lower_margin = 4,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 2,
.vsync_len = 10,
.lower_margin = 2,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 35 - 2,
.vsync_len = 2,
.lower_margin = 525 - 480 - 35,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 16, /* 15 according to datasheet */
.vsync_len = 3, /* TVP -> 1>x>5 */
.lower_margin = 4, /* 4.5 according to datasheet */
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
.upper_margin = 35 - 2,
.vsync_len = 2,
.lower_margin = 525 - 480 - 35,
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
{
/* unnamed entry for assigning parameters parsed from 'video_mode' string */
- .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
};
void lcd_disable(void)
{
- mxsfb_disable();
}
void lcd_panel_disable(void)
if (karo_load_splashimage(0) == 0) {
debug("Initializing LCD controller\n");
- mxsfb_init(p, PIX_FMT_RGB24, color_depth);
video_hw_init(lcdbase);
} else {
debug("Skipping initialization of LCD controller\n");
return 0;
}
+#define BOOT_CAUSE_MASK (RTC_PERSISTENT0_EXTERNAL_RESET | \
+ RTC_PERSISTENT0_ALARM_WAKE | \
+ RTC_PERSISTENT0_THERMAL_RESET)
+
+static void thermal_init(void)
+{
+ struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+ struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+
+ writel(POWER_THERMAL_LOW_POWER | POWER_THERMAL_OFFSET_ADJ_ENABLE |
+ POWER_THERMAL_OFFSET_ADJ_OFFSET(3),
+ &power_regs->hw_power_thermal);
+
+ writel(CLKCTRL_RESET_EXTERNAL_RESET_ENABLE |
+ CLKCTRL_RESET_THERMAL_RESET_ENABLE,
+ &clkctrl_regs->hw_clkctrl_reset);
+}
+
int checkboard(void)
{
- printf("Board: Ka-Ro TX28-4%sxx\n", TX28_MOD_SUFFIX);
+ struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+ u32 pwr_sts = readl(&power_regs->hw_power_sts);
+ u32 pwrup_src = (pwr_sts >> 24) & 0x3f;
+ const char *dlm = "";
+
+ printf("Board: Ka-Ro TX28-4%sx%d\n", TX28_MOD_SUFFIX,
+ CONFIG_SDRAM_SIZE / SZ_128M);
+
+ printf("POWERUP Source: ");
+ if (pwrup_src & (3 << 0)) {
+ printf("%sPSWITCH %s voltage", dlm,
+ pwrup_src & (1 << 1) ? "HIGH" : "MID");
+ dlm = " | ";
+ }
+ if (pwrup_src & (1 << 4)) {
+ printf("%sRTC", dlm);
+ dlm = " | ";
+ }
+ if (pwrup_src & (1 << 5)) {
+ printf("%s5V", dlm);
+ dlm = " | ";
+ }
+ printf("\n");
+
+ if (boot_cause & BOOT_CAUSE_MASK) {
+ dlm="";
+ printf("Last boot cause: ");
+ if (boot_cause & RTC_PERSISTENT0_EXTERNAL_RESET) {
+ printf("%sEXTERNAL", dlm);
+ dlm = " | ";
+ }
+ if (boot_cause & RTC_PERSISTENT0_THERMAL_RESET) {
+ printf("%sTHERMAL", dlm);
+ dlm = " | ";
+ }
+ if (*dlm != '\0')
+ printf(" RESET");
+ if (boot_cause & RTC_PERSISTENT0_ALARM_WAKE) {
+ printf("%sALARM WAKE", dlm);
+ dlm = " | ";
+ }
+ printf("\n");
+ }
+
+ while (pwr_sts & POWER_STS_THERMAL_WARNING) {
+ static int first = 1;
+
+ if (first) {
+ printf("CPU too hot to boot\n");
+ first = 0;
+ }
+ if (tstc())
+ break;
+ pwr_sts = readl(&power_regs->hw_power_sts);
+ }
+
+ if (!(boot_cause & RTC_PERSISTENT0_THERMAL_RESET))
+ thermal_init();
+
return 0;
}
#include <jffs2/jffs2.h>
#include <mtd_node.h>
struct node_info tx28_nand_nodes[] = {
- { "gpmi-nand", MTD_DEV_TYPE_NAND, },
+ { "fsl,imx28-gpmi-nand", MTD_DEV_TYPE_NAND, },
};
#else
#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
#endif
-static void tx28_fixup_flexcan(void *blob)
+static int flexcan_enabled(void *blob)
{
- karo_fdt_del_prop(blob, "fsl,imx28-flexcan", 0x80032000, "transceiver-switch");
- karo_fdt_del_prop(blob, "fsl,imx28-flexcan", 0x80034000, "transceiver-switch");
+ const char *status;
+ int off = fdt_path_offset(blob, "can0");
+
+ if (off < 0) {
+ printf("node 'can0' not found\n");
+ } else {
+ status = fdt_getprop(blob, off, "status", NULL);
+ if (status && strcmp(status, "okay") == 0) {
+ printf("can0 is enabled\n");
+ return 1;
+ }
+ }
+ off = fdt_path_offset(blob, "can1");
+ if (off < 0) {
+ printf("node 'can1' not found\n");
+ return 0;
+ }
+ status = fdt_getprop(blob, off, "status", NULL);
+ if (status && strcmp(status, "okay") == 0) {
+ printf("can1 is enabled\n");
+ return 1;
+ }
+ printf("can driver disabled\n");
+ return 0;
+}
+
+static void tx28_set_lcd_pins(void *blob, const char *name)
+{
+ int off = fdt_path_offset(blob, name);
+ u32 ph;
+ const struct fdt_property *pc;
+ int len;
+
+ if (off < 0)
+ return;
+
+ ph = fdt32_to_cpu(fdt_create_phandle(blob, off));
+ if (!ph)
+ return;
+
+ off = fdt_path_offset(blob, "lcdif");
+ if (off < 0)
+ return;
+
+ pc = fdt_get_property(blob, off, "pinctrl-0", &len);
+ if (!pc || len < sizeof(ph))
+ return;
+
+ memcpy((void *)pc->data, &ph, sizeof(ph));
+ fdt_setprop(blob, off, "pinctrl-0", pc->data, len);
+}
+
+static void tx28_fixup_flexcan(void *blob, int stk5_v5)
+{
+ const char *can_xcvr = "disabled";
+
+ if (stk5_v5) {
+ if (flexcan_enabled(blob)) {
+ tx28_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+ can_xcvr = "okay";
+ } else {
+ tx28_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+ }
+ } else {
+ const char *otg_mode = getenv("otg_mode");
+
+ if (otg_mode && (strcmp(otg_mode, "host") == 0))
+ karo_fdt_enable_node(blob, "can1", 0);
+ }
+ fdt_find_and_setprop(blob, "/regulators/can-xcvr", "status",
+ can_xcvr, strlen(can_xcvr) + 1, 1);
}
static void tx28_fixup_fec(void *blob)
void ft_board_setup(void *blob, bd_t *bd)
{
const char *baseboard = getenv("baseboard");
+ int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
#ifdef CONFIG_TX28_S
/* TX28-41xx (aka TX28S) has no external RTC
karo_fdt_remove_node(blob, "ds1339");
karo_fdt_remove_node(blob, "gpio5");
#endif
- if (baseboard != NULL && strcmp(baseboard, "stk5-v5") == 0) {
+ if (stk5_v5) {
karo_fdt_remove_node(blob, "stk5led");
} else {
- tx28_fixup_flexcan(blob);
tx28_fixup_fec(blob);
}
-
- if (baseboard != NULL && strcmp(baseboard, "stk5-v3") == 0) {
- const char *otg_mode = getenv("otg_mode");
-
- if (otg_mode && (strcmp(otg_mode, "device") == 0 ||
- strcmp(otg_mode, "gadget") == 0))
- karo_fdt_enable_node(blob, "can1", 0);
- }
+ tx28_fixup_flexcan(blob, stk5_v5);
fdt_fixup_mtdparts(blob, tx28_nand_nodes, ARRAY_SIZE(tx28_nand_nodes));
fdt_fixup_ethernet(blob);
#define SDRAM_SIZE PHYS_SDRAM_1_SIZE
#endif
- #define REG_ESDCTL0 0x00
- #define REG_ESDCFG0 0x04
- #define REG_ESDCTL1 0x08
- #define REG_ESDCFG1 0x0c
- #define REG_ESDMISC 0x10
- #define REG_ESDSCR 0x14
- #define REG_ESDGPR 0x34
-#define REG_CCOSR 0x60
#define REG_CCGR0 0x68
#define REG_CCGR1 0x6c
(((l) >> 8) & 0x0000FF00) | \
(((l) >> 24) & 0x000000FF))
- #define MXC_DCD_ITEM(addr, val) \
- .word CPU_2_BE_32(addr), CPU_2_BE_32(val)
+ /*
+ CCM register set 0x53FD4000 0x53FD7FFF
+ EIM register set 0x63FDA000 0x63FDAFFF
+ NANDFC register set 0xF7FF0000 0xF7FFFFFF
+ IOMUX Control (IOMUXC) registers 0x53FA8000 0x53FABFFF
+ DPLLC1 register 0x63F80000 0x63F83FFF
+ DPLLC2 register 0x63F84000 0x63F87FFF
+ DPLLC3 register 0x63F88000 0x63F8BFFF
+ DPLLC4 register 0x63F8C000 0x63F8FFFF
+ ESD RAM controller register 0x63FD9000 0x63FD9FFF
+ M4IF register 0x63FD8000 0x63FD8FFF
+ DDR 0x70000000 0xEFFFFFFF
+ EIM 0xF0000000 0xF7FEFFFF
+ NANDFC Buffers 0xF7FF0000 0xF7FFFFFF
+ IRAM Free Space 0xF8006000 0xF8017FF0
+ GPU Memory 0xF8020000 0xF805FFFF
+ */
+ #define CHECK_DCD_ADDR(a) ( \
+ ((a) >= 0x53fd4000 && (a) <= 0x53fd7fff) /* CCM */ || \
+ ((a) >= 0x63fda000 && (a) <= 0x63fdafff) /* EIM (CS0) */ || \
+ ((a) >= 0x53fa8000 && (a) <= 0x53fabfff) /* IOMUXC */ || \
+ ((a) >= 0x63f80000 && (a) <= 0x63f8ffff) /* DPLLC1..4 */ || \
+ ((a) >= 0x63fd8000 && (a) <= 0x63fd9fff) /* M4IF & SDRAM Contr. */ || \
+ ((a) >= 0x70000000 && (a) <= 0xefffffff) /* SDRAM */ || \
+ ((a) >= 0xf0000000 && (a) <= 0xf7ffffff) /* EIM & NANDFC buffers */ || \
+ ((a) >= 0xf8006000 && (a) <= 0xf8017ff0) /* IRAM free space */ || \
+ ((a) >= 0xf8020000 && (a) <= 0xf805ffff) /* GPU RAM */)
+
+ .macro mxc_dcd_item addr, val
+ .ifne CHECK_DCD_ADDR(\addr)
+ .word CPU_2_BE_32(\addr), CPU_2_BE_32(\val)
+ .else
+ .error "Address \addr not accessible from DCD"
+ .endif
+ .endm
+
+ #define MXC_DCD_ITEM(addr, val) mxc_dcd_item addr, val
#define MXC_DCD_CMD_SZ_BYTE 1
#define MXC_DCD_CMD_SZ_SHORT 2
#define CK_TO_NS(ck) (((ck) * 1000 + SDRAM_CLK / 2) / SDRAM_CLK)
#define NS_TO_CK(ns) (((ns) * SDRAM_CLK + 999) / 1000)
+ #define NS_TO_CK10(ns) DIV_ROUND_UP(NS_TO_CK(ns), 10)
.macro CK_VAL, name, clks, offs, max
.iflt \clks - \offs
.else
.ifle \clks - \offs - \max
.set \name, \clks - \offs
+ .else
+ .error "Value \clks out of range for parameter \name"
.endif
.endif
.endm
#endif
#define SDRAM_BURST_LENGTH 8
#define RALAT 5
- #define WALAT 1
+ #define WALAT 0
+ #define BI_ON 0
#define ADDR_MIRROR 0
#define DDR_TYPE ESDMISC_DDR_TYPE_DDR3
- /* 512/1024MiB SDRAM: NT5CB128M16P-CG */
+ /* 512/1024MiB SDRAM: NT5CB128M16FP-DII */
+ #if SDRAM_CLK > 666 && SDRAM_CLK <= 800
+ #define CL_VAL 11
+ #define CWL_VAL 8
+ #elif SDRAM_CLK > 533 && SDRAM_CLK <= 666
+ #define CL_VAL 9 // or 10
+ #define CWL_VAL 7
+ #elif SDRAM_CLK > 400 && SDRAM_CLK <= 533
+ #define CL_VAL 7 // or 8
+ #define CWL_VAL 6
+ #elif SDRAM_CLK > 333 && SDRAM_CLK <= 400
+ #define CL_VAL 6
+ #define CWL_VAL 5
+ #elif SDRAM_CLK >= 303 && SDRAM_CLK <= 333
+ #define CL_VAL 5
+ #define CWL_VAL 5
+ #else
+ #error SDRAM clock out of range: 303 .. 800
+ #endif
+
/* ESDCFG0 0x0c */
NS_VAL tRFC, 160, 1, 255 /* clks - 1 (0..255) */
- CK_MAX tXS, tRFC + 1 + NS_TO_CK(10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
- CK_MAX tXP, 3, NS_TO_CK(6), 1, 7 /* clks - 1 (0..7) */ /* max(6ns, 3*CK) */
+ CK_MAX tXS, NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
+ CK_MAX tXP, NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15 /* clks - 1 (0..15) */
- NS_VAL tFAW, 45, 1, 31 /* clks - 1 (0..31) */
- CK_VAL tCL, 9, 3, 8 /* clks - 3 (0..8) CAS Latency */
+ NS_VAL tFAW, 50, 1, 31 /* clks - 1 (0..31) */
+ CK_VAL tCL, CL_VAL, 3, 8 /* clks - 3 (0..8) CAS Latency */
/* ESDCFG1 0x10 */
- NS_VAL tRCD, 14, 1, 7 /* clks - 1 (0..7) */
- NS_VAL tRP, 14, 1, 7 /* clks - 1 (0..7) */
+ CK_VAL tRCD, NS_TO_CK10(125), 1, 7 /* clks - 1 (0..7) */ /* 12.5 */
+ CK_VAL tRP, NS_TO_CK10(125), 1, 7 /* clks - 1 (0..7) */ /* 12.5 */
NS_VAL tRC, 50, 1, 31 /* clks - 1 (0..31) */
- NS_VAL tRAS, 36, 1, 31 /* clks - 1 (0..31) */
- CK_VAL tRPA, 0, 0, 1 /* clks (0..1) */
+ CK_VAL tRAS, NS_TO_CK10(375), 1, 31 /* clks - 1 (0..31) */ /* 37.5 */
+ CK_VAL tRPA, 1, 0, 1 /* clks (0..1) */
NS_VAL tWR, 15, 1, 15 /* clks - 1 (0..15) */
CK_VAL tMRD, 4, 1, 15 /* clks - 1 (0..15) */
- CK_VAL tCWL, 5, 2, 6 /* clks - 2 (0..6) */
+ CK_VAL tCWL, CWL_VAL, 2, 6 /* clks - 2 (0..6) */
/* ESDCFG2 0x14 */
CK_VAL tDLLK, 512, 1, 511 /* clks - 1 (0..511) */
- CK_MAX tRTP, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
- CK_MAX tWTR, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
- CK_MAX tRRD, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
+ CK_MAX tRTP, NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+ CK_MAX tWTR, NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+ CK_MAX tRRD, NS_TO_CK(10), 4, 1, 7 /* clks - 1 (0..7) */
/* ESDOR 0x30 */
CK_MAX tXPR, NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
-
- /* ESDOTC 0x08 */
- NS_VAL tAOFPD, 9, 1, 7 /* clks - 1 (0..7) */
- NS_VAL tAONPD, 9, 1, 7 /* clks - 1 (0..7) */
- CK_VAL tANPD, tCWL, 1, 15 /* clks - 1 (0..15) */
- CK_VAL tAXPD, tCWL, 1, 15 /* clks - 1 (0..15) */
- CK_VAL tODTLon tCWL - 1, 1, 7 /* clks - 1 (0..7) */
- CK_VAL tODTLoff tCWL - 1, 1, 31 /* clks - 1 (0..31) */
-
#define tSDE_RST (DIV_ROUND_UP(200000, ESDOR_CLK_PERIOD_ns) + 1)
-
/* Add an extra (or two?) ESDOR_CLK_PERIOD_ns according to
* erroneous Erratum Engcm12377
*/
#define tRST_CKE (DIV_ROUND_UP(500000 + 2 * ESDOR_CLK_PERIOD_ns, ESDOR_CLK_PERIOD_ns) + 1)
+
+ /* ESDOTC 0x08 */
+ CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7 /* clks - 1 (0..7) */ /* 8.5ns */
+ CK_VAL tAONPD, NS_TO_CK10(85), 1, 7 /* clks - 1 (0..7) */ /* 8.5ns */
+ CK_VAL tANPD, tCWL + 1, 1, 15 /* clks - 1 (0..15) */
+ CK_VAL tAXPD, tCWL + 1, 1, 15 /* clks - 1 (0..15) */
+ CK_VAL tODTLon tCWL, 0, 7 /* clks - 1 (0..7) */ /* CWL+AL-2 */
+ CK_VAL tODTLoff tCWL, 0, 31 /* clks - 1 (0..31) */ /* CWL+AL-2 */
+
+ /* ESDPDC 0x04 */
+ CK_MAX tCKE, NS_TO_CK(5), 3, 1, 7
+ CK_MAX tCKSRX, NS_TO_CK(10), 5, 0, 7
+ CK_MAX tCKSRE, NS_TO_CK(10), 5, 0, 7
+
+ #define PRCT 0
+ #define PWDT 5
+ #define SLOW_PD 0
+ #define BOTH_CS_PD 1
+
+ #define ESDPDC_VAL_0 ( \
+ (PRCT << 28) | \
+ (PRCT << 24) | \
+ (tCKE << 16) | \
+ (SLOW_PD << 7) | \
+ (BOTH_CS_PD << 6) | \
+ (tCKSRX << 3) | \
+ (tCKSRE << 0) \
+ )
+
+ #define ESDPDC_VAL_1 (ESDPDC_VAL_0 | \
+ (PWDT << 12) | \
+ (PWDT << 8) \
+ )
+
#define ROW_ADDR_BITS 14
#define COL_ADDR_BITS 10
+ #define Rtt_Nom 1 /* ODT: 0: off 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */
+ #define Rtt_WR 0 /* Dynamic ODT: 0: off 1: RZQ/4 2: RZQ/2 */
+ #define DLL_DISABLE 0
+
.iflt tWR - 7
- .set mrs_val, (0x8080 | \
- (3 << 4) /* MRS command */ | \
- ((1 << 8) /* DLL Reset */ | \
- ((tWR + 1 - 4) << 9) | \
- (((tCL + 3) - 4) << 4)) << 16)
+ .set mr0_val, (((1 - DLL_DISABLE) << 8) /* DLL Reset */ | \
+ (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+ ((tWR + 1 - 4) << 9) | \
+ ((((tCL + 3) - 4) & 0x7) << 4) | \
+ ((((tCL + 3) - 4) & 0x8) >> 1))
.else
- .set mrs_val, (0x8080 | \
- (3 << 4) /* MRS command */ | \
- ((1 << 8) /* DLL Reset */ | \
- (((tWR + 1) / 2) << 9) | \
- (((tCL + 3) - 4) << 4)) << 16)
+ .set mr0_val, ((1 << 8) /* DLL Reset */ | \
+ (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+ (((tWR + 1) / 2) << 9) | \
+ ((((tCL + 3) - 4) & 0x7) << 4) | \
+ ((((tCL + 3) - 4) & 0x8) >> 1))
.endif
- #define ESDSCR_MRS_VAL(cs) (mrs_val | ((cs) << 3))
-
- #define ESDCFG0_VAL ( \
- (tRFC << 24) | \
- (tXS << 16) | \
- (tXP << 13) | \
- (tXPDLL << 9) | \
- (tFAW << 4) | \
- (tCL << 0)) \
-
- #define ESDCFG1_VAL ( \
- (tRCD << 29) | \
- (tRP << 26) | \
- (tRC << 21) | \
- (tRAS << 16) | \
- (tRPA << 15) | \
- (tWR << 9) | \
- (tMRD << 5) | \
- (tCWL << 0)) \
-
- #define ESDCFG2_VAL ( \
- (tDLLK << 16) | \
- (tRTP << 6) | \
- (tWTR << 3) | \
+
+ #define mr1_val ( \
+ ((Rtt_Nom & 1) << 2) | \
+ (((Rtt_Nom >> 1) & 1) << 6) | \
+ (((Rtt_Nom >> 2) & 1) << 9) | \
+ (DLL_DISABLE << 0) | \
+ 0)
+ #define mr2_val ( \
+ (Rtt_WR << 9) /* dynamic ODT */ | \
+ (0 << 7) /* SRT: Ext. temp. (mutually exclusive with ASR!) */ | \
+ (1 << 6) | /* ASR: Automatic Self Refresh */ \
+ (((tCWL + 2) - 5) << 3) | \
+ 0)
+ #define mr3_val 0
+
+ #define ESDSCR_MRS_VAL(cs, mr, val) (((val) << 16) | \
+ (1 << 15) /* CON_REQ */ | \
+ 0x80 | \
+ (3 << 4) /* MRS command */ | \
+ ((cs) << 3) | \
+ ((mr) << 0) | \
+ 0)
+
+ #define ESDCFG0_VAL ( \
+ (tRFC << 24) | \
+ (tXS << 16) | \
+ (tXP << 13) | \
+ (tXPDLL << 9) | \
+ (tFAW << 4) | \
+ (tCL << 0)) \
+
+ #define ESDCFG1_VAL ( \
+ (tRCD << 29) | \
+ (tRP << 26) | \
+ (tRC << 21) | \
+ (tRAS << 16) | \
+ (tRPA << 15) | \
+ (tWR << 9) | \
+ (tMRD << 5) | \
+ (tCWL << 0)) \
+
+ #define ESDCFG2_VAL ( \
+ (tDLLK << 16) | \
+ (tRTP << 6) | \
+ (tWTR << 3) | \
(tRRD << 0))
- #define BURST_LEN (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
- #define ESDCTL_VAL (((ROW_ADDR_BITS - 11) << 24) | \
- ((COL_ADDR_BITS - 9) << 20) | \
- (BURST_LEN << 19) | \
- (1 << 16) | /* SDRAM bus width */ \
- ((-1) << (32 - BANK_ADDR_BITS)))
+ #define BURST_LEN (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
+
+ #define ESDCTL_VAL (((ROW_ADDR_BITS - 11) << 24) | \
+ ((COL_ADDR_BITS - 9) << 20) | \
+ (BURST_LEN << 19) | \
+ (1 << 16) | /* SDRAM bus width */ \
+ ((-1) << (32 - BANK_ADDR_BITS)))
- #define ESDMISC_VAL ((1 << 12) | \
- (0x3 << 9) | \
- (RALAT << 6) | \
- (WALAT << 16) | \
- (ADDR_MIRROR << 19) | \
- (DDR_TYPE << 3))
+ #define ESDMISC_VAL ((ADDR_MIRROR << 19) | \
+ (WALAT << 16) | \
+ (BI_ON << 12) | \
+ (0x3 << 9) | \
+ (RALAT << 6) | \
+ (DDR_TYPE << 3))
#define ESDOR_VAL ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
.word CPU_2_BE_32((0xd2 << 24) | ((dcd_end - .) << 8) | DCD_VERSION)
dcd_start:
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, zq_calib)
+
+ MXC_DCD_ITEM(0x53fa8004, 0x00194005) @ set LDO to 1.3V
+
/* disable all irrelevant clocks */
MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR0, 0xffcf0fff)
MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR1, 0x000fffc3)
MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR6, 0x0f00030f)
MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR7, 0xfff00000)
MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CMEOR, 0x00000000)
-#if 1
- MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCOSR, (1 << 24) | (0xe << 16))
- MXC_DCD_ITEM(IOMUXC_BASE_ADDR + 0x320, 0x4) /* GPIO_3 => CLKO2 */
-#endif
+
MXC_DCD_ITEM(IOMUXC_BASE_ADDR + 0x340, 0x11) /* GPIO_17 => RESET_OUT */
MXC_DCD_ITEM(0x63fd800c, 0x00000000) /* M4IF: MUX NFC signals on WEIM */
MXC_DCD_ITEM(0x63fd902c, 0x000026d2)
MXC_DCD_ITEM(0x63fd9030, ESDOR_VAL)
MXC_DCD_ITEM(0x63fd9008, ESDOTC_VAL)
- MXC_DCD_ITEM(0x63fd9004, 0x00030012)
-
- /* MR0 - CS0 */
- MXC_DCD_ITEM(0x63fd901c, 0x00008032) /* MRS: MR2 */
- MXC_DCD_ITEM(0x63fd901c, 0x00008033) /* MRS: MR3 */
- MXC_DCD_ITEM(0x63fd901c, 0x00408031) /* MRS: MR1 */
- MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0)) /* MRS: MR0 */
- /* MR0 - CS1 */
+ MXC_DCD_ITEM(0x63fd9004, ESDPDC_VAL_0)
+
+ /* MR0..3 - CS0 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 2, mr2_val)) /* MRS: MR2 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, mr3_val)) /* MRS: MR3 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 1, mr1_val)) /* MRS: MR1 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 0, mr0_val)) /* MRS: MR0 */
#if BANK_ADDR_BITS > 1
- MXC_DCD_ITEM(0x63fd901c, 0x0000803a) /* MRS: MR2 */
- MXC_DCD_ITEM(0x63fd901c, 0x0000803b) /* MRS: MR3 */
- MXC_DCD_ITEM(0x63fd901c, 0x00408039) /* MRS: MR1 */
- MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1)) /* MRS: MR0 */
+ /* MR0..3 - CS1 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 2, 0x0000)) /* MRS: MR2 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 3, 0x0000)) /* MRS: MR3 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 1, 0x0040)) /* MRS: MR1 */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 0, mr0_val)) /* MRS: MR0 */
#endif
- MXC_DCD_ITEM(0x63fd9020, 0x00005800) /* refresh interval */
- MXC_DCD_ITEM(0x63fd9058, 0x00011112)
+ MXC_DCD_ITEM(0x63fd9020, 3 << 14) /* disable refresh during calibration */
+ MXC_DCD_ITEM(0x63fd9058, 0x00022222)
MXC_DCD_ITEM(0x63fd90d0, 0x00000003) /* select default compare pattern for calibration */
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, wl_calib)
/* Write Leveling */
- MXC_DCD_ITEM(0x63fd901c, 0x00048033) /* MRS: select MPR */
- MXC_DCD_ITEM(0x63fd901c, 0x00848231) /* MRS: start write leveling */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 1, mr1_val | (1 << 7)) | (1 << 9)) /* MRS: start write leveling */
MXC_DCD_ITEM(0x63fd901c, 0x00000000)
MXC_DCD_ITEM(0x63fd9048, 0x00000001)
wl_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, 0, 0x63fd9048, 0x00000001)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, dqs_calib)
- MXC_DCD_ITEM(0x63fd901c, 0x00048031) /* MRS: end write leveling */
- MXC_DCD_ITEM(0x63fd901c, 0x00008033) /* MRS: select normal data path */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 1, mr1_val)) /* MRS: end write leveling */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
/* DQS calibration */
MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
- MXC_DCD_ITEM(0x63fd901c, 0x00048033) /* MRS: select MPR */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
MXC_DCD_ITEM(0x63fd907c, 0x90000000) /* reset RD fifo and start DQS calib. */
dqs_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, 0, 0x63fd907c, 0x90000000)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, wr_dl_calib)
- MXC_DCD_ITEM(0x63fd901c, 0x00008033) /* MRS: select normal data path */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
/* WR DL calibration */
MXC_DCD_ITEM(0x63fd901c, 0x00000000)
MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
- MXC_DCD_ITEM(0x63fd901c, 0x00048033) /* MRS: select MPR */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
MXC_DCD_ITEM(0x63fd90a4, 0x00000010)
wr_dl_calib: /* 6c4 */
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, 0, 0x63fd90a4, 0x00000010)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, rd_dl_calib)
- MXC_DCD_ITEM(0x63fd901c, 0x00008033) /* MRS: select normal data path */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
/* RD DL calibration */
MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
- MXC_DCD_ITEM(0x63fd901c, 0x00048033) /* MRS: select MPR */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
MXC_DCD_ITEM(0x63fd90a0, 0x00000010)
rd_dl_calib: /* 70c */
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, 0, 0x63fd90a0, 0x00000010)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, dcd_end)
- MXC_DCD_ITEM(0x63fd901c, 0x00008033) /* MRS: select normal data path */
+ MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
+ MXC_DCD_ITEM(0x63fd9020, (3 << 11) | (0 << 14)) /* refresh interval: 4 cycles every 64kHz period */
+ MXC_DCD_ITEM(0x63fd9004, ESDPDC_VAL_1)
MXC_DCD_ITEM(0x63fd901c, 0x00000000)
- MXC_DCD_ITEM(0x53fa8004, 0x00194005) @ set LDO to 1.3V
-
/* setup NFC pads */
/* MUX_SEL */
MXC_DCD_ITEM(0x53fa819c, 0x00000000) @ EIM_DA0
MXC_DCD_ITEM(0x53fa85b0, 0x00000004) @ NANDF_CS0
dcd_end:
.ifgt dcd_end - dcd_start - 1768
- DCD too large!
+ .error "DCD too large!"
.endif
#include <asm/arch/imx-regs.h>
#include <generated/asm-offsets.h>
-//#define DO_WL_CALIB
-
#ifndef CCM_CCR
#error asm-offsets not included
#endif
.endm
#define MXC_DCD_ITEM(addr, val) mxc_dcd_item addr, val
+ #if PHYS_SDRAM_1_WIDTH == 64
+ #define MXC_DCD_ITEM_64(addr, val) mxc_dcd_item addr, val
+ #define MXC_DCD_CMD_CHK_64(type, flags, addr, mask) MXC_DCD_CMD_CHK(type, flags, addr, mask)
+ #else
+ #define MXC_DCD_ITEM_64(addr, val)
+ #define MXC_DCD_CMD_CHK_64(type, flags, addr, mask)
+ #endif
#define MXC_DCD_CMD_SZ_BYTE 1
#define MXC_DCD_CMD_SZ_SHORT 2
.word CPU_2_BE_32((0xcf << 24) | (16 << 8) | ((flags) << 3) | (type)),\
CPU_2_BE_32(addr), CPU_2_BE_32(mask), CPU_2_BE_32(count)
- #define MXC_DCD_CMD_NOP \
+ #define MXC_DCD_CMD_NOP() \
.word CPU_2_BE_32((0xc0 << 24) | (4 << 8))
#define CK_TO_NS(ck) (((ck) * 1000 + SDRAM_CLK / 2) / SDRAM_CLK)
#define NS_TO_CK(ns) (((ns) * SDRAM_CLK + 999) / 1000)
+ #define NS_TO_CK10(ns) DIV_ROUND_UP(NS_TO_CK(ns), 10)
.macro CK_VAL, name, clks, offs, max
.iflt \clks - \offs
#define SDRAM_BURST_LENGTH 8
#define RALAT 5
#define WALAT 0
- #define BI_ON 1
- #define ADDR_MIRROR 1
+ #define BI_ON 0
+ #define ADDR_MIRROR 0
#define DDR_TYPE MDMISC_DDR_TYPE_DDR3
- /* 512/1024MiB SDRAM: NT5CB128M16P-CG */
+ /* 512/1024MiB SDRAM: NT5CB128M16FP-DII */
+ #if SDRAM_CLK > 666 && SDRAM_CLK <= 800
+ #define CL_VAL 11
+ #define CWL_VAL 8
+ #elif SDRAM_CLK > 533 && SDRAM_CLK <= 666
+ #define CL_VAL 9 // or 10
+ #define CWL_VAL 7
+ #elif SDRAM_CLK > 400 && SDRAM_CLK <= 533
+ #define CL_VAL 7 // or 8
+ #define CWL_VAL 6
+ #elif SDRAM_CLK > 333 && SDRAM_CLK <= 400
+ #define CL_VAL 6
+ #define CWL_VAL 5
+ #elif SDRAM_CLK >= 303 && SDRAM_CLK <= 333
+ #define CL_VAL 5
+ #define CWL_VAL 5
+ #else
+ #error SDRAM clock out of range: 303 .. 800
+ #endif
+
/* MDCFG0 0x0c */
NS_VAL tRFC, 160, 1, 255 /* clks - 1 (0..255) */
- CK_MAX tXS, tRFC + 1 + NS_TO_CK(10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
- CK_MAX tXP, 3, NS_TO_CK(6), 1, 7 /* clks - 1 (0..7) */ /* max(6ns, 3*CK) */
+ CK_MAX tXS, NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
+ CK_MAX tXP, NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15 /* clks - 1 (0..15) */
- NS_VAL tFAW, 45, 1, 31 /* clks - 1 (0..31) */
- CK_VAL tCL, 8, 3, 8 /* clks - 3 (0..8) CAS Latency */
+ NS_VAL tFAW, 50, 1, 31 /* clks - 1 (0..31) */
+ CK_VAL tCL, CL_VAL, 3, 8 /* clks - 3 (0..8) CAS Latency */
/* MDCFG1 0x10 */
- NS_VAL tRCD, 14, 1, 7 /* clks - 1 (0..7) */
- NS_VAL tRP, 14, 1, 7 /* clks - 1 (0..7) */
+ CK_VAL tRCD, NS_TO_CK10(125), 1, 7 /* clks - 1 (0..7) */ /* 12.5 */
+ CK_VAL tRP, NS_TO_CK10(125), 1, 7 /* clks - 1 (0..7) */ /* 12.5 */
NS_VAL tRC, 50, 1, 31 /* clks - 1 (0..31) */
- NS_VAL tRAS, 36, 1, 31 /* clks - 1 (0..31) */
- CK_VAL tRPA, 0, 0, 1 /* clks (0..1) */
+ CK_VAL tRAS, NS_TO_CK10(375), 1, 31 /* clks - 1 (0..31) */ /* 37.5 */
+ CK_VAL tRPA, 1, 0, 1 /* clks (0..1) */
NS_VAL tWR, 15, 1, 15 /* clks - 1 (0..15) */
CK_VAL tMRD, 4, 1, 15 /* clks - 1 (0..15) */
- CK_VAL tCWL, 6, 2, 6 /* clks - 2 (0..6) */
+ CK_VAL tCWL, CWL_VAL, 2, 6 /* clks - 2 (0..6) */
/* MDCFG2 0x14 */
CK_VAL tDLLK, 512, 1, 511 /* clks - 1 (0..511) */
- CK_MAX tRTP, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
- CK_MAX tWTR, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
- CK_MAX tRRD, 4, NS_TO_CK(8), 1, 7 /* clks - 1 (0..7) */
+ CK_MAX tRTP, NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+ CK_MAX tWTR, NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+ CK_MAX tRRD, NS_TO_CK(10), 4, 1, 7 /* clks - 1 (0..7) */
/* MDOR 0x30 */
CK_MAX tXPR, NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
#define tRST_CKE (DIV_ROUND_UP(500000, MDOR_CLK_PERIOD_ns) + 2)
/* MDOTC 0x08 */
- NS_VAL tAOFPD, 9, 1, 7 /* clks - 1 (0..7) */
- NS_VAL tAONPD, 9, 1, 7 /* clks - 1 (0..7) */
+ CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7 /* clks - 1 (0..7) */ /* 8.5ns */
+ CK_VAL tAONPD, NS_TO_CK10(85), 1, 7 /* clks - 1 (0..7) */ /* 8.5ns */
CK_VAL tANPD, tCWL + 1, 1, 15 /* clks - 1 (0..15) */
CK_VAL tAXPD, tCWL + 1, 1, 15 /* clks - 1 (0..15) */
- CK_VAL tODTLon tCWL, 1, 7 /* clks - 1 (0..7) */
- CK_VAL tODTLoff tCWL, 1, 31 /* clks - 1 (0..31) */
+ CK_VAL tODTLon tCWL, 0, 7 /* clks - 1 (0..7) */ /* CWL+AL-2 */
+ CK_VAL tODTLoff tCWL, 0, 31 /* clks - 1 (0..31) */ /* CWL+AL-2 */
/* MDPDC 0x04 */
- CK_MAX tCKE, NS_TO_CK(6), 3, 1, 7
+ CK_MAX tCKE, NS_TO_CK(5), 3, 1, 7
CK_MAX tCKSRX, NS_TO_CK(10), 5, 0, 7
CK_MAX tCKSRE, NS_TO_CK(10), 5, 0, 7
(PWDT << 8) \
)
- #define ROW_ADDR_BITS 14
- #define COL_ADDR_BITS 10
+ #define ROW_ADDR_BITS 14
+ #define COL_ADDR_BITS 10
+
+ #define Rtt_Nom 1 /* ODT: 0: off 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */
+ #define Rtt_WR 0 /* Dynamic ODT: 0: off 1: RZQ/4 2: RZQ/2 */
+ #define DLL_DISABLE 0
.iflt tWR - 7
- .set mr0_val, ((1 << 8) /* DLL Reset */ | \
- ((tWR + 1 - 4) << 9) | \
- (((tCL + 3) - 4) << 4))
+ .set mr0_val, (((1 - DLL_DISABLE) << 8) /* DLL Reset */ | \
+ (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+ ((tWR + 1 - 4) << 9) | \
+ ((((tCL + 3) - 4) & 0x7) << 4) | \
+ ((((tCL + 3) - 4) & 0x8) >> 1))
.else
- .set mr0_val, ((1 << 8) /* DLL Reset */ | \
+ .set mr0_val, ((1 << 8) /* DLL Reset */ | \
+ (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
(((tWR + 1) / 2) << 9) | \
- (((tCL + 3) - 4) << 4))
+ ((((tCL + 3) - 4) & 0x7) << 4) | \
+ ((((tCL + 3) - 4) & 0x8) >> 1))
.endif
+ #define mr1_val ( \
+ ((Rtt_Nom & 1) << 2) | \
+ (((Rtt_Nom >> 1) & 1) << 6) | \
+ (((Rtt_Nom >> 2) & 1) << 9) | \
+ (DLL_DISABLE << 0) | \
+ 0)
+ #define mr2_val ( \
+ (Rtt_WR << 9) /* dynamic ODT */ | \
+ (0 << 7) /* SRT: Ext. temp. (mutually exclusive with ASR!) */ | \
+ (1 << 6) | /* ASR: Automatic Self Refresh */ \
+ (((tCWL + 2) - 5) << 3) | \
+ 0)
+ #define mr3_val 0
+
#define MDSCR_MRS_VAL(cs, mr, val) (((val) << 16) | \
- (1 << 15) /* CON REQ */ | \
+ (1 << 15) /* CON_REQ */ | \
(3 << 4) /* MRS command */ | \
((cs) << 3) | \
- ((mr) << 0))
-
- #define mr1_val 0x0040
- #define mr2_val 0x0408
+ ((mr) << 0) | \
+ 0)
#define MDCFG0_VAL ( \
(tRFC << 24) | \
(tWTR << 3) | \
(tRRD << 0))
- #define BURST_LEN (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
+ #define BURST_LEN (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
- #if PHYS_SDRAM_1_WIDTH == 64
- #define MDCTL_VAL (((ROW_ADDR_BITS - 11) << 24) | \
- ((COL_ADDR_BITS - 9) << 20) | \
- (BURST_LEN << 19) | \
- (2 << 16) | /* SDRAM bus width */ \
- ((-1) << (32 - BANK_ADDR_BITS)))
- #else
- #define MDCTL_VAL (((ROW_ADDR_BITS - 11) << 24) | \
- ((COL_ADDR_BITS - 9) << 20) | \
- (BURST_LEN << 19) | \
- (1 << 16) | /* SDRAM bus width */ \
- ((-1) << (32 - BANK_ADDR_BITS)))
- #endif
+ #define MDCTL_VAL (((ROW_ADDR_BITS - 11) << 24) | \
+ ((COL_ADDR_BITS - 9) << 20) | \
+ (BURST_LEN << 19) | \
+ ((PHYS_SDRAM_1_WIDTH / 32) << 16) | \
+ ((-1) << (32 - BANK_ADDR_BITS)))
+
+ #define MDMISC_VAL ((ADDR_MIRROR << 19) | \
+ (WALAT << 16) | \
+ (BI_ON << 12) | \
+ (0x3 << 9) | \
+ (RALAT << 6) | \
+ (DDR_TYPE << 3))
+
+ #define MDOR_VAL ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
+
+ #define MDOTC_VAL ((tAOFPD << 27) | \
+ (tAONPD << 24) | \
+ (tANPD << 20) | \
+ (tAXPD << 16) | \
+ (tODTLon << 12) | \
+ (tODTLoff << 4))
- #define MDMISC_VAL ((ADDR_MIRROR << 19) | \
- (WALAT << 16) | \
- (BI_ON << 12) | \
- (0x3 << 9) | \
- (RALAT << 6) | \
- (DDR_TYPE << 3))
-
- #define MDOR_VAL ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
-
- #define MDOTC_VAL ((tAOFPD << 27) | \
- (tAONPD << 24) | \
- (tANPD << 20) | \
- (tAXPD << 16) | \
- (tODTLon << 12) | \
- (tODTLoff << 4))
-
- fcb_start:
- b _start
- .org 0x400
ivt_header:
- .word CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
+ .word CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
app_start_addr:
- .long _start
- .long 0x0
+ .long _start
+ .long 0x0
dcd_ptr:
- .long dcd_hdr
+ .long dcd_hdr
boot_data_ptr:
- .word boot_data
+ .word boot_data
self_ptr:
- .word ivt_header
+ .word ivt_header
app_code_csf:
- .word 0x0
- .word 0x0
+ .word 0x0
+ .word 0x0
boot_data:
- .long fcb_start
+ .long _start
image_len:
- .long CONFIG_U_BOOT_IMG_SIZE
+ .long CONFIG_U_BOOT_IMG_SIZE
plugin:
- .word 0
+ .word 0
ivt_end:
#define DCD_VERSION 0x40
#define MMDC1_MAPSR 0x021b0404
#define MMDC1_MPZQHWCTRL 0x021b0800
#define MMDC1_MPWLGCR 0x021b0808
+ #define MMDC1_MPWLDECTRL0 0x021b080c
+ #define MMDC1_MPWLDECTRL1 0x021b0810
+ #define MMDC1_MPWLDLST 0x021b0814
#define MMDC1_MPODTCTRL 0x021b0818
#define MMDC1_MPRDDQBY0DL 0x021b081c
#define MMDC1_MPRDDQBY1DL 0x021b0820
#define MMDC1_MPRDDQBY2DL 0x021b0824
#define MMDC1_MPRDDQBY3DL 0x021b0828
#define MMDC1_MPDGCTRL0 0x021b083c
+ #define MMDC1_MPDGCTRL1 0x021b0840
+ #define MMDC1_MPDGDLST0 0x021b0844
+ #define MMDC1_MPWRDLST 0x021b0854
#define MMDC1_MPRDDLCTL 0x021b0848
+ #define MMDC1_MPRDDLST 0x021b084c
#define MMDC1_MPWRDLCTL 0x021b0850
+ #define MMDC1_MPWRDLST 0x021b0854
#define MMDC1_MPRDDLHWCTL 0x021b0860
#define MMDC1_MPWRDLHWCTL 0x021b0864
#define MMDC1_MPPDCMPR2 0x021b0890
+ #define MMDC1_MPSWDRDR0 0x021b0898
+ #define MMDC1_MPSWDRDR1 0x021b089c
+ #define MMDC1_MPSWDRDR2 0x021b08a0
+ #define MMDC1_MPSWDRDR3 0x021b08a4
+ #define MMDC1_MPSWDRDR4 0x021b08a8
+ #define MMDC1_MPSWDRDR5 0x021b08ac
+ #define MMDC1_MPSWDRDR6 0x021b08b0
+ #define MMDC1_MPSWDRDR7 0x021b08b4
#define MMDC1_MPMUR0 0x021b08b8
- #define MMDC2_MPZQHWCTRL 0x021b4800
+
+ #if PHYS_SDRAM_1_WIDTH == 64
+ #define MMDC2_MDPDC 0x021b4004
#define MMDC2_MPWLGCR 0x021b4808
+ #define MMDC2_MPWLDECTRL0 0x021b480c
+ #define MMDC2_MPWLDECTRL1 0x021b4810
+ #define MMDC2_MPWLDLST 0x021b4814
#define MMDC2_MPODTCTRL 0x021b4818
#define MMDC2_MPRDDQBY0DL 0x021b481c
#define MMDC2_MPRDDQBY1DL 0x021b4820
#define MMDC2_MPRDDQBY2DL 0x021b4824
#define MMDC2_MPRDDQBY3DL 0x021b4828
#define MMDC2_MPDGCTRL0 0x021b483c
+ #define MMDC2_MPDGCTRL1 0x021b4840
+ #define MMDC2_MPDGDLST0 0x021b4844
#define MMDC2_MPRDDLCTL 0x021b4848
+ #define MMDC2_MPRDDLST 0x021b484c
#define MMDC2_MPWRDLCTL 0x021b4850
+ #define MMDC2_MPWRDLST 0x021b4854
#define MMDC2_MPRDDLHWCTL 0x021b4860
#define MMDC2_MPWRDLHWCTL 0x021b4864
- #define MMDC2_MPMUR0 0x021b48b8
+ #define MMDC2_MPRDDLHWST0 0x021b4868
+ #define MMDC2_MPRDDLHWST1 0x021b486c
+ #define MMDC2_MPWRDLHWST0 0x021b4870
+ #define MMDC2_MPWRDLHWST1 0x021b4874
+ #define MMDC2_MPWLHWERR 0x021b4878
+ #define MMDC2_MPDGHWST0 0x021b487c
+ #define MMDC2_MPDGHWST1 0x021b4880
+ #define MMDC2_MPDGHWST2 0x021b4884
+ #define MMDC2_MPDGHWST3 0x021b4888
+ #define MMDC2_MPSWDAR0 0x021b4894
+ #define MMDC2_MPSWDRDR0 0x021b4898
+ #define MMDC2_MPSWDRDR1 0x021b489c
+ #define MMDC2_MPSWDRDR2 0x021b48a0
+ #define MMDC2_MPSWDRDR3 0x021b48a4
+ #define MMDC2_MPSWDRDR4 0x021b48a8
+ #define MMDC2_MPSWDRDR5 0x021b48ac
+ #define MMDC2_MPSWDRDR6 0x021b48b0
+ #define MMDC2_MPSWDRDR7 0x021b48b4
+ #endif
#ifdef CONFIG_MX6Q
#define IOMUXC_GPR1 0x020e0004
MXC_DCD_ITEM(IOMUXC_UART1_UART_RTS_B_SELECT_INPUT, 0x00000003) /* UART1 RTS INPUT_SEL */
/* NAND */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CLE, 0x00000000) /* NANDF_CLE: NANDF_CLE */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_ALE, 0x00000000) /* NANDF_ALE: NANDF_ALE */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B, 0x00000000) /* NANDF_WP_B: NANDF_WPn */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_READY, 0x00000000) /* NANDF_RB0: NANDF_READY0 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B, 0x00000000) /* NANDF_CS0: NANDF_CS0 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CMD, 0x00000001) /* SD4_CMD: NANDF_RDn */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CLK, 0x00000001) /* SD4_CLK: NANDF_WRn */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00, 0x00000000) /* NANDF_D0: NANDF_D0 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01, 0x00000000) /* NANDF_D1: NANDF_D1 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02, 0x00000000) /* NANDF_D2: NANDF_D2 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03, 0x00000000) /* NANDF_D3: NANDF_D3 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04, 0x00000000) /* NANDF_D4: NANDF_D4 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05, 0x00000000) /* NANDF_D5: NANDF_D5 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06, 0x00000000) /* NANDF_D6: NANDF_D6 */
- MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07, 0x00000000) /* NANDF_D7: NANDF_D7 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CLE, 0x00000000) /* NANDF_CLE: NANDF_CLE */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_ALE, 0x00000000) /* NANDF_ALE: NANDF_ALE */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B, 0x00000000) /* NANDF_WP_B: NANDF_WPn */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_READY, 0x00000000) /* NANDF_RB0: NANDF_READY0 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B, 0x00000000) /* NANDF_CS0: NANDF_CS0 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CMD, 0x00000001) /* SD4_CMD: NANDF_RDn */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CLK, 0x00000001) /* SD4_CLK: NANDF_WRn */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00, 0x00000000) /* NANDF_D0: NANDF_D0 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01, 0x00000000) /* NANDF_D1: NANDF_D1 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02, 0x00000000) /* NANDF_D2: NANDF_D2 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03, 0x00000000) /* NANDF_D3: NANDF_D3 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04, 0x00000000) /* NANDF_D4: NANDF_D4 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05, 0x00000000) /* NANDF_D5: NANDF_D5 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06, 0x00000000) /* NANDF_D6: NANDF_D6 */
+ MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07, 0x00000000) /* NANDF_D7: NANDF_D7 */
/* ext. mem CS */
MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B, 0x00000000) /* NANDF_CS2: NANDF_CS2 */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1, DQM_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2, DQM_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3, DQM_MASK)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4, DQM_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5, DQM_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6, DQM_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7, DQM_MASK)
- #endif
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4, DQM_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5, DQM_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6, DQM_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7, DQM_MASK)
/* DRAM_A[0..15] */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR00, DDR_ADDR_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B1DS, DSE_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B2DS, DSE_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B3DS, DSE_MASK)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B4DS, DSE_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B5DS, DSE_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B6DS, DSE_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B7DS, DSE_MASK)
- #endif
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B4DS, DSE_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B5DS, DSE_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B6DS, DSE_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B7DS, DSE_MASK)
/* ADDDS */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_ADDDS, DSE_MASK)
/* DDRMODE_CTL */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL6, ODT_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL7, ODT_MASK)
#endif
-
/* SDRAM initialization */
/* MPRDDQBY[0..7]DL */
MXC_DCD_ITEM(MMDC1_MPRDDQBY0DL, 0x33333333)
MXC_DCD_ITEM(MMDC1_MPRDDQBY1DL, 0x33333333)
MXC_DCD_ITEM(MMDC1_MPRDDQBY2DL, 0x33333333)
MXC_DCD_ITEM(MMDC1_MPRDDQBY3DL, 0x33333333)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPRDDQBY0DL, 0x33333333)
- MXC_DCD_ITEM(MMDC2_MPRDDQBY1DL, 0x33333333)
- MXC_DCD_ITEM(MMDC2_MPRDDQBY2DL, 0x33333333)
- MXC_DCD_ITEM(MMDC2_MPRDDQBY3DL, 0x33333333)
- #endif
+ MXC_DCD_ITEM_64(MMDC2_MPRDDQBY0DL, 0x33333333)
+ MXC_DCD_ITEM_64(MMDC2_MPRDDQBY1DL, 0x33333333)
+ MXC_DCD_ITEM_64(MMDC2_MPRDDQBY2DL, 0x33333333)
+ MXC_DCD_ITEM_64(MMDC2_MPRDDQBY3DL, 0x33333333)
/* MDMISC */
MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL | 2) /* reset MMDC FSM */
ddr_reset:
MXC_DCD_ITEM(MMDC1_MDOR, MDOR_VAL)
MXC_DCD_ITEM(MMDC1_MDOTC, MDOTC_VAL)
MXC_DCD_ITEM(MMDC1_MDPDC, MDPDC_VAL_0)
+ MXC_DCD_ITEM_64(MMDC2_MDPDC, MDPDC_VAL_0)
MXC_DCD_ITEM(MMDC1_MDASP, (PHYS_SDRAM_1_SIZE + SZ_256M) / SZ_32M - 1) /* MDASP */
/* CS0 MRS: */
MXC_DCD_ITEM(MMDC1_MDREF, 0x0000c000) /* disable refresh */
- MXC_DCD_ITEM(MMDC1_MPODTCTRL, 0x00011112) /* MPODTCTRL */
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPODTCTRL, 0x00011112)
- #endif
+ MXC_DCD_ITEM(MMDC1_MPODTCTRL, 0x00022222) /* MPODTCTRL */
+ MXC_DCD_ITEM_64(MMDC2_MPODTCTRL, 0x00022222)
/* DDR3 calibration */
MXC_DCD_ITEM(MMDC1_MPPDCMPR2, 0x00000003) /* select default compare pattern for DQ calibration */
/* ZQ calibration */
MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008010) /* precharge all */
MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008040) /* MRS: ZQ calibration */
-
MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa139002b)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPZQHWCTRL, 0xa138002b)
- #endif
zq_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPZQHWCTRL, 0x00010000)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, wl_calib)
- /* Write leveling */
MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa1380000)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPZQHWCTRL, 0xa1380000)
- #endif
+ #ifndef DO_WL_CALIB
+ #define WL_DLY_DQS_VAL 30
+ #define WL_DLY_DQS0 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS1 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS2 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS3 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS4 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS5 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS6 (WL_DLY_DQS_VAL + 0)
+ #define WL_DLY_DQS7 (WL_DLY_DQS_VAL + 0)
+ #endif
+ /* Write leveling */
MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 4)) /* MRS: select MPR */
+ #ifdef DO_WL_CALIB
MXC_DCD_ITEM(MMDC1_MDSCR, 0x00808231) /* MRS: start write leveling */
-
MXC_DCD_ITEM(MMDC1_MPWLGCR, 0x00000001) /* initiate Write leveling */
wl_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPWLGCR, 0x00000001)
#if PHYS_SDRAM_1_WIDTH == 64
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPWLGCR, 0x00000001)
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPWLGCR, 0x00000f00)
- #endif
+ #endif /* PHYS_SDRAM_1_WIDTH == 64 */
+ #else
+ MXC_DCD_ITEM(MMDC1_MPWLDECTRL0, (WL_DLY_DQS1 << 16) | (WL_DLY_DQS0 << 0))
+ MXC_DCD_ITEM(MMDC1_MPWLDECTRL1, (WL_DLY_DQS3 << 16) | (WL_DLY_DQS2 << 0))
+ MXC_DCD_ITEM_64(MMDC2_MPWLDECTRL0, (WL_DLY_DQS5 << 16) | (WL_DLY_DQS4 << 0))
+ MXC_DCD_ITEM_64(MMDC2_MPWLDECTRL1, (WL_DLY_DQS7 << 16) | (WL_DLY_DQS6 << 0))
+ wl_calib:
+ #endif /* DO_WL_CALIB */
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, dqs_fifo_reset)
- MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa138002b)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPZQHWCTRL, 0xa138002b)
- #endif
-
MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 1, mr1_val)) /* MRS: end write leveling */
+ MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa138002b)
+
/* DQS gating calibration */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P, SDQS_MASK | 0x7000) /* enable Pullups on DQS pads */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P, SDQS_MASK | 0x7000)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P, SDQS_MASK | 0x7000)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P, SDQS_MASK | 0x7000)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK | 0x7000)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK | 0x7000)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK | 0x7000)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK | 0x7000)
- #endif
- MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL | (7 << 6) | (3 << 16)) /* RALAT/WALAT max. */
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK | 0x7000)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK | 0x7000)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK | 0x7000)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK | 0x7000)
+
+ MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL)
MXC_DCD_ITEM(MMDC1_MDSCR, 0x00008020) /* issue one refresh cycle */
MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
MXC_DCD_ITEM(MMDC1_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
MXC_DCD_ITEM(MMDC1_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
+ MXC_DCD_ITEM_64(MMDC2_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
+ MXC_DCD_ITEM_64(MMDC2_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
MXC_DCD_ITEM(MMDC1_MPMUR0, 0x00000800)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(MMDC2_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
- MXC_DCD_ITEM(MMDC2_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
- MXC_DCD_ITEM(MMDC2_MPMUR0, 0x00000800)
- #endif
-
MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x80000000) /* issue fifo reset */
dqs_fifo_reset:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x80000000)
dqs_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x10000000)
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x00001000)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPDGCTRL0, 0x10000000)
- MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPDGCTRL0, 0x00001000)
- #endif
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, rd_dl_calib)
/* DRAM_SDQS[0..7] pad config */
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P, SDQS_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P, SDQS_MASK)
MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P, SDQS_MASK)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK)
- MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK)
- #endif
-
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK)
+ MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK)
MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL)
/* Read delay calibration */
MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
- MXC_DCD_ITEM(MMDC1_MPRDDLHWCTL, 0x00000030) /* MPRDDLHWCTL: HW_RD_DL_EN */
+ MXC_DCD_ITEM(MMDC1_MPRDDLHWCTL, 0x00000030) /* MPRDDLHWCTL: HW_WR_DL_CMP_CYC | HW_RD_DL_EN */
+ MXC_DCD_ITEM_64(MMDC2_MPRDDLHWCTL, 0x00000030) /* MPRDDLHWCTL: HW_WR_DL_CMP_CYC | HW_RD_DL_EN */
rd_dl_calib:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPRDDLHWCTL, 0x00000010)
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPRDDLHWCTL, 0x0000000f)
- #if PHYS_SDRAM_1_WIDTH == 64
- MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPRDDLHWCTL, 0x00000010)
- MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPRDDLHWCTL, 0x0000000f)
- #endif
+ MXC_DCD_CMD_CHK_64(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPRDDLHWCTL, 0x00000010)
+ MXC_DCD_CMD_CHK_64(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPRDDLHWCTL, 0x0000000f)
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, wr_dl_calib)
MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPWRDLHWCTL, 0x00000010)
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPWRDLHWCTL, 0x0000000f)
#if PHYS_SDRAM_1_WIDTH == 64
+ MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, wr_dl_calib2)
+
+ MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
+ MXC_DCD_ITEM(MMDC2_MPWRDLHWCTL, 0x00000030) /* start WR DL calibration */
+ wr_dl_calib2:
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPWRDLHWCTL, 0x00000010)
MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPWRDLHWCTL, 0x0000000f)
#endif
MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE, con_ack_clr)
MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
- MXC_DCD_ITEM(MMDC1_MDREF, 0x00005800) /* MDREF */
+ MXC_DCD_ITEM(MMDC1_MDREF, (3 << 11) | (0 << 14)) /* 4 cycles per 64kHz period (3.9us) */
MXC_DCD_ITEM(MMDC1_MAPSR, 0x00011006) /* MAPSR */
MXC_DCD_ITEM(MMDC1_MDPDC, MDPDC_VAL_1)
+ MXC_DCD_ITEM_64(MMDC2_MDPDC, MDPDC_VAL_1)
/* MDSCR: Normal operation */
MXC_DCD_ITEM(MMDC1_MDSCR, 0x00000000)
* Pantelis Antoniou <pantelis.antoniou@gmail.com> and
* Matthew McClintock <msm@freescale.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
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <linux/ctype.h>
#include <linux/types.h>
#include <asm/global_data.h>
- #include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>
+ #include <asm/io.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
#define SCRATCHPAD 1024 /* bytes of scratchpad memory */
*/
DECLARE_GLOBAL_DATA_PTR;
- static int fdt_valid(void);
+ static int fdt_valid(struct fdt_header **blobp);
static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
static int fdt_print(const char *pathp, char *prop, int depth);
static int is_printable_string(const void *data, int len);
void set_working_fdt_addr(void *addr)
{
- char buf[17];
+ void *buf;
- working_fdt = addr;
-
- sprintf(buf, "%lx", (unsigned long)addr);
- setenv("fdtaddr", buf);
+ buf = map_sysmem((ulong)addr, 0);
+ working_fdt = buf;
+ setenv_addr("fdtaddr", addr);
}
/*
*/
if (argv[1][0] == 'a') {
unsigned long addr;
+ int control = 0;
+ struct fdt_header *blob;
/*
* Set the address [and length] of the fdt.
*/
- if (argc == 2) {
- if (!fdt_valid()) {
+ argc -= 2;
+ argv += 2;
+ /* Temporary #ifdef - some archs don't have fdt_blob yet */
+ #ifdef CONFIG_OF_CONTROL
+ if (argc && !strcmp(*argv, "-c")) {
+ control = 1;
+ argc--;
+ argv++;
+ }
+ #endif
+ if (argc == 0) {
+ if (control)
+ blob = (struct fdt_header *)gd->fdt_blob;
+ else
+ blob = working_fdt;
+ if (!blob || !fdt_valid(&blob))
return 1;
- }
- printf("The address of the fdt is %p\n", working_fdt);
+ printf("The address of the fdt is %#08lx\n",
+ control ? (ulong)blob :
+ getenv_hex("fdtaddr", 0));
return 0;
}
- addr = simple_strtoul(argv[2], NULL, 16);
- set_working_fdt_addr((void *)addr);
-
- if (!fdt_valid()) {
+ addr = simple_strtoul(argv[0], NULL, 16);
+ blob = map_sysmem(addr, 0);
+ if (!fdt_valid(&blob))
return 1;
- }
+ if (control)
+ gd->fdt_blob = blob;
+ else
+ set_working_fdt_addr(blob);
- if (argc >= 4) {
+ if (argc >= 2) {
int len;
int err;
/*
* Optional new length
*/
- len = simple_strtoul(argv[3], NULL, 16);
- if (len < fdt_totalsize(working_fdt)) {
+ len = simple_strtoul(argv[1], NULL, 16);
+ if (len < fdt_totalsize(blob)) {
printf ("New length %d < existing length %d, "
"ignoring.\n",
- len, fdt_totalsize(working_fdt));
+ len, fdt_totalsize(blob));
} else {
/*
* Open in place with a new length.
*/
- err = fdt_open_into(working_fdt, working_fdt, len);
+ err = fdt_open_into(blob, blob, len);
if (err != 0) {
printf ("libfdt fdt_open_into(): %s\n",
fdt_strerror(err));
* Set the address and length of the fdt.
*/
working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
- if (!fdt_valid()) {
+ if (!fdt_valid(&working_fdt))
return 1;
- }
newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
}
if (subcmd[0] == 's') {
/* get the num nodes at this level */
- char buf[11];
-
- sprintf(buf, "%d", curIndex + 1);
- setenv(var, buf);
+ setenv_ulong(var, curIndex + 1);
} else {
/* node index not found */
printf("libfdt node not found\n");
/****************************************************************************/
- static int fdt_valid(void)
+ /**
+ * fdt_valid() - Check if an FDT is valid. If not, change it to NULL
+ *
+ * @blobp: Pointer to FDT pointer
+ * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL)
+ */
+ static int fdt_valid(struct fdt_header **blobp)
{
- int err;
+ const void *blob = *blobp;
+ int err;
- if (working_fdt == NULL) {
+ if (blob == NULL) {
printf ("The address of the fdt is invalid (NULL).\n");
return 0;
}
- err = fdt_check_header(working_fdt);
+ err = fdt_check_header(blob);
if (err == 0)
return 1; /* valid */
* Be more informative on bad version.
*/
if (err == -FDT_ERR_BADVERSION) {
- if (fdt_version(working_fdt) <
+ if (fdt_version(blob) <
FDT_FIRST_SUPPORTED_VERSION) {
printf (" - too old, fdt %d < %d",
- fdt_version(working_fdt),
+ fdt_version(blob),
FDT_FIRST_SUPPORTED_VERSION);
- working_fdt = NULL;
}
- if (fdt_last_comp_version(working_fdt) >
+ if (fdt_last_comp_version(blob) >
FDT_LAST_SUPPORTED_VERSION) {
printf (" - too new, fdt %d > %d",
- fdt_version(working_fdt),
+ fdt_version(blob),
FDT_LAST_SUPPORTED_VERSION);
- working_fdt = NULL;
}
- return 0;
}
printf("\n");
+ *blobp = NULL;
return 0;
}
return 1;
/********************************************************************/
#ifdef CONFIG_SYS_LONGHELP
static char fdt_help_text[] =
- "addr <addr> [<length>] - Set the fdt location to <addr>\n"
+ "addr [-c] <addr> [<length>] - Set the [control] fdt location to <addr>\n"
#ifdef CONFIG_OF_BOARD_SETUP
"fdt boardsetup - Do board-specific set up\n"
#endif
"fdt rsvmem delete <index> - Delete a mem reserves\n"
"fdt chosen [<start> <end>] - Add/update the /chosen branch in the tree\n"
" <start>/<end> - initrd start/end addr\n"
- "NOTE: Dereference aliases by omiting the leading '/', "
+ "NOTE: Dereference aliases by omitting the leading '/', "
"e.g. fdt print ethernet0.";
#endif
* (C) Copyright 2001-2002
* Wolfgang Denk, DENX Software Engineering -- wd@denx.de
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
/************************************************************************/
#include <common.h>
#include <command.h>
#include <stdarg.h>
+ #include <search.h>
+ #include <env_callback.h>
#include <linux/types.h>
#include <stdio_dev.h>
#if defined(CONFIG_POST)
#include <lcd.h>
#include <watchdog.h>
+ #include <splash.h>
+
#if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
defined(CONFIG_CPU_MONAHANS)
#define CONFIG_CPU_PXA
#include <atmel_lcdc.h>
#endif
+ #if defined(CONFIG_LCD_DT_SIMPLEFB)
+ #include <libfdt.h>
+ #endif
+
/************************************************************************/
/* ** FONT DATA */
/************************************************************************/
#define CONFIG_CONSOLE_SCROLL_LINES 1
#endif
- DECLARE_GLOBAL_DATA_PTR;
+ /************************************************************************/
+ /* ** CONSOLE DEFINITIONS & FUNCTIONS */
+ /************************************************************************/
+ #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+ # define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
+ / VIDEO_FONT_HEIGHT)
+ #else
+ # define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT)
+ #endif
+
+ #define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH)
+ #define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
+ #define CONSOLE_ROW_FIRST lcd_console_address
+ #define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE)
+ #define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \
+ - CONSOLE_ROW_SIZE)
+ #define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+ #define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
- ulong lcd_setmem (ulong addr);
+ #if LCD_BPP == LCD_MONOCHROME
+ # define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
+ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
+ #elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || (LCD_BPP == LCD_COLOR24)
+ # define COLOR_MASK(c) (c)
+ #else
+ # error Unsupported LCD BPP.
+ #endif
+
+ DECLARE_GLOBAL_DATA_PTR;
static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
static inline void lcd_puts_xy(ushort x, ushort y, uchar *s);
static int lcd_init(void *lcdbase);
- static void *lcd_logo (void);
+ static void *lcd_logo(void);
static int lcd_getbgcolor(void);
static void lcd_setfgcolor(int color);
static void lcd_setbgcolor(int color);
+ static int lcd_color_fg;
+ static int lcd_color_bg;
+ int lcd_line_length;
+
char lcd_is_enabled = 0;
- static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
+ static short console_col;
+ static short console_row;
+ static void *lcd_console_address;
+ static void *lcd_base; /* Start of framebuffer memory */
- #ifdef NOT_USED_SO_FAR
- static void lcd_getcolreg(ushort regno,
- ushort *red, ushort *green, ushort *blue);
- static int lcd_getfgcolor(void);
- #endif /* NOT_USED_SO_FAR */
+ static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
/************************************************************************/
/* Clear the last rows */
memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
COLOR_MASK(lcd_color_bg),
- CONSOLE_ROW_SIZE * rows);
+ CONSOLE_ROW_SIZE * rows);
lcd_sync();
console_row -= rows;
{
if (--console_col < 0) {
console_col = CONSOLE_COLS-1 ;
- if (--console_row < 0) {
+ if (--console_row < 0)
console_row = 0;
- }
}
lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
static inline void console_newline(void)
{
- ++console_row;
console_col = 0;
/* Check if we need to scroll the terminal */
- if (console_row >= CONSOLE_ROWS) {
- /* Scroll everything up */
+ if (++console_row >= CONSOLE_ROWS)
console_scrollup();
- } else {
+ else
lcd_sync();
- }
}
/*----------------------------------------------------------------------*/
return;
}
- while (*s) {
+ while (*s)
lcd_putc(*s++);
- }
+
lcd_sync();
}
#endif
#if LCD_BPP == LCD_MONOCHROME
- uchar rest = *d & -(1 << (8-off));
+ uchar rest = *d & -(1 << (8 - off));
uchar sym;
#endif
for (i = 0; i < count; ++i) {
#endif
}
#if LCD_BPP == LCD_MONOCHROME
- *d = rest | (*d & ((1 << (8-off)) - 1));
+ *d = rest | (*d & ((1 << (8 - off)) - 1));
#endif
}
}
#define N_BLK_VERT 2
#define N_BLK_HOR 3
- static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
+ static int test_colors[N_BLK_HOR * N_BLK_VERT] = {
CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW,
CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
};
for (v = 0; v < v_max; ++v) {
uchar iy = v / v_step;
for (h = 0; h < h_max; ++h) {
- uchar ix = N_BLK_HOR * iy + (h/h_step);
+ uchar ix = N_BLK_HOR * iy + h / h_step;
*pix++ = test_colors[ix];
}
}
lcd_base = (void *)gd->fb_base;
- lcd_get_size(&lcd_line_length);
-
lcd_init(lcd_base); /* LCD initialization */
/* Device initialization */
lcddev.putc = lcd_putc; /* 'putc' function */
lcddev.puts = lcd_puts; /* 'puts' function */
- rc = stdio_register (&lcddev);
+ rc = stdio_register(&lcddev);
return (rc == 0) ? 1 : rc;
}
/* set framebuffer to background color */
memset((char *)lcd_base,
COLOR_MASK(lcd_getbgcolor()),
- lcd_line_length*panel_info.vl_row);
+ lcd_line_length * panel_info.vl_row);
#endif
/* Paint the logo and retrieve LCD base address */
debug("[LCD] Drawing the logo @ %p...\n", lcd_base);
lcdbase);
lcd_ctrl_init(lcdbase);
+
+ /*
+ * lcd_ctrl_init() of some drivers (i.e. bcm2835 on rpi_b) ignores
+ * the 'lcdbase' argument and uses custom lcd base address
+ * by setting up gd->fb_base. Check for this condition and fixup
+ * 'lcd_base' address.
+ */
+ if ((unsigned long)lcdbase != gd->fb_base)
+ lcd_base = (void *)gd->fb_base;
+
+ debug("[LCD] Using LCD frambuffer at %p\n", lcd_base);
+
+ lcd_get_size(&lcd_line_length);
+ lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
lcd_is_enabled = 1;
lcd_clear();
lcd_enable();
/* Allocate pages for the frame buffer. */
addr -= size;
- debug("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
+ debug("Reserving %ldk for LCD Framebuffer at: %08lx\n",
+ size >> 10, addr);
return addr;
}
/*----------------------------------------------------------------------*/
- #ifdef NOT_USED_SO_FAR
- static int lcd_getfgcolor(void)
+ int lcd_getfgcolor(void)
{
return lcd_color_fg;
}
- #endif /* NOT_USED_SO_FAR */
/*----------------------------------------------------------------------*/
return lcd_color_bg;
}
- /*----------------------------------------------------------------------*/
-
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0));
#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB)
return panel_info.cmap;
- #else
- #if defined(CONFIG_LCD_LOGO)
+ #elif defined(CONFIG_LCD_LOGO)
return bmp_logo_palette;
#else
return NULL;
#endif
- #endif
}
#ifdef CONFIG_LCD_LOGO
immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
#endif
+ unsigned bpix = NBITS(panel_info.vl_bpix);
debug("Logo: width %d height %d colors %d cmap %d\n",
BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
ARRAY_SIZE(bmp_logo_palette));
bmap = &bmp_logo_bitmap[0];
- fb = (uchar *)(lcd_base + y * lcd_line_length + x);
+ fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8);
- if (NBITS(panel_info.vl_bpix) < 12) {
+ if (bpix < 12) {
/* Leave room for default color map
* default case: generic system with no cmap (most likely 16bpp)
* cmap was set to the source palette, so no change is done.
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
memcpy(fb, bmap, BMP_LOGO_WIDTH);
bmap += BMP_LOGO_WIDTH;
- fb += panel_info.vl_col;
+ fb += panel_info.vl_col;
}
} else if (NBITS(panel_info.vl_bpix) == 16) {
u16 col16;
- fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
+ fb16 = (ushort *)fb;
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
for (j = 0; j < BMP_LOGO_WIDTH; j++) {
col16 = bmp_logo_palette[(bmap[j]-16)];
*fb++ = c;
cnt--;
}
- (*fbp) = fb;
+ *fbp = fb;
}
/*
- * Do not call this function directly, must be called from
- * lcd_display_bitmap.
+ * Do not call this function directly, must be called from lcd_display_bitmap.
*/
static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb,
int x_off, int y_off)
unsigned long long colors;
unsigned bpix, bmp_bpix;
- if (!bmp || !((bmp->header.signature[0] == 'B') &&
- (bmp->header.signature[1] == 'M'))) {
+ if (!bmp || !(bmp->header.signature[0] == 'B' &&
+ bmp->header.signature[1] == 'M')) {
printf("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
bpix = NBITS(panel_info.vl_bpix);
- if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 32)) {
+ if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, bmp_bpix);
}
bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
- fb = (uchar *) (lcd_base +
+ fb = (uchar *)(lcd_base +
(y + height - 1) * lcd_line_length + x * bpix / 8);
switch (bmp_bpix) {
fb_put_word(&fb, &bmap);
bmap += (padded_width - width) * 2;
- fb -= width * 2 + lcd_line_length;
+ fb -= width * 2 + lcd_line_length;
}
break;
#endif /* CONFIG_BMP_16BPP */
fb[2] = *bmap++; /* R */
fb += 4;
}
- fb -= width * 4 + lcd_line_length;
+ bmap += (padded_width - width) * 4;
+ fb -= lcd_line_length + width * (bpix / 8);
}
break;
};
do_splash = 0;
+ if (splash_screen_prepare())
+ return (void *)lcd_base;
+
addr = simple_strtoul (s, &end, 16);
if (addr == 0 || *end != '\0')
return lcd_base;
- #ifdef CONFIG_SPLASH_SCREEN_ALIGN
- s = getenv("splashpos");
- if (s != NULL) {
- if (s[0] == 'm')
- x = BMP_ALIGN_CENTER;
- else
- x = simple_strtol(s, NULL, 0);
-
- s = strchr(s + 1, ',');
- if (s != NULL) {
- if (s[1] == 'm')
- y = BMP_ALIGN_CENTER;
- else
- y = simple_strtol (s + 1, NULL, 0);
- }
- }
- #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+
+ splash_get_pos(&x, &y);
if (bmp_display(addr, x, y) == 0)
return (void *)lcd_base;
#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
}
+ #ifdef CONFIG_SPLASHIMAGE_GUARD
+ static int on_splashimage(const char *name, const char *value, enum env_op op,
+ int flags)
+ {
+ ulong addr;
+ int aligned;
+
+ if (op == env_op_delete)
+ return 0;
+
+ addr = simple_strtoul(value, NULL, 16);
+ /* See README.displaying-bmps */
+ aligned = (addr % 4 == 2);
+ if (!aligned) {
+ printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
+ #endif
+
void lcd_position_cursor(unsigned col, unsigned row)
{
console_col = min(col, CONSOLE_COLS - 1);
return CONSOLE_COLS;
}
- /************************************************************************/
- /************************************************************************/
+ #if defined(CONFIG_LCD_DT_SIMPLEFB)
+ static int lcd_dt_simplefb_configure_node(void *blob, int off)
+ {
+ u32 stride;
+ fdt32_t cells[2];
+ int ret;
+ static const char format[] =
+ #if LCD_BPP == LCD_COLOR16
+ "r5g6b5";
+ #else
+ "";
+ #endif
+
+ if (!format[0])
+ return -1;
+
+ stride = panel_info.vl_col * 2;
+
+ cells[0] = cpu_to_fdt32(gd->fb_base);
+ cells[1] = cpu_to_fdt32(stride * panel_info.vl_row);
+ ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2);
+ if (ret < 0)
+ return -1;
+
+ cells[0] = cpu_to_fdt32(panel_info.vl_col);
+ ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0]));
+ if (ret < 0)
+ return -1;
+
+ cells[0] = cpu_to_fdt32(panel_info.vl_row);
+ ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0]));
+ if (ret < 0)
+ return -1;
+
+ cells[0] = cpu_to_fdt32(stride);
+ ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0]));
+ if (ret < 0)
+ return -1;
+
+ ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1);
+ if (ret < 0)
+ return -1;
+
+ ret = fdt_delprop(blob, off, "status");
+ if (ret < 0)
+ return -1;
+
+ return 0;
+ }
+
+ int lcd_dt_simplefb_add_node(void *blob)
+ {
+ static const char compat[] = "simple-framebuffer";
+ static const char disabled[] = "disabled";
+ int off, ret;
+
+ off = fdt_add_subnode(blob, 0, "framebuffer");
+ if (off < 0)
+ return -1;
+
+ ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled));
+ if (ret < 0)
+ return -1;
+
+ ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat));
+ if (ret < 0)
+ return -1;
+
+ return lcd_dt_simplefb_configure_node(blob, off);
+ }
+
+ int lcd_dt_simplefb_enable_existing_node(void *blob)
+ {
+ int off;
+
+ off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
+ if (off < 0)
+ return -1;
+
+ return lcd_dt_simplefb_configure_node(blob, off);
+ }
+ #endif
* (C) Copyright 2003
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
- * 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
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
else if (cmd->resp_type & MMC_RSP_PRESENT)
xfertyp |= XFERTYP_RSPTYP_48;
- #ifdef CONFIG_MX53
+ #if defined(CONFIG_MX53) || defined(CONFIG_T4240QDS)
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
xfertyp |= XFERTYP_CMDTYP_ABORT;
#endif
return 0;
}
- static void check_and_invalidate_dcache_range(struct mmc_cmd *cmd,
+ static inline void check_and_invalidate_dcache_range(struct mmc_cmd *cmd,
struct mmc_data *data)
{
- unsigned start = (unsigned)data->dest;
- unsigned size = roundup(ARCH_DMA_MINALIGN,
- data->blocks * data->blocksize);
- unsigned end = start + size;
+ unsigned long start = (unsigned long)data->dest;
+ size_t start_ofs = start & (ARCH_DMA_MINALIGN - 1);
+ unsigned long size = data->blocks * data->blocksize;
+ unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN);
+ start -= start_ofs;
invalidate_dcache_range(start, end);
}
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
return 0;
#endif
-
esdhc_write32(®s->irqstat, -1);
sync();
/* Figure out the transfer arguments */
xfertyp = esdhc_xfertyp(cmd, data);
+ /* Mask all irqs */
+ esdhc_write32(®s->irqsigen, 0);
+
/* Send the command */
esdhc_write32(®s->cmdarg, cmd->cmdarg);
#if defined(CONFIG_FSL_USDHC)
check_and_invalidate_dcache_range(cmd, data);
irqstat = esdhc_read32(®s->irqstat);
- esdhc_write32(®s->irqstat, irqstat);
/* Reset CMD and DATA portions on error */
if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
#else
unsigned long start = get_timer_masked();
unsigned long data_timeout = data->blocks *
- data->blocksize * 100 / mmc->bus_width /
+ (data->blocksize + 100) * 8 / mmc->bus_width /
(mmc->tran_speed / CONFIG_SYS_HZ) + CONFIG_SYS_HZ;
do {
int timeout = 1000;
/* Reset the entire host controller */
- esdhc_write32(®s->sysctl, SYSCTL_RSTA);
+ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA);
/* Wait until the controller is available */
while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout)
esdhc_write32(®s->scr, 0x00000040);
#endif
- esdhc_write32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+ esdhc_setbits32(®s->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
/* Set the initial clock speed */
mmc_set_clock(mmc, 400000);
unsigned long timeout = 100; /* wait max 100 ms */
/* reset the controller */
- esdhc_write32(®s->sysctl, SYSCTL_RSTA);
+ esdhc_setbits32(®s->sysctl, SYSCTL_RSTA);
/* hardware clears the bit when it is done */
while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA) && --timeout)
mmc->set_ios = esdhc_set_ios;
mmc->init = esdhc_init;
mmc->getcd = esdhc_getcd;
+ mmc->getwp = NULL;
voltage_caps = 0;
caps = regs->hostcapblt;
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+ if (cfg->max_bus_width > 0) {
+ if (cfg->max_bus_width < 8)
+ mmc->host_caps &= ~MMC_MODE_8BIT;
+ if (cfg->max_bus_width < 4)
+ mmc->host_caps &= ~MMC_MODE_4BIT;
+ }
+
if (caps & ESDHC_HOSTCAPBLT_HSS)
mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
#include <i2c.h>
#include <twl4030.h>
#include <twl6030.h>
- #include <twl6035.h>
+ #include <palmas.h>
+ #include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#define SYSCTL_SRC (1 << 25)
#define SYSCTL_SRD (1 << 26)
+ struct omap_hsmmc_data {
+ struct hsmmc *base_addr;
+ int cd_gpio;
+ int wp_gpio;
+ };
+
/* If we fail after 1 second wait, something is really bad */
#define MAX_RETRY_MS 1000
static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
unsigned int siz);
- static struct mmc hsmmc_dev[2];
+ static struct mmc hsmmc_dev[3];
+ static struct omap_hsmmc_data hsmmc_dev_data[3];
+
+ #if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \
+ (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT))
+ static int omap_mmc_setup_gpio_in(int gpio, const char *label)
+ {
+ if (!gpio_is_valid(gpio))
+ return -1;
+
+ if (gpio_request(gpio, label) < 0)
+ return -1;
+
+ if (gpio_direction_input(gpio) < 0)
+ return -1;
+
+ return gpio;
+ }
+
+ static int omap_mmc_getcd(struct mmc *mmc)
+ {
+ int cd_gpio = ((struct omap_hsmmc_data *)mmc->priv)->cd_gpio;
+ return gpio_get_value(cd_gpio);
+ }
+
+ static int omap_mmc_getwp(struct mmc *mmc)
+ {
+ int wp_gpio = ((struct omap_hsmmc_data *)mmc->priv)->wp_gpio;
+ return gpio_get_value(wp_gpio);
+ }
+ #else
+ static inline int omap_mmc_setup_gpio_in(int gpio, const char *label)
+ {
+ return -1;
+ }
+
+ #define omap_mmc_getcd NULL
+ #define omap_mmc_getwp NULL
+ #endif
#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER)
static void omap4_vmmc_pbias_config(struct mmc *mmc)
{
u32 value = 0;
- struct omap_sys_ctrl_regs *const ctrl =
- (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
-
- value = readl(&ctrl->control_pbiaslite);
+ value = readl((*ctrl)->control_pbiaslite);
value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ);
- writel(value, &ctrl->control_pbiaslite);
+ writel(value, (*ctrl)->control_pbiaslite);
/* set VMMC to 3V */
twl6030_power_mmc_init();
- value = readl(&ctrl->control_pbiaslite);
+ value = readl((*ctrl)->control_pbiaslite);
value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ;
- writel(value, &ctrl->control_pbiaslite);
+ writel(value, (*ctrl)->control_pbiaslite);
}
#endif
- #if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER)
+ #if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER)
static void omap5_pbias_config(struct mmc *mmc)
{
u32 value = 0;
- struct omap_sys_ctrl_regs *const ctrl =
- (struct omap_sys_ctrl_regs *) SYSCTRL_GENERAL_CORE_BASE;
-
- value = readl(&ctrl->control_pbias);
- value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);
- value |= SDCARD_BIAS_HIZ_MODE;
- writel(value, &ctrl->control_pbias);
-
- twl6035_mmc1_poweron_ldo();
-
- value = readl(&ctrl->control_pbias);
- value &= ~SDCARD_BIAS_HIZ_MODE;
- value |= SDCARD_PBIASLITE_VMODE | SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ;
- writel(value, &ctrl->control_pbias);
-
- value = readl(&ctrl->control_pbias);
- if (value & (1 << 23)) {
- value &= ~(SDCARD_PWRDNZ | SDCARD_BIAS_PWRDNZ);
- value |= SDCARD_BIAS_HIZ_MODE;
- writel(value, &ctrl->control_pbias);
- }
+
+ value = readl((*ctrl)->control_pbias);
+ value &= ~SDCARD_PWRDNZ;
+ writel(value, (*ctrl)->control_pbias);
+ udelay(10); /* wait 10 us */
+ value &= ~SDCARD_BIAS_PWRDNZ;
+ writel(value, (*ctrl)->control_pbias);
+
+ palmas_mmc1_poweron_ldo();
+
+ value = readl((*ctrl)->control_pbias);
+ value |= SDCARD_BIAS_PWRDNZ;
+ writel(value, (*ctrl)->control_pbias);
+ udelay(150); /* wait 150 us */
+ value |= SDCARD_PWRDNZ;
+ writel(value, (*ctrl)->control_pbias);
+ udelay(150); /* wait 150 us */
}
#endif
if (mmc->block_dev.dev == 0)
omap4_vmmc_pbias_config(mmc);
#endif
- #if defined(CONFIG_OMAP54XX) && defined(CONFIG_TWL6035_POWER)
+ #if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER)
if (mmc->block_dev.dev == 0)
omap5_pbias_config(mmc);
#endif
static int mmc_init_setup(struct mmc *mmc)
{
- struct hsmmc *mmc_base = (struct hsmmc *)mmc->priv;
- struct hsmmc *mmc_base;
++ struct omap_hsmmc_data *priv_data = mmc->priv;
++ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int reg_val;
unsigned int dsor;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
mmc_board_init(mmc);
writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
- struct hsmmc *mmc_base = mmc->priv;
- struct hsmmc *mmc_base;
++ struct omap_hsmmc_data *priv_data = mmc->priv;
++ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int flags, mmc_stat;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
start = get_timer(0);
while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
if (get_timer(start) > MAX_RETRY_MS) {
static void mmc_set_ios(struct mmc *mmc)
{
- struct hsmmc *mmc_base = (struct hsmmc *)mmc->priv;
- struct hsmmc *mmc_base;
++ struct omap_hsmmc_data *priv_data = mmc->priv;
++ struct hsmmc *mmc_base = priv_data->base_addr;
unsigned int dsor = 0;
ulong start;
- mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
/* configue bus width */
switch (mmc->bus_width) {
case 8:
writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
}
- int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max)
+ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
+ int wp_gpio)
{
- struct mmc *mmc;
-
- mmc = &hsmmc_dev[dev_index];
+ struct mmc *mmc = &hsmmc_dev[dev_index];
+ struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
sprintf(mmc->name, "OMAP SD/MMC");
mmc->send_cmd = mmc_send_cmd;
mmc->set_ios = mmc_set_ios;
mmc->init = mmc_init_setup;
- mmc->getcd = NULL;
+ mmc->priv = priv_data;
switch (dev_index) {
case 0:
- mmc->priv = (struct hsmmc *)OMAP_HSMMC1_BASE;
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
break;
#ifdef OMAP_HSMMC2_BASE
case 1:
- mmc->priv = (struct hsmmc *)OMAP_HSMMC2_BASE;
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE;
break;
#endif
#ifdef OMAP_HSMMC3_BASE
case 2:
- mmc->priv = (struct hsmmc *)OMAP_HSMMC3_BASE;
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE;
break;
#endif
default:
- mmc->priv = (struct hsmmc *)OMAP_HSMMC1_BASE;
+ priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
return 1;
}
+ priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd");
+ if (priv_data->cd_gpio != -1)
+ mmc->getcd = omap_mmc_getcd;
+
+ priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
+ if (priv_data->wp_gpio != -1)
+ mmc->getwp = omap_mmc_getwp;
+
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
mmc->host_caps = (MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
MMC_MODE_HC) & ~host_caps_mask;
#include <asm/arch/imx-regs.h>
#endif
- #ifdef DEBUG
- #define pr_debug(fmt...) printk(fmt)
- #else
- #define pr_debug(fmt...) do { } while (0)
- #endif
-
- typedef enum _bool { false, true } bool;
-
static struct mxc_nand_host mxc_host;
static struct mxc_nand_host *host = &mxc_host;
#define nfc_is_v3_2() 1
#define nfc_is_v3() nfc_is_v3_2()
#define NFC_VERSION "V3"
- #ifndef CONFIG_MXC_NAND_IP_BASE
- #error CONFIG_MXC_NAND_IP_BASE not defined
+ #ifndef CONFIG_MXC_NAND_IP_REGS_BASE
+ #error CONFIG_MXC_NAND_IP_REGS_BASE not defined
#endif
#else
#error mxc_nand driver not supported on this platform
#define NFC_VERSION "unknown"
#endif
- #ifndef CONFIG_MXC_NAND_IP_BASE
- #define CONFIG_MXC_NAND_IP_BASE 0
-#ifndef CONFIG_MXC_NAND_IP_REGS_BASE
-#define CONFIG_MXC_NAND_IP_REGS_BASE 0
--#endif
--
/* Addresses for NFC registers */
#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
#define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
this->ecc.bytes = 3;
host->eccsize = 1;
} else if (nfc_is_v3_2()) {
- host->regs_ip = (void __iomem *)CONFIG_MXC_NAND_IP_BASE;
+ host->regs_ip = (void __iomem *)CONFIG_MXC_NAND_IP_REGS_BASE;
host->regs_axi = host->base + 0x1e00;
host->spare0 = host->base + 0x1000;
host->spare_len = 64;
host->get_dev_status = get_dev_status_v3;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
+ this->ecc.strength = 4;
} else
hang();
this->options |= NAND_BUSWIDTH_16;
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
- this->options |= NAND_USE_FLASH_BBT;
+ this->bbt_options |= NAND_BBT_USE_FLASH;
this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr;
this->bbt_td->options |= NAND_BBT_CREATE;
* (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
* (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
return val;
}
- static void fec_mii_setspeed(struct fec_priv *fec)
+ static void fec_mii_setspeed(struct ethernet_regs *eth)
{
/*
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
*/
writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
- &fec->eth->mii_speed);
- debug("%s: mii_speed %08x\n", __func__, readl(&fec->eth->mii_speed));
+ ð->mii_speed);
+ debug("%s: mii_speed %08x\n", __func__, readl(ð->mii_speed));
}
static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
return 0;
}
- static void fec_eth_phy_config(struct eth_device *dev)
- {
- #ifdef CONFIG_PHYLIB
- struct fec_priv *fec = (struct fec_priv *)dev->priv;
- struct phy_device *phydev;
-
- if (fec->phy_id < 0) {
- int phy_id;
-
- for (phy_id = 0; phy_id < 32; phy_id++) {
- debug("%s: Probing PHY ID %02x\n", __func__, phy_id);
- phydev = phy_connect(fec->bus, phy_id, dev,
- PHY_INTERFACE_MODE_RGMII);
-
- if (phydev)
- break;
- }
- } else {
- phydev = phy_connect(fec->bus, fec->phy_id, dev,
- PHY_INTERFACE_MODE_RGMII);
- }
- if (phydev) {
- fec->phydev = phydev;
- phy_config(phydev);
- }
- #endif
- }
-
/*
* Do initial configuration of the FEC registers
*/
#endif
#ifdef CONFIG_PHYLIB
- if (!fec->phydev)
- fec_eth_phy_config(edev);
- if (fec->phydev) {
+ {
/* Start up the PHY */
int ret = phy_startup(fec->phydev);
return ret;
}
speed = fec->phydev->speed;
- } else {
- speed = _100BASET;
}
#else
miiphy_wait_aneg(edev);
{
u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
+
if (speed == _1000BASET)
ecr |= FEC_ECNTRL_SPEED;
else if (speed != _100BASET)
}
memset(fec->tbd_base, 0, size);
fec_tbd_init(fec);
- flush_dcache_range((unsigned)fec->tbd_base, size);
}
/*
fec_reg_setup(fec);
if (fec->xcv_type != SEVENWIRE)
- fec_mii_setspeed(fec);
+ fec_mii_setspeed(fec->bus->priv);
/*
* Set Opcode/Pause Duration Register
uint32_t size, end;
uint32_t addr;
int timeout = FEC_XFER_TIMEOUT;
+ int ret = 0;
/*
* This routine transmits one frame. This routine only accepts
flush_dcache_range(addr, end);
writew(length, &fec->tbd_base[fec->tbd_index].data_length);
- writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
+ writel((unsigned long)packet,
+ &fec->tbd_base[fec->tbd_index].data_pointer);
/*
* update BD's status now
addr = (uint32_t)fec->tbd_base;
flush_dcache_range(addr, addr + size);
+ /*
+ * Below we read the DMA descriptor's last four bytes back from the
+ * DRAM. This is important in order to make sure that all WRITE
+ * operations on the bus that were triggered by previous cache FLUSH
+ * have completed.
+ *
+ * Otherwise, on MX28, it is possible to observe a corruption of the
+ * DMA descriptors. Please refer to schematic "Figure 1-2" in MX28RM
+ * for the bus structure of MX28. The scenario is as follows:
+ *
+ * 1) ARM core triggers a series of WRITEs on the AHB_ARB2 bus going
+ * to DRAM due to flush_dcache_range()
+ * 2) ARM core writes the FEC registers via AHB_ARB2
+ * 3) FEC DMA starts reading/writing from/to DRAM via AHB_ARB3
+ *
+ * Note that 2) does sometimes finish before 1) due to reordering of
+ * WRITE accesses on the AHB bus, therefore triggering 3) before the
+ * DMA descriptor is fully written into DRAM. This results in occasional
+ * corruption of the DMA descriptor.
+ */
+ readl(addr + size - 4);
+
/*
* Enable SmartDMA transmit task
*/
* invalidate data cache to see what's really in RAM. Also, we need
* barrier here.
*/
- invalidate_dcache_range(addr, addr + size);
- while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) {
- if (--timeout < 0)
- return -ETIMEDOUT;
- udelay(1);
- invalidate_dcache_range(addr, addr + size);
+ while (--timeout) {
+ if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
+ break;
}
- debug("fec_send: status 0x%04x index %d\n",
+ if (!timeout)
+ ret = -EINVAL;
+
+ invalidate_dcache_range(addr, addr + size);
+ if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY)
+ ret = -EINVAL;
+
+ debug("fec_send: status 0x%x index %d ret %i\n",
readw(&fec->tbd_base[fec->tbd_index].status),
- fec->tbd_index);
+ fec->tbd_index, ret);
/* for next transmission use the other buffer */
if (fec->tbd_index)
fec->tbd_index = 0;
else
fec->tbd_index = 1;
- return 0;
+ return ret;
}
/**
return len;
}
- static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
+ static void fec_set_dev_name(char *dest, int dev_id)
+ {
+ sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id);
+ }
+
+ #ifdef CONFIG_PHYLIB
+ int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+ struct mii_dev *bus, struct phy_device *phydev)
+ #else
+ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+ struct mii_dev *bus, int phy_id)
+ #endif
{
struct eth_device *edev;
struct fec_priv *fec;
- struct mii_dev *bus;
unsigned char ethaddr[6];
uint32_t start;
int ret = 0;
}
fec_reg_setup(fec);
- fec_mii_setspeed(fec);
-
- if (dev_id == -1) {
- sprintf(edev->name, "FEC");
- fec->dev_id = 0;
- } else {
- sprintf(edev->name, "FEC%i", dev_id);
- fec->dev_id = dev_id;
- }
- fec->phy_id = phy_id;
-
- bus = mdio_alloc();
- if (!bus) {
- printf("mdio_alloc failed\n");
- ret = -ENOMEM;
- goto err3;
- }
- bus->read = fec_phy_read;
- bus->write = fec_phy_write;
- sprintf(bus->name, edev->name);
- #ifdef CONFIG_MX28
- /*
- * The i.MX28 has two ethernet interfaces, but they are not equal.
- * Only the first one can access the MDIO bus.
- */
- bus->priv = (struct ethernet_regs *)MXS_ENET0_BASE;
+ fec_set_dev_name(edev->name, dev_id);
+ fec->dev_id = (dev_id == -1) ? 0 : dev_id;
+ fec->bus = bus;
+ fec_mii_setspeed(bus->priv);
+ #ifdef CONFIG_PHYLIB
+ fec->phydev = phydev;
+ phy_connect_dev(phydev, edev);
+ /* Configure phy */
+ phy_config(phydev);
#else
- bus->priv = fec->eth;
+ fec->phy_id = phy_id;
#endif
- ret = mdio_register(bus);
- if (ret) {
- printf("mdio_register failed\n");
- free(bus);
- ret = -ENOMEM;
- goto err3;
- }
- fec->bus = bus;
eth_register(edev);
if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
memcpy(edev->enetaddr, ethaddr, 6);
}
- /* Configure phy */
- fec_eth_phy_config(edev);
return ret;
-
err3:
free(fec);
err2:
return ret;
}
- #ifndef CONFIG_FEC_MXC_MULTI
- int fecmxc_initialize(bd_t *bd)
+ struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
{
- int lout = 1;
+ struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
+ struct mii_dev *bus;
+ int ret;
- debug("eth_init: fec_probe(PHY %02x FEC: %08x)\n",
- CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
- lout = fec_probe(bd, -1, CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
+ bus = mdio_alloc();
+ if (!bus) {
+ printf("mdio_alloc failed\n");
+ return NULL;
+ }
+ bus->read = fec_phy_read;
+ bus->write = fec_phy_write;
+ bus->priv = eth;
+ fec_set_dev_name(bus->name, dev_id);
- return lout;
+ ret = mdio_register(bus);
+ if (ret) {
+ printf("mdio_register failed\n");
+ free(bus);
+ return NULL;
+ }
+ fec_mii_setspeed(eth);
+ return bus;
}
- #endif
int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
{
- int lout = 1;
+ uint32_t base_mii;
+ struct mii_dev *bus = NULL;
+ #ifdef CONFIG_PHYLIB
+ struct phy_device *phydev = NULL;
+ #endif
+ int ret;
+ #ifdef CONFIG_MX28
+ /*
+ * The i.MX28 has two ethernet interfaces, but they are not equal.
+ * Only the first one can access the MDIO bus.
+ */
+ base_mii = MXS_ENET0_BASE;
+ #else
+ base_mii = addr;
+ #endif
debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
- lout = fec_probe(bd, dev_id, phy_id, addr);
+ bus = fec_get_miibus(base_mii, dev_id);
+ if (!bus)
+ return -ENOMEM;
+ #ifdef CONFIG_PHYLIB
+ phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);
+ if (!phydev) {
+ free(bus);
+ return -ENOMEM;
+ }
+ ret = fec_probe(bd, dev_id, addr, bus, phydev);
+ #else
+ ret = fec_probe(bd, dev_id, addr, bus, phy_id);
+ #endif
+ if (ret) {
+ #ifdef CONFIG_PHYLIB
+ free(phydev);
+ #endif
+ free(bus);
+ }
+ return ret;
+ }
- return lout;
+ #ifdef CONFIG_FEC_MXC_PHYADDR
+ int fecmxc_initialize(bd_t *bd)
+ {
+ return fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR,
+ IMX_FEC_BASE);
}
+ #endif
#ifndef CONFIG_PHYLIB
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
*
* (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
/* #define DEBUG */
#include "ipu_regs.h"
+ static struct mxc_ccm_reg __maybe_unused *mxc_ccm = (void *)CCM_BASE_ADDR;
+
struct ipu_ch_param_word {
uint32_t data[5];
uint32_t res[3];
temp1; \
})
- int clk_get_usecount(struct clk *clk)
- {
- if (clk == NULL)
- return 0;
-
- return clk->usecount;
- }
-
- u32 clk_get_rate(struct clk *clk)
- {
- if (!clk)
- return 0;
-
- return clk->rate;
- }
-
- struct clk *clk_get_parent(struct clk *clk)
- {
- if (!clk)
- return 0;
-
- return clk->parent;
- }
-
- int clk_set_rate(struct clk *clk, unsigned long rate)
- {
- if (clk && clk->set_rate)
- clk->set_rate(clk, rate);
- return clk->rate;
- }
-
- long clk_round_rate(struct clk *clk, unsigned long rate)
- {
- if (clk == NULL || !clk->round_rate)
- return 0;
-
- return clk->round_rate(clk, rate);
- }
-
- int clk_set_parent(struct clk *clk, struct clk *parent)
- {
- debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
- clk ? clk->parent : NULL);
-
- if (!clk || clk == parent)
- return 0;
-
- if (clk->set_parent) {
- int ret;
-
- ret = clk->set_parent(clk, parent);
- if (ret)
- return ret;
- }
- clk->parent = parent;
- return 0;
- }
+ #define IPU_SW_RST_TOUT_USEC (10000)
static int clk_ipu_enable(struct clk *clk)
{
static struct clk ipu_clk = {
.name = "ipu_clk",
- #if defined(CONFIG_IPUV3_CLK)
.rate = CONFIG_IPUV3_CLK,
+ #if defined(CONFIG_MX51) || defined(CONFIG_MX53)
+ .enable_reg = (u32 *)(CCM_BASE_ADDR +
+ offsetof(struct mxc_ccm_reg, CCGR5)),
+ .enable_shift = MXC_CCM_CCGR5_IPU_OFFSET,
+ #else
+ .enable_reg = (u32 *)(CCM_BASE_ADDR +
+ offsetof(struct mxc_ccm_reg, CCGR3)),
+ .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET,
#endif
.enable = clk_ipu_enable,
.disable = clk_ipu_disable,
};
+ static struct clk ldb_clk = {
+ .name = "ldb_clk",
+ .rate = 65000000,
+ };
+
/* Globals */
struct clk *g_ipu_clk;
+ struct clk *g_ldb_clk;
struct clk *g_di_clk[2];
struct clk *g_pixel_clk[2];
unsigned char g_dc_di_assignment[10];
if (parent == g_ipu_clk)
di_gen &= ~DI_GEN_DI_CLK_EXT;
- else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_di_clk[clk->id])
+ else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_ldb_clk)
di_gen |= DI_GEN_DI_CLK_EXT;
else
goto err;
if (ret)
goto err;
__raw_writel(di_gen, DI_GENERAL(clk->id));
-debug("%s@%d:\n", __func__, __LINE__);
ipu_pixel_clk_recalc(clk);
clk->disable(clk->parent);
clk->parent = parent;
{
u32 *reg;
u32 value;
+ int timeout = IPU_SW_RST_TOUT_USEC;
reg = (u32 *)SRC_BASE_ADDR;
value = __raw_readl(reg);
value = value | SW_IPU_RST;
__raw_writel(value, reg);
+
+ while (__raw_readl(reg) & SW_IPU_RST) {
+ udelay(1);
+ if (!(timeout--)) {
+ printf("ipu software reset timeout\n");
+ break;
+ }
+ };
}
/*
int ret;
void *ipu_base;
unsigned long start;
-
- #if defined(CONFIG_MXC_HSC)
+ #if defined CONFIG_MX51
u32 temp;
u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR;
u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800);
temp = __raw_readl(reg_hsc_mxt_conf);
__raw_writel(temp | 0x10000, reg_hsc_mxt_conf);
#endif
- ipu_base = (void *)IPU_CTRL_BASE_ADDR;
+ ipu_base = (void *)IPU_SOC_BASE_ADDR;
/* base fixup */
if (gd->arch.ipu_hw_rev == IPUV3_HW_REV_IPUV3H) /* IPUv3H */
ipu_base += IPUV3H_REG_BASE;
g_ipu_clk = &ipu_clk;
debug("ipu_clk = %u\n", clk_get_rate(g_ipu_clk));
+ g_ldb_clk = &ldb_clk;
+ debug("ldb_clk = %u\n", clk_get_rate(g_ldb_clk));
+
ret = clk_enable(g_ipu_clk);
if (ret)
return ret;
ipu_reset();
if (di_clk_parent == DI_PCLK_LDB) {
- clk_set_parent(g_pixel_clk[di], g_di_clk[di]);
+ clk_set_parent(g_pixel_clk[di], g_ldb_clk);
} else {
clk_set_parent(g_pixel_clk[0], g_ipu_clk);
clk_set_parent(g_pixel_clk[1], g_ipu_clk);
__raw_writel(ipu_conf, IPU_CONF);
+ /* clear interrupt status */
+ __raw_writel(__raw_readl(IPU_STAT), IPU_STAT);
+
if (ipu_conf == 0) {
clk_disable(g_ipu_clk);
g_ipu_clk_enabled = 0;
}
-
}
static inline void ipu_ch_param_dump(int ch)
{
#ifdef DEBUG
struct ipu_ch_param *p = ipu_ch_param_addr(ch);
- printf("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
+ debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
p->word[0].data[3], p->word[0].data[4]);
- printf("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
+ debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
p->word[1].data[3], p->word[1].data[4]);
- printf("PFS 0x%x, ",
+ debug("PFS 0x%x, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4));
- printf("BPP 0x%x, ",
+ debug("BPP 0x%x, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3));
- printf("NPB 0x%x\n",
+ debug("NPB 0x%x\n",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7));
- printf("FW %d, ",
+ debug("FW %d, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13));
- printf("FH %d, ",
+ debug("FH %d, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12));
- printf("Stride %d\n",
+ debug("Stride %d\n",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14));
- printf("Width0 %d+1, ",
+ debug("Width0 %d+1, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3));
- printf("Width1 %d+1, ",
+ debug("Width1 %d+1, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3));
- printf("Width2 %d+1, ",
+ debug("Width2 %d+1, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3));
- printf("Width3 %d+1, ",
+ debug("Width3 %d+1, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3));
- printf("Offset0 %d, ",
+ debug("Offset0 %d, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5));
- printf("Offset1 %d, ",
+ debug("Offset1 %d, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5));
- printf("Offset2 %d, ",
+ debug("Offset2 %d, ",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5));
- printf("Offset3 %d\n",
+ debug("Offset3 %d\n",
ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5));
#endif
}
uint32_t bytes_per_pixel(uint32_t fmt)
{
switch (fmt) {
- case IPU_PIX_FMT_GENERIC: /*generic data */
+ case IPU_PIX_FMT_GENERIC: /* generic data */
case IPU_PIX_FMT_RGB332:
case IPU_PIX_FMT_YUV420P:
case IPU_PIX_FMT_YUV422P:
case IPU_PIX_FMT_BGR24:
case IPU_PIX_FMT_RGB24:
return 3;
- case IPU_PIX_FMT_GENERIC_32: /*generic data */
+ case IPU_PIX_FMT_GENERIC_32: /* generic data */
case IPU_PIX_FMT_BGR32:
case IPU_PIX_FMT_BGRA32:
case IPU_PIX_FMT_RGB32:
*
* (C) Copyright 2004-2011 Freescale Semiconductor, Inc.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
+/* #define DEBUG */
#include <common.h>
#include <asm/errno.h>
#include <linux/string.h>
#include <lcd.h>
#include <ipu.h>
#include <video_fb.h>
+ #include <mxcfb.h>
#include "videomodes.h"
- #include "mxcfb.h"
DECLARE_GLOBAL_DATA_PTR;
- extern vidinfo_t panel_info;
-
- void *lcd_base; /* Start of framebuffer memory */
- void *lcd_console_address; /* Start of console buffer */
-
- int lcd_line_length;
- int lcd_color_fg;
- int lcd_color_bg;
-
- short console_col;
- short console_row;
-
static int mxcfb_map_video_memory(struct fb_info *fbi);
static int mxcfb_unmap_video_memory(struct fb_info *fbi);
{
}
- void lcd_disable(void)
- {
- }
-
- void lcd_panel_disable(void)
- {
- }
-
static void fb_videomode_to_var(struct fb_var_screeninfo *var,
const struct fb_videomode *mode)
{
fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length;
mxcfb_check_var(&fbi->var, fbi);
+
+ /* Default Y virtual size is 2x panel size */
+ fbi->var.yres_virtual = fbi->var.yres * 2;
+
mxcfb_set_fix(fbi);
/* allocate fb first */
NBITS(panel_info.vl_bpix)) / 8;
}
- int overwrite_console(void)
- {
- /* Keep stdout / stderr on serial, our LCD is for splashscreen only */
- return 1;
- }
-
int ipuv3_fb_init(struct fb_videomode *mode, int di, unsigned int interface_pix_fmt,
ipu_di_clk_parent_t di_clk_parent, unsigned long di_clk_val, int bpp)
{
int ret;
- // default_bpp = bpp;
+ default_bpp = bpp;
ret = ipu_probe(di, di_clk_parent, di_clk_val);
if (ret) {
return ret;
}
- debug("Framebuffer at %p\n", lcd_base);
- ret = mxcfb_probe(interface_pix_fmt, mode, di);
-
- return ret;
+ return mxcfb_probe(interface_pix_fmt, mode, di);
}
* based on: am335x_evm
* 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.
+ * SPDX-License-Identifier: GPL-2.0
*
- * 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.
*/
--#ifndef __CONFIGS_TX48_H
--#define __CONFIGS_TX48_H
++#ifndef __CONFIG_H
++#define __CONFIG_H
#include <asm/sizes.h>
/*
* Ka-Ro TX48 board - SoC configuration
*/
+ #define CONFIG_OMAP
#define CONFIG_AM33XX
#define CONFIG_AM33XX_GPIO
#define CONFIG_SYS_HZ 1000 /* Ticks per second */
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_BOOTCE
#define CONFIG_CMD_TIME
+ #define CONFIG_CMD_MEMTEST
/*
* Serial Driver
#define CONFIG_SYS_SPL_MALLOC_START (PHYS_SDRAM_1 + SZ_2M + SZ_32K)
#define CONFIG_SYS_SPL_MALLOC_SIZE SZ_1M
--#endif /* __CONFIGS_TX48_H */
++#endif /* __CONFIG_H */
/*
* Copyright (C) 2012 <LW@KARO-electronics.de>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
+ * SPDX-License-Identifier: GPL-2.0
*
- * 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.
*/
--#ifndef __CONFIGS_TX51_H
--#define __CONFIGS_TX51_H
+
-#define CONFIG_MX51 /* must be set before including imx-regs.h */
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_MX51 /* must be set before including imx-regs.h */
#include <asm/sizes.h>
+ #include <asm/arch/imx-regs.h>
/*
* Ka-Ro TX51 board - SoC configuration
*/
- #define CONFIG_MX51 /* i.MX51 SoC */
#define CONFIG_SYS_MX5_IOMUX_V3
--#define CONFIG_MXC_GPIO /* GPIO control */
++#define CONFIG_MXC_GPIO /* GPIO control */
#define CONFIG_SYS_MX5_HCLK 24000000
- #define CONFIG_SYS_MX5_CLK32 32768
#define CONFIG_SYS_DDR_CLKSEL 0
#define CONFIG_SYS_HZ 1000 /* Ticks per second */
#define CONFIG_SHOW_ACTIVITY
*/
#include <config_cmd_default.h>
#define CONFIG_CMD_CACHE
-#if 0
--#define CONFIG_CMD_IIM
-#endif
#define CONFIG_CMD_MMC
#define CONFIG_CMD_NAND
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_BOOTCE
#define CONFIG_CMD_TIME
+ #define CONFIG_CMD_MEMTEST
/*
* Serial Driver
#define CONFIG_MTD_DEVICE
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_NAND_MXC
- #define CONFIG_MXC_NAND_REGS_BASE 0xcfff0000
- #define CONFIG_MXC_NAND_IP_BASE 0x83fdb000
-#define CONFIG_MXC_NAND_REGS_BASE NFC_BASE_ADDR_AXI // 0xcfff0000
-#define CONFIG_MXC_NAND_IP_REGS_BASE NFC_BASE_ADDR // 0x83fdb000
++#define CONFIG_MXC_NAND_REGS_BASE NFC_BASE_ADDR_AXI
++#define CONFIG_MXC_NAND_IP_REGS_BASE NFC_BASE_ADDR
#define CONFIG_MXC_NAND_HWECC
#define CONFIG_CMD_NAND_TRIMFFS
#define CONFIG_SYS_MAX_FLASH_SECT 1024
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_FSL_ESDHC
- #define CONFIG_SYS_FSL_ESDHC_USE_PIO
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_FSL_ESDHC_NUM 2
GENERATED_GBL_DATA_SIZE)
#ifdef CONFIG_CMD_IIM
- #define CONFIG_IMX_IIM
+ #define CONFIG_FSL_IIM
#endif
--#endif /* __CONFIGS_TX51_H */
++#endif /* __CONFIG_H */
/*
* Copyright (C) 2012 <LW@KARO-electronics.de>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
+ * SPDX-License-Identifier: GPL-2.0
*
- * 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.
*/
- #ifndef __CONFIGS_TX53_H
- #define __CONFIGS_TX53_H
+
-#ifndef __CONFIGS_TX53_H
-#define __CONFIGS_TX53_H
++#ifndef __CONFIG_H
++#define __CONFIG_H
+
-#define CONFIG_MX53 /* must be set before including imx-regs.h */
++#define CONFIG_MX53 /* must be set before including imx-regs.h */
#include <asm/sizes.h>
+ #include <asm/arch/imx-regs.h>
/*
* Ka-Ro TX53 board - SoC configuration
*/
--#define CONFIG_TX53 /* TX53 SoM */
- #define CONFIG_MX53 /* i.MX53 SoC */
++#define CONFIG_TX53 /* TX53 SoM */
#define CONFIG_SYS_MX5_IOMUX_V3
--#define CONFIG_MXC_GPIO /* GPIO control */
++#define CONFIG_MXC_GPIO /* GPIO control */
#define CONFIG_SYS_MX5_HCLK 24000000
- #define CONFIG_SYS_MX5_CLK32 32768
#define CONFIG_SYS_DDR_CLKSEL 0
#define CONFIG_SYS_HZ 1000 /* Ticks per second */
#define CONFIG_SHOW_ACTIVITY
*/
#include <config_cmd_default.h>
#define CONFIG_CMD_CACHE
-#if 0
--#define CONFIG_CMD_IIM
-#endif
#define CONFIG_CMD_MMC
#define CONFIG_CMD_NAND
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_BOOTCE
#define CONFIG_CMD_TIME
+ #define CONFIG_CMD_MEMTEST
/*
* Serial Driver
#define CONFIG_MTD_DEVICE
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_NAND_MXC
- #define CONFIG_MXC_NAND_REGS_BASE 0xf7ff0000
- #define CONFIG_MXC_NAND_IP_BASE 0x63fdb000
-#define CONFIG_MXC_NAND_REGS_BASE NFC_BASE_ADDR_AXI // 0xf7ff0000
-#define CONFIG_MXC_NAND_IP_REGS_BASE NFC_BASE_ADDR // 0x63fdb000
++#define CONFIG_MXC_NAND_REGS_BASE NFC_BASE_ADDR_AXI
++#define CONFIG_MXC_NAND_IP_REGS_BASE NFC_BASE_ADDR
#define CONFIG_MXC_NAND_HWECC
#define CONFIG_CMD_NAND_TRIMFFS
#define CONFIG_SYS_MAX_FLASH_SECT 1024
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_FSL_ESDHC
-#if 0
--#define CONFIG_SYS_FSL_ESDHC_USE_PIO
-#endif
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_FSL_ESDHC_NUM 2
GENERATED_GBL_DATA_SIZE)
#ifdef CONFIG_CMD_IIM
- #define CONFIG_IMX_IIM
+ #define CONFIG_FSL_IIM
#endif
--#endif /* __CONFIGS_TX53_H */
++#endif /* __CONFIG_H */
/*
* Copyright (C) 2012 <LW@KARO-electronics.de>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
+ * SPDX-License-Identifier: GPL-2.0
*
- * 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.
*/
- #ifndef __TX6_H
- #define __TX6_H
+
-#ifndef __TX6_H
-#define __TX6_H
++#ifndef __CONFIG_H
++#define __CONFIG_H
#include <asm/sizes.h>
+ #include <asm/arch/imx-regs.h>
/*
* Ka-Ro TX6 board - SoC configuration
#ifndef CONFIG_MFG
/* LCD Logo and Splash screen support */
#define CONFIG_LCD
- #define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
#ifdef CONFIG_LCD
#define CONFIG_SPLASH_SCREEN
#define CONFIG_SPLASH_SCREEN_ALIGN
#define CONFIG_CMD_BOOTCE
#define CONFIG_CMD_TIME
#define CONFIG_CMD_I2C
+ #define CONFIG_CMD_MEMTEST
/*
* Serial Driver
#ifdef CONFIG_FEC_MXC
/* This is required for the FEC driver to work with cache enabled */
#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+ #define CONFIG_SYS_CACHELINE_SIZE 64
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
GENERATED_GBL_DATA_SIZE)
- #ifdef CONFIG_CMD_IIM
- #define CONFIG_IMX_IIM
- #endif
-
-#endif /* __CONFIGS_TX6_H */
+#endif /* __CONFIG_H */