--- /dev/null
+# Not Linux, so don't expect a Linux tree.
+--no-tree
+
+# Temporary for false positive in checkpatch
+--ignore COMPLEX_MACRO
+
+# For CONFIG_SYS_I2C_NOPROBES
+--ignore MULTISTATEMENT_MACRO_USE_DO_WHILE
+
+# For simple_strtoul
+--ignore CONSIDER_KSTRTO
+
+# For min/max
+--ignore MINMAX
/u-boot.lds
/u-boot.ubl
/u-boot.dtb
+/u-boot.sb
#
# Generated files
W: http://www.windriver.com
N: Stelian Pop
-E: stelian.pop@leadtechdesign.com
+E: stelian@popies.net
D: Atmel AT91CAP9ADK support
N: Ricardo Ribalda Delgado
rsk7264 SH7264
+egnite GmbH <info@egnite.de>
+
+ ethernut5 ARM926EJS (AT91SAM9XE SoC)
+
Dirk Eibach <eibach@gdsys.de>
devconcenter PPC460EX
gdppc440etx PPC440EP/GR
intip PPC460EX
io PPC405EP
+ io64 PPC405EX
iocon PPC405EP
neo PPC405EP
snapper9260 ARM926EJS (AT91SAM9260 SoC)
snapper9g20 ARM926EJS (AT91SAM9G20 SoC)
-Eran Man <eran@nbase.co.il>
-
- EVB64260_750CX MPC750CX
-
Andrea "llandre" Marson <andrea.marson@dave-tech.it>
PPChameleonEVB PPC405EP
pcm030 MPC5200
+Ira W. Snyder <iws@ovro.caltech.edu>
+
+ P2020COME P2020
+
Timur Tabi <timur@freescale.com>
MPC8349E-mITX MPC8349
rsdproto MPC8260
EVB64260 MPC7xx_74xx
+ EVB64260_750CX MPC750CX [Eran Man <eran@nbase.co.il>]
versatile ARM926EJ-S
-
#########################################################################
# ARM Systems: #
# #
inetspace_v2 ARM926EJS (Kirkwood SoC)
netspace_v2 ARM926EJS (Kirkwood SoC)
netspace_max_v2 ARM926EJS (Kirkwood SoC)
+ net2big_v2 ARM926EJS (Kirkwood SoC)
Igor Grinberg <grinberg@compulab.co.il>
Torsten Koschorrek <koschorrek@synertronixx.de>
scb9328 ARM920T (i.MXL)
-Frederik Kriewitz <frederik@kriewitz.eu>
-
- devkit8000 ARM ARMV7 (OMAP3530 SoC)
-
Sergey Kubushyn <ksi@koi8.net>
DV-EVM ARM926EJS
SONATA ARM926EJS
SCHMOOGIE ARM926EJS
-Prakash Kumar <prakash@embedx.com>
-
- cerf250 xscale/pxa
-
Vipin Kumar <vipin.kumar@st.com>
spear300 ARM926EJS (spear300 Soc)
omap730p2 ARM926EJS
-Manikandan Pillai <mani.pillai@ti.com>
-
- omap3_evm ARM ARMV7 (OMAP3xx SoC)
-
-Stelian Pop <stelian.pop@leadtechdesign.com>
+Stelian Pop <stelian@popies.net>
at91sam9260ek ARM926EJS (AT91SAM9260 SoC)
at91sam9261ek ARM926EJS (AT91SAM9261 SoC)
at91sam9263ek ARM926EJS (AT91SAM9263 SoC)
at91sam9rlek ARM926EJS (AT91SAM9RL SoC)
+Tom Rini <trini@ti.com>
+
+ omap3_evm ARM ARMV7 (OMAP3xx SoC)
+
Tom Rix <Tom.Rix@windriver.com>
omap3_zoom2 ARM ARMV7 (OMAP3xx SoC)
Heiko Schocher <hs@denx.de>
+ enbw_cmc ARM926EJS (AM1808 SoC)
magnesium i.MX27
mgcoge3un ARM926EJS (Kirkwood SoC)
-Robert Schwebel <r.schwebel@pengutronix.de>
-
- csb226 xscale/pxa
- innokom xscale/pxa
-
Michael Schwingen <michael@schwingen.org>
actux1 xscale/ixp
omap4_panda ARM ARMV7 (OMAP4xx SoC)
omap4_sdp4430 ARM ARMV7 (OMAP4xx SoC)
+ omap5_evm ARM ARMV7 (OMAP5xx Soc)
Marek Vasut <marek.vasut@gmail.com>
palmtc xscale/pxa
vpac270 xscale/pxa
zipitz2 xscale/pxa
+ m28evk i.MX28
efikamx i.MX51
efikasb i.MX51
harmony Tegra2 (ARM7 & A9 Dual Core)
seaboard Tegra2 (ARM7 & A9 Dual Core)
+Thomas Weber <weber@corscience.de>
+
+ devkit8000 ARM ARMV7 (OMAP3530 SoC)
+
Lei Wen <leiwen@marvell.com>
dkb ARM926EJS (PANTHEON 88AP920 SOC)
Unknown / orphaned boards:
Board CPU Last known maintainer / Comment
.........................................................................
- cradle xscale/pxa Kyle Harris <kharris@nexus-tech.net> / dead address
lubbock xscale/pxa Kyle Harris <kharris@nexus-tech.net> / dead address
imx31_phycore_eet i.MX31 Guennadi Liakhovetski <g.liakhovetski@gmx.de> / resigned
RSK7203 SH7203
AP325RXA SH7723
SHMIN SH7706
+ ECOVEC SH7724
Mark Jonas <mark.jonas@de.bosch.com>
Macpaul Lin <macpaul@andestech.com>
ADP-AG101 N1213 (AG101 SoC)
+ ADP-AG101P N1213 (AG101P XC5 FPGA)
#########################################################################
# End of MAINTAINERS list #
-c CPU, --cpu CPU Build all boards with cpu CPU
-v VENDOR, --vendor VENDOR Build all boards with vendor VENDOR
-s SOC, --soc SOC Build all boards with soc SOC
+ -l, --list List all targets to be built
-h, --help This help output
Selections by these options are logically ANDed; if the same option
exit ${ret}
}
-SHORT_OPTS="ha:c:v:s:"
-LONG_OPTS="help,arch:,cpu:,vendor:,soc:"
+SHORT_OPTS="ha:c:v:s:l"
+LONG_OPTS="help,arch:,cpu:,vendor:,soc:,list"
# Option processing based on util-linux-2.13/getopt-parse.bash
eval set -- "$TEMP"
SELECTED=''
+ONLY_LIST=''
while true ; do
case "$1" in
fi
SELECTED='y'
shift 2 ;;
+ -l|--list)
+ ONLY_LIST='y'
+ shift ;;
-h|--help)
usage ;;
--)
imx31_phycore \
imx31_phycore_eet \
mx31pdk \
- mx31pdk_nand \
smdk6400 \
"
build_target() {
target=$1
+ if [ "$ONLY_LIST" == 'y' ] ; then
+ echo "$target"
+ return
+ fi
+
${MAKE} distclean >/dev/null
${MAKE} -s ${target}_config
#-----------------------------------------------------------------------
print_stats() {
+ if [ "$ONLY_LIST" == 'y' ] ; then return ; fi
echo ""
echo "--------------------- SUMMARY ----------------------------"
echo "Boards compiled: ${TOTAL_CNT}"
endif
LIBS += drivers/rtc/librtc.o
LIBS += drivers/serial/libserial.o
+ifeq ($(CONFIG_GENERIC_LPC_TPM),y)
+LIBS += drivers/tpm/libtpm.o
+endif
LIBS += drivers/twserial/libtws.o
LIBS += drivers/usb/eth/libusb_eth.o
LIBS += drivers/usb/gadget/libusb_gadget.o
LIBS += api/libapi.o
LIBS += post/libpost.o
-ifeq ($(SOC),am33xx)
-LIBS += $(CPUDIR)/omap-common/libomap-common.o
-endif
-ifeq ($(SOC),omap3)
-LIBS += $(CPUDIR)/omap-common/libomap-common.o
-endif
-ifeq ($(SOC),omap4)
+ifneq ($(CONFIG_AM335X)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
LIBS += $(CPUDIR)/omap-common/libomap-common.o
endif
-
ifeq ($(SOC),s5pc1xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
rm $(obj)u-boot-ubl.bin
rm $(obj)spl/u-boot-spl-pad.bin
+$(obj)u-boot.sb: $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
+ elftosb -zdf imx28 -c $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd \
+ -o $(obj)u-boot.sb
+
ifeq ($(CONFIG_SANDBOX),y)
GEN_UBOOT = \
cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
$(obj)mmc_spl/u-boot-mmc-spl.bin: mmc_spl
-$(obj)spl/u-boot-spl.bin: depend
+$(obj)spl/u-boot-spl.bin: $(SUBDIR_TOOLS) depend
$(MAKE) -C spl all
updater:
$(obj)tools/envcrc \
$(obj)tools/gdb/{astest,gdbcont,gdbsend} \
$(obj)tools/gen_eth_addr $(obj)tools/img2srec \
- $(obj)tools/mkimage $(obj)tools/mpc86x_clk \
+ $(obj)tools/mk{env,}image $(obj)tools/mpc86x_clk \
$(obj)tools/ncb $(obj)tools/ubsha1
@rm -f $(obj)board/cray/L1/{bootscript.c,bootscript.image} \
$(obj)board/matrix_vision/*/bootscript.img \
$(obj)arch/blackfin/cpu/bootrom-asm-offsets.[chs] \
$(obj)arch/blackfin/cpu/init.{lds,elf}
@rm -f $(obj)include/bmp_logo.h
+ @rm -f $(obj)include/bmp_logo_data.h
@rm -f $(obj)lib/asm-offsets.s
@rm -f $(obj)include/generated/asm-offsets.h
@rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s
-o -name '*.o' -o -name '*.a' -o -name '*.exe' \) -print \
| xargs rm -f
-clobber: clean
- @find $(OBJTREE) -type f \( -name '*.depend*' \
- -o -name '*.srec' -o -name '*.bin' -o -name u-boot.img \) \
- -print0 \
- | xargs -0 rm -f
+# Removes everything not needed for testing u-boot
+tidy: clean
+ @find $(OBJTREE) -type f \( -name '*.depend*' \) -print | xargs rm -f
+
+clobber: tidy
+ @find $(OBJTREE) -type f \( -name '*.srec' \
+ -o -name '*.bin' -o -name u-boot.img \) \
+ -print0 | xargs -0 rm -f
@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
$(obj)cscope.* $(obj)*.*~
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL-y)
@rm -f $(obj)u-boot.imx
@rm -f $(obj)u-boot.ubl
@rm -f $(obj)u-boot.dtb
- @rm -f $(obj)tools/{env/crc32.c,inca-swap-bytes}
+ @rm -f $(obj)u-boot.sb
+ @rm -f $(obj)tools/inca-swap-bytes
@rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)arch/powerpc/cpu/mpc83xx/ddr-gen?.c
@rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
Define this to use i/o functions instead of macros
(some hardware wont work with macros)
+ CONFIG_DRIVER_TI_EMAC
+ Support for davinci emac
+
+ CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT
+ Define this if you have more then 3 PHYs.
+
CONFIG_FTGMAC100
Support for Faraday's FTGMAC100 Gigabit SoC Ethernet
CONFIG_SH_ETHER_CACHE_WRITEBACK
If this option is set, the driver enables cache flush.
+- TPM Support:
+ CONFIG_GENERIC_LPC_TPM
+ Support for generic parallel port TPM devices. Only one device
+ per system is supported at this time.
+
+ CONFIG_TPM_TIS_BASE_ADDRESS
+ Base address where the generic TPM device is mapped
+ to. Contemporary x86 systems usually map it at
+ 0xfed40000.
+
- USB Support:
At the moment only the UHCI host controller is
supported (PIP405, MIP405, MPC5200); define
be used if available. These functions may be faster under some
conditions but may increase the binary size.
+Freescale QE/FMAN Firmware Support:
+-----------------------------------
+
+The Freescale QUICCEngine (QE) and Frame Manager (FMAN) both support the
+loading of "firmware", which is encoded in the QE firmware binary format.
+This firmware often needs to be loaded during U-Boot booting, so macros
+are used to identify the storage device (NOR flash, SPI, etc) and the address
+within that device.
+
+- CONFIG_SYS_QE_FMAN_FW_ADDR
+ The address in the storage device where the firmware is located. The
+ meaning of this address depends on which CONFIG_SYS_QE_FW_IN_xxx macro
+ is also specified.
+
+- CONFIG_SYS_QE_FMAN_FW_LENGTH
+ The maximum possible size of the firmware. The firmware binary format
+ has a field that specifies the actual size of the firmware, but it
+ might not be possible to read any part of the firmware unless some
+ local storage is allocated to hold the entire firmware first.
+
+- CONFIG_SYS_QE_FMAN_FW_IN_NOR
+ Specifies that QE/FMAN firmware is located in NOR flash, mapped as
+ normal addressable memory via the LBC. CONFIG_SYS_FMAN_FW_ADDR is the
+ virtual address in NOR flash.
+
+- CONFIG_SYS_QE_FMAN_FW_IN_NAND
+ Specifies that QE/FMAN firmware is located in NAND flash.
+ CONFIG_SYS_FMAN_FW_ADDR is the offset within NAND flash.
+
+- CONFIG_SYS_QE_FMAN_FW_IN_MMC
+ Specifies that QE/FMAN firmware is located on the primary SD/MMC
+ device. CONFIG_SYS_FMAN_FW_ADDR is the byte offset on that device.
+
+- CONFIG_SYS_QE_FMAN_FW_IN_SPIFLASH
+ Specifies that QE/FMAN firmware is located on the primary SPI
+ device. CONFIG_SYS_FMAN_FW_ADDR is the byte offset on that device.
+
+
Building the Software:
======================
LIB = $(obj)libapi.o
-COBJS-$(CONFIG_API) += api.o api_net.o api_storage.o api_platform-$(ARCH).o
+COBJS-$(CONFIG_API) += api.o api_display.o api_net.o api_storage.o \
+ api_platform-$(ARCH).o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
return 0;
}
+/*
+ * pseudo signature:
+ *
+ * int API_display_get_info(int type, struct display_info *di)
+ */
+static int API_display_get_info(va_list ap)
+{
+ int type;
+ struct display_info *di;
+
+ type = va_arg(ap, int);
+ di = va_arg(ap, struct display_info *);
+
+ return display_get_info(type, di);
+}
+
+/*
+ * pseudo signature:
+ *
+ * int API_display_draw_bitmap(ulong bitmap, int x, int y)
+ */
+static int API_display_draw_bitmap(va_list ap)
+{
+ ulong bitmap;
+ int x, y;
+
+ bitmap = va_arg(ap, ulong);
+ x = va_arg(ap, int);
+ y = va_arg(ap, int);
+
+ return display_draw_bitmap(bitmap, x, y);
+}
+
+/*
+ * pseudo signature:
+ *
+ * void API_display_clear(void)
+ */
+static int API_display_clear(va_list ap)
+{
+ display_clear();
+ return 0;
+}
+
static cfp_t calls_table[API_MAXCALL] = { NULL, };
/*
calls_table[API_ENV_GET] = &API_env_get;
calls_table[API_ENV_SET] = &API_env_set;
calls_table[API_ENV_ENUM] = &API_env_enum;
+ calls_table[API_DISPLAY_GET_INFO] = &API_display_get_info;
+ calls_table[API_DISPLAY_DRAW_BITMAP] = &API_display_draw_bitmap;
+ calls_table[API_DISPLAY_CLEAR] = &API_display_clear;
calls_no = API_MAXCALL;
debugf("API initialized with %d calls\n", calls_no);
--- /dev/null
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <api_public.h>
+#include <lcd.h>
+#include <video_font.h> /* Get font width and height */
+
+/* lcd.h needs BMP_LOGO_HEIGHT to calculate CONSOLE_ROWS */
+#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+#include <bmp_logo.h>
+#endif
+
+/* TODO(clchiou): add support of video device */
+
+int display_get_info(int type, struct display_info *di)
+{
+ if (!di)
+ return API_EINVAL;
+
+ switch (type) {
+ default:
+ debug("%s: unsupport display device type: %d\n",
+ __FILE__, type);
+ return API_ENODEV;
+#ifdef CONFIG_LCD
+ case DISPLAY_TYPE_LCD:
+ di->pixel_width = panel_info.vl_col;
+ di->pixel_height = panel_info.vl_row;
+ di->screen_rows = CONSOLE_ROWS;
+ di->screen_cols = CONSOLE_COLS;
+ break;
+#endif
+ }
+
+ di->type = type;
+ return 0;
+}
+
+int display_draw_bitmap(ulong bitmap, int x, int y)
+{
+ if (!bitmap)
+ return API_EINVAL;
+#ifdef CONFIG_LCD
+ return lcd_display_bitmap(bitmap, x, y);
+#else
+ return API_ENODEV;
+#endif
+}
+
+void display_clear(void)
+{
+#ifdef CONFIG_LCD
+ lcd_clear();
+#endif
+}
void dev_stor_init(void);
+int display_get_info(int type, struct display_info *di);
+int display_draw_bitmap(ulong bitmap, int x, int y);
+void display_clear(void);
+
#endif /* _API_PRIVATE_H_ */
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
-#ifdef CONFIG_SYS_MX31_UART1
void mx31_uart1_hw_init(void)
{
/* setup pins for UART1 */
mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
}
-#endif
-#ifdef CONFIG_SYS_MX31_UART2
void mx31_uart2_hw_init(void)
{
/* setup pins for UART2 */
mx31_gpio_mux(MUX_RTS2__UART2_RTS_B);
mx31_gpio_mux(MUX_CTS2__UART2_CTS_B);
}
-#endif
#ifdef CONFIG_MXC_SPI
/*
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
-#define IOMUXGPR (IOMUXC_BASE + 0x008)
-
static u32 mx31_decode_pll(u32 reg, u32 infreq)
{
u32 mfi = GET_PLL_MFI(reg);
void mx31_dump_clocks(void)
{
u32 cpufreq = mx31_get_mcu_main_clk();
- printf("mx31 cpu clock: %dMHz\n",cpufreq / 1000000);
+ printf("mx31 cpu clock: %dMHz\n", cpufreq / 1000000);
printf("ipg clock : %dHz\n", mx31_get_ipg_clk());
printf("hsp clock : %dHz\n", mx31_get_hsp_clk());
}
void mx31_set_gpr(enum iomux_gp_func gp, char en)
{
u32 l;
+ struct iomuxc_regs *iomuxc = (struct iomuxc_regs *)IOMUXC_BASE;
- l = readl(IOMUXGPR);
+ l = readl(&iomuxc->gpr);
if (en)
l |= gp;
else
l &= ~gp;
- writel(l, IOMUXGPR);
+ writel(l, &iomuxc->gpr);
}
void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs)
}
#if defined(CONFIG_DISPLAY_CPUINFO)
-int print_cpuinfo (void)
+int print_cpuinfo(void)
{
u32 srev = get_cpu_rev();
*/
#include <common.h>
+#include <div64.h>
#include <asm/io.h>
#include <faraday/ftpmu010.h>
#include <faraday/fttmr010.h>
-static ulong timestamp;
-static ulong lastdec;
-
-static struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+DECLARE_GLOBAL_DATA_PTR;
#define TIMER_CLOCK 32768
#define TIMER_LOAD_VAL 0xffffffff
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, gd->timer_rate_hz);
+
+ return tick;
+}
+
+static inline unsigned long long usec_to_tick(unsigned long long usec)
+{
+ usec *= gd->timer_rate_hz;
+ do_div(usec, 1000000);
+
+ return usec;
+}
+
int timer_init(void)
{
+ struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
unsigned int cr;
debug("%s()\n", __func__);
cr |= FTTMR010_TM3_ENABLE;
writel(cr, &tmr->cr);
- /* init the timestamp and lastdec value */
- reset_timer_masked();
+ gd->timer_rate_hz = TIMER_CLOCK;
+ gd->tbu = gd->tbl = 0;
return 0;
}
/*
- * timer without interrupts
- */
-
-/*
- * reset time
- */
-void reset_timer_masked(void)
-{
- /* capure current decrementer value time */
- lastdec = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
- timestamp = 0; /* start "advancing" time stamp from 0 */
-
- debug("%s(): lastdec = %lx\n", __func__, lastdec);
-}
-
-/*
- * return timer ticks
- */
-ulong get_timer_masked(void)
-{
- /* current tick value */
- ulong now = readl(&tmr->timer3_counter) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
- debug("%s(): now = %lx, lastdec = %lx\n", __func__, now, lastdec);
-
- if (lastdec >= now) {
- /*
- * normal mode (non roll)
- * move stamp fordward with absoulte diff ticks
- */
- timestamp += lastdec - now;
- } else {
- /*
- * we have overflow of the count down timer
- *
- * nts = ts + ld + (TLV - now)
- * ts=old stamp, ld=time that passed before passing through -1
- * (TLV-now) amount of time after passing though -1
- * nts = new "advancing time stamp"...it could also roll and
- * cause problems.
- */
- timestamp += lastdec + TIMER_LOAD_VAL - now;
- }
-
- lastdec = now;
-
- debug("%s() returns %lx\n", __func__, timestamp);
-
- return timestamp;
-}
-
-/*
- * return difference between timer ticks and base
+ * Get the current 64 bit timer tick count
*/
-ulong get_timer(ulong base)
+unsigned long long get_ticks(void)
{
- debug("%s(%lx)\n", __func__, base);
- return get_timer_masked() - base;
+ struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
+ ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
+
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->tbl)
+ gd->tbu++;
+ gd->tbl = now;
+ return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
}
-/* delay x useconds AND preserve advance timestamp value */
void __udelay(unsigned long usec)
{
- long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
- unsigned long now, last = readl(&tmr->timer3_counter);
-
- debug("%s(%lu)\n", __func__, usec);
- while (tmo > 0) {
- now = readl(&tmr->timer3_counter);
- if (now > last) /* count down timer overflow */
- tmo -= TIMER_LOAD_VAL + last - now;
- else
- tmo -= last - now;
- last = now;
- }
+ unsigned long long start;
+ ulong tmo;
+
+ start = get_ticks(); /* get current timestamp */
+ tmo = usec_to_tick(usec); /* convert usecs to ticks */
+ while ((get_ticks() - start) < tmo)
+ ; /* loop till time has passed */
}
/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
+ * get_timer(base) can be used to check for timeouts or
+ * to measure elasped time relative to an event:
+ *
+ * ulong start_time = get_timer(0) sets start_time to the current
+ * time value.
+ * get_timer(start_time) returns the time elapsed since then.
+ *
+ * The time is used in CONFIG_SYS_HZ units!
*/
-unsigned long long get_ticks(void)
+ulong get_timer(ulong base)
{
- debug("%s()\n", __func__);
- return get_timer(0);
+ return tick_to_time(get_ticks()) - base;
}
/*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
+ * Return the number of timer ticks per second.
*/
ulong get_tbclk(void)
{
- debug("%s()\n", __func__);
- return CONFIG_SYS_HZ;
+ return gd->timer_rate_hz;
}
* Andreas Bießmann <andreas.devel@googlemail.com>
*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
LIB = $(obj)lib$(CPU).o
START = start.o
-COBJS = cpu.o
+COBJS = cpu.o cache.o
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_NO_CPU_SUPPORT_CODE
+START :=
+endif
+endif
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* (C) Copyright 2009
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* (C) Copyright 2009-2011
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* See file CREDITS for list of people who contributed to this
--- /dev/null
+/*
+ * (C) Copyright 2011
+ * Ilya Yanok, EmCraft Systems
+ *
+ * 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.
+ */
+#include <linux/types.h>
+#include <common.h>
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+static inline void dcache_noop(void)
+{
+ if (dcache_status()) {
+ puts("WARNING: cache operations are not implemented!\n"
+ "WARNING: disabling D-Cache now, you can re-enable it"
+ "later with 'dcache on' command\n");
+ dcache_disable();
+ }
+}
+
+void invalidate_dcache_all(void)
+{
+ dcache_noop();
+}
+
+void flush_dcache_all(void)
+{
+ dcache_noop();
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ dcache_noop();
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ dcache_noop();
+}
+#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_cache(unsigned long start, unsigned long size)
+{
+}
+#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
LIB = $(obj)lib$(SOC).o
-COBJS-y += cpu.o timer.o psc.o
-COBJS-$(CONFIG_AM18018_LOWLEVEL) += am1808_lowlevel.o
+COBJS-y += cpu.o misc.o timer.o psc.o pinmux.o
+COBJS-$(CONFIG_DA850_LOWLEVEL) += da850_lowlevel.o
COBJS-$(CONFIG_SOC_DM355) += dm355.o
COBJS-$(CONFIG_SOC_DM365) += dm365.o
COBJS-$(CONFIG_SOC_DM644X) += dm644x.o
COBJS-$(CONFIG_SOC_DM646X) += dm646x.o
+COBJS-$(CONFIG_SOC_DA850) += da850_pinmux.o
COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o
ifdef CONFIG_SPL_BUILD
+++ /dev/null
-/*
- * SoC-specific lowlevel code for AM1808 and similar chips
- *
- * Copyright (C) 2011
- * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <common.h>
-#include <nand.h>
-#include <ns16550.h>
-#include <post.h>
-#include <asm/arch/am1808_lowlevel.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/ddr2_defs.h>
-#include <asm/arch/emif_defs.h>
-
-void am1808_waitloop(unsigned long loopcnt)
-{
- unsigned long i;
-
- for (i = 0; i < loopcnt; i++)
- asm(" NOP");
-}
-
-int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult)
-{
- if (reg == davinci_pllc0_regs)
- /* Unlock PLL registers. */
- clrbits_le32(&davinci_syscfg_regs->cfgchip0, 0x00000010);
-
- /*
- * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled
- * through MMR
- */
- clrbits_le32(®->pllctl, 0x00000020);
- /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */
- clrbits_le32(®->pllctl, 0x00000200);
-
- /* Set PLLEN=0 => PLL BYPASS MODE */
- clrbits_le32(®->pllctl, 0x00000001);
-
- am1808_waitloop(150);
-
- if (reg == davinci_pllc0_regs) {
- /*
- * Select the Clock Mode bit 8 as External Clock or On Chip
- * Oscilator
- */
- dv_maskbits(®->pllctl, 0xFFFFFEFF);
- setbits_le32(®->pllctl, (CONFIG_SYS_DV_CLKMODE << 8));
- }
-
- /* Clear PLLRST bit to reset the PLL */
- clrbits_le32(®->pllctl, 0x00000008);
-
- /* Disable the PLL output */
- setbits_le32(®->pllctl, 0x00000010);
-
- /* PLL initialization sequence */
- /*
- * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of
- * power down bit
- */
- clrbits_le32(®->pllctl, 0x00000002);
-
- /* Enable the PLL from Disable Mode PLLDIS bit to 0 */
- clrbits_le32(®->pllctl, 0x00000010);
-
- /* Program the required multiplier value in PLLM */
- writel(pllmult, ®->pllm);
-
- /* program the postdiv */
- if (reg == davinci_pllc0_regs)
- writel((0x8000 | CONFIG_SYS_AM1808_PLL0_POSTDIV),
- ®->postdiv);
- else
- writel((0x8000 | CONFIG_SYS_AM1808_PLL1_POSTDIV),
- ®->postdiv);
-
- /*
- * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that
- * no GO operation is currently in progress
- */
- while ((readl(®->pllstat) & 0x1) == 1)
- ;
-
- if (reg == davinci_pllc0_regs) {
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV1, ®->plldiv1);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV2, ®->plldiv2);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV3, ®->plldiv3);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV4, ®->plldiv4);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV5, ®->plldiv5);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV6, ®->plldiv6);
- writel(CONFIG_SYS_AM1808_PLL0_PLLDIV7, ®->plldiv7);
- } else {
- writel(CONFIG_SYS_AM1808_PLL1_PLLDIV1, ®->plldiv1);
- writel(CONFIG_SYS_AM1808_PLL1_PLLDIV2, ®->plldiv2);
- writel(CONFIG_SYS_AM1808_PLL1_PLLDIV3, ®->plldiv3);
- }
-
- /*
- * Set the GOSET bit in PLLCMD to 1 to initiate a new divider
- * transition.
- */
- setbits_le32(®->pllcmd, 0x01);
-
- /*
- * Wait for the GOSTAT bit in PLLSTAT to clear to 0
- * (completion of phase alignment).
- */
- while ((readl(®->pllstat) & 0x1) == 1)
- ;
-
- /* Wait for PLL to reset properly. See PLL spec for PLL reset time */
- am1808_waitloop(200);
-
- /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */
- setbits_le32(®->pllctl, 0x00000008);
-
- /* Wait for PLL to lock. See PLL spec for PLL lock time */
- am1808_waitloop(2400);
-
- /*
- * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass
- * mode
- */
- setbits_le32(®->pllctl, 0x00000001);
-
-
- /*
- * clear EMIFA and EMIFB clock source settings, let them
- * run off SYSCLK
- */
- if (reg == davinci_pllc0_regs)
- dv_maskbits(&davinci_syscfg_regs->cfgchip3, 0xFFFFFFF8);
-
- return 0;
-}
-
-void am1808_lpc_transition(unsigned char pscnum, unsigned char module,
- unsigned char domain, unsigned char state)
-{
- struct davinci_psc_regs *reg;
- dv_reg_p mdstat, mdctl;
-
- if (pscnum == 0) {
- reg = davinci_psc0_regs;
- mdstat = ®->psc0.mdstat[module];
- mdctl = ®->psc0.mdctl[module];
- } else {
- reg = davinci_psc1_regs;
- mdstat = ®->psc1.mdstat[module];
- mdctl = ®->psc1.mdctl[module];
- }
-
- /* Wait for any outstanding transition to complete */
- while ((readl(®->ptstat) & (0x00000001 << domain)))
- ;
-
- /* If we are already in that state, just return */
- if ((readl(mdstat) & 0x1F) == state)
- return;
-
- /* Perform transition */
- writel((readl(mdctl) & 0xFFFFFFE0) | state, mdctl);
- setbits_le32(®->ptcmd, (0x00000001 << domain));
-
- /* Wait for transition to complete */
- while (readl(®->ptstat) & (0x00000001 << domain))
- ;
-
- /* Wait and verify the state */
- while ((readl(mdstat) & 0x1F) != state)
- ;
-}
-
-int am1808_ddr_setup(unsigned int freq)
-{
- unsigned long tmp;
-
- /* Enable the Clock to DDR2/mDDR */
- am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
-
- tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
- if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) {
- /* Begin VTP Calibration */
- clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
- clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
- setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
- clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
- setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
-
- /* Polling READY bit to see when VTP calibration is done */
- tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
- while ((tmp & VTP_READY) != VTP_READY)
- tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
-
- setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
- setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
-
- setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
- }
-
- writel(CONFIG_SYS_AM1808_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
- clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
- (1 << DDR_SLEW_CMOSEN_BIT));
-
- setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK);
-
- writel((CONFIG_SYS_AM1808_DDR2_SDBCR & ~0xf0000000) |
- (readl(&dv_ddr2_regs_ctrl->sdbcr) & 0xf0000000), /*rsv Bytes*/
- &dv_ddr2_regs_ctrl->sdbcr);
- writel(CONFIG_SYS_AM1808_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2);
-
- writel(CONFIG_SYS_AM1808_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
- writel(CONFIG_SYS_AM1808_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
-
- clrbits_le32(&dv_ddr2_regs_ctrl->sdbcr,
- (1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT));
-
- /*
- * LPMODEN and MCLKSTOPEN must be set!
- * Without this bits set, PSC don;t switch states !!
- */
- writel(CONFIG_SYS_AM1808_DDR2_SDRCR |
- (1 << DV_DDR_SRCR_LPMODEN_SHIFT) |
- (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT),
- &dv_ddr2_regs_ctrl->sdrcr);
-
- /* SyncReset the Clock to EMIF3A SDRAM */
- am1808_lpc_transition(1, 6, 0, PSC_SYNCRESET);
- /* Enable the Clock to EMIF3A SDRAM */
- am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
-
- /* disable self refresh */
- clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, 0xc0000000);
- writel(0x30, &dv_ddr2_regs_ctrl->pbbpr);
-
- return 0;
-}
-
-static void am1808_set_mdctl(dv_reg_p mdctl)
-{
- if ((readl(mdctl) & 0x1F) != PSC_ENABLE)
- writel(((readl(mdctl) & 0xFFFFFFE0) | PSC_ENABLE), mdctl);
-}
-
-void am1808_psc_init(void)
-{
- struct davinci_psc_regs *reg;
- int i;
-
- /* PSC 0 domain 0 init */
- reg = davinci_psc0_regs;
- while ((readl(®->ptstat) & 0x00000001))
- ;
-
- for (i = 3; i <= 4 ; i++)
- am1808_set_mdctl(®->psc0.mdctl[i]);
-
- for (i = 7; i <= 12 ; i++)
- am1808_set_mdctl(®->psc0.mdctl[i]);
-
- /* Do Always-On Power Domain Transitions */
- setbits_le32(®->ptcmd, 0x00000001);
- while (readl(®->ptstat) & 0x00000001)
- ;
-
- /* PSC1, domain 1 init */
- reg = davinci_psc1_regs;
- while ((readl(®->ptstat) & 0x00000001))
- ;
-
- am1808_set_mdctl(®->psc1.mdctl[3]);
- am1808_set_mdctl(®->psc1.mdctl[6]);
-
- /* UART1 + UART2 */
- for (i = 12 ; i <= 13 ; i++)
- am1808_set_mdctl(®->psc1.mdctl[i]);
-
- am1808_set_mdctl(®->psc1.mdctl[26]);
- am1808_set_mdctl(®->psc1.mdctl[31]);
-
- /* Do Always-On Power Domain Transitions */
- setbits_le32(®->ptcmd, 0x00000001);
- while (readl(®->ptstat) & 0x00000001)
- ;
-}
-
-void am1808_pinmux_ctl(unsigned long offset, unsigned long mask,
- unsigned long value)
-{
- clrbits_le32(&davinci_syscfg_regs->pinmux[offset], mask);
- setbits_le32(&davinci_syscfg_regs->pinmux[offset], (mask & value));
-}
-
-__attribute__((weak))
-void board_gpio_init(void)
-{
- return;
-}
-
-#if defined(CONFIG_NAND_SPL)
-void nand_boot(void)
-{
- __attribute__((noreturn)) void (*uboot)(void);
-
- /* copy image from NOR to RAM */
- memcpy((void *)CONFIG_SYS_NAND_U_BOOT_DST,
- (void *)CONFIG_SYS_NAND_U_BOOT_OFFS,
- CONFIG_SYS_NAND_U_BOOT_SIZE);
-
- /* and jump to it ... */
- uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
- (*uboot)();
-}
-#endif
-
-#if defined(CONFIG_NAND_SPL)
-void board_init_f(ulong bootflag)
-#else
-int arch_cpu_init(void)
-#endif
-{
- /*
- * copied from arch/arm/cpu/arm926ejs/start.S
- *
- * flush v4 I/D caches
- */
- asm("mov r0, #0");
- asm("mcr p15, 0, r0, c7, c7, 0"); /* flush v3/v4 cache */
- asm("mcr p15, 0, r0, c8, c7, 0"); /* flush v4 TLB */
-
- /*
- * disable MMU stuff and caches
- */
- asm("mrc p15, 0, r0, c1, c0, 0");
- /* clear bits 13, 9:8 (--V- --RS) */
- asm("bic r0, r0, #0x00002300");
- /* clear bits 7, 2:0 (B--- -CAM) */
- asm("bic r0, r0, #0x00000087");
- /* set bit 2 (A) Align */
- asm("orr r0, r0, #0x00000002");
- /* set bit 12 (I) I-Cache */
- asm("orr r0, r0, #0x00001000");
- asm("mcr p15, 0, r0, c1, c0, 0");
-
- /* Unlock kick registers */
- writel(0x83e70b13, &davinci_syscfg_regs->kick0);
- writel(0x95a4f1e0, &davinci_syscfg_regs->kick1);
-
- dv_maskbits(&davinci_syscfg_regs->suspsrc,
- ((1 << 27) | (1 << 22) | (1 << 20) | (1 << 5) | (1 << 16)));
-
- /* System PSC setup - enable all */
- am1808_psc_init();
-
- /* Setup Pinmux */
- am1808_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX0);
- am1808_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX1);
- am1808_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX2);
- am1808_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX3);
- am1808_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX4);
- am1808_pinmux_ctl(5, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX5);
- am1808_pinmux_ctl(6, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX6);
- am1808_pinmux_ctl(7, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX7);
- am1808_pinmux_ctl(8, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX8);
- am1808_pinmux_ctl(9, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX9);
- am1808_pinmux_ctl(10, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX10);
- am1808_pinmux_ctl(11, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX11);
- am1808_pinmux_ctl(12, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX12);
- am1808_pinmux_ctl(13, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX13);
- am1808_pinmux_ctl(14, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX14);
- am1808_pinmux_ctl(15, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX15);
- am1808_pinmux_ctl(16, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX16);
- am1808_pinmux_ctl(17, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX17);
- am1808_pinmux_ctl(18, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX18);
- am1808_pinmux_ctl(19, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX19);
-
- /* PLL setup */
- am1808_pll_init(davinci_pllc0_regs, CONFIG_SYS_AM1808_PLL0_PLLM);
- am1808_pll_init(davinci_pllc1_regs, CONFIG_SYS_AM1808_PLL1_PLLM);
-
- /* GPIO setup */
- board_gpio_init();
-
- /* setup CSn config */
- writel(CONFIG_SYS_AM1808_CS2CFG, &davinci_emif_regs->ab1cr);
- writel(CONFIG_SYS_AM1808_CS3CFG, &davinci_emif_regs->ab2cr);
-
- am1808_lpc_transition(1, 13, 0, PSC_ENABLE);
- NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1),
- CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
-
- /*
- * Fix Power and Emulation Management Register
- * see sprufw3a.pdf page 37 Table 24
- */
- writel(readl((CONFIG_SYS_NS16550_COM1 + 0x30)) | 0x00006001,
- (CONFIG_SYS_NS16550_COM1 + 0x30));
-#if defined(CONFIG_NAND_SPL)
- puts("ddr init\n");
- am1808_ddr_setup(132);
-
- puts("boot u-boot ...\n");
-
- nand_boot();
-#else
- am1808_ddr_setup(132);
- return 0;
-#endif
-}
--- /dev/null
+/*
+ * SoC-specific lowlevel code for DA850
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <common.h>
+#include <nand.h>
+#include <ns16550.h>
+#include <post.h>
+#include <asm/arch/da850_lowlevel.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/davinci_misc.h>
+#include <asm/arch/ddr2_defs.h>
+#include <asm/arch/emif_defs.h>
+#include <asm/arch/pll_defs.h>
+
+void da850_waitloop(unsigned long loopcnt)
+{
+ unsigned long i;
+
+ for (i = 0; i < loopcnt; i++)
+ asm(" NOP");
+}
+
+int da850_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult)
+{
+ if (reg == davinci_pllc0_regs)
+ /* Unlock PLL registers. */
+ clrbits_le32(&davinci_syscfg_regs->cfgchip0, PLL_MASTER_LOCK);
+
+ /*
+ * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled
+ * through MMR
+ */
+ clrbits_le32(®->pllctl, PLLCTL_PLLENSRC);
+ /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */
+ clrbits_le32(®->pllctl, PLLCTL_EXTCLKSRC);
+
+ /* Set PLLEN=0 => PLL BYPASS MODE */
+ clrbits_le32(®->pllctl, PLLCTL_PLLEN);
+
+ da850_waitloop(150);
+
+ if (reg == davinci_pllc0_regs) {
+ /*
+ * Select the Clock Mode bit 8 as External Clock or On Chip
+ * Oscilator
+ */
+ dv_maskbits(®->pllctl, ~PLLCTL_RES_9);
+ setbits_le32(®->pllctl,
+ (CONFIG_SYS_DV_CLKMODE << PLLCTL_CLOCK_MODE_SHIFT));
+ }
+
+ /* Clear PLLRST bit to reset the PLL */
+ clrbits_le32(®->pllctl, PLLCTL_PLLRST);
+
+ /* Disable the PLL output */
+ setbits_le32(®->pllctl, PLLCTL_PLLDIS);
+
+ /* PLL initialization sequence */
+ /*
+ * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of
+ * power down bit
+ */
+ clrbits_le32(®->pllctl, PLLCTL_PLLPWRDN);
+
+ /* Enable the PLL from Disable Mode PLLDIS bit to 0 */
+ clrbits_le32(®->pllctl, PLLCTL_PLLDIS);
+
+ /* Program the required multiplier value in PLLM */
+ writel(pllmult, ®->pllm);
+
+ /* program the postdiv */
+ if (reg == davinci_pllc0_regs)
+ writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL0_POSTDIV),
+ ®->postdiv);
+ else
+ writel((PLL_POSTDEN | CONFIG_SYS_DA850_PLL1_POSTDIV),
+ ®->postdiv);
+
+ /*
+ * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that
+ * no GO operation is currently in progress
+ */
+ while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT)
+ ;
+
+ if (reg == davinci_pllc0_regs) {
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV1, ®->plldiv1);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV2, ®->plldiv2);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV3, ®->plldiv3);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV4, ®->plldiv4);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV5, ®->plldiv5);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV6, ®->plldiv6);
+ writel(CONFIG_SYS_DA850_PLL0_PLLDIV7, ®->plldiv7);
+ } else {
+ writel(CONFIG_SYS_DA850_PLL1_PLLDIV1, ®->plldiv1);
+ writel(CONFIG_SYS_DA850_PLL1_PLLDIV2, ®->plldiv2);
+ writel(CONFIG_SYS_DA850_PLL1_PLLDIV3, ®->plldiv3);
+ }
+
+ /*
+ * Set the GOSET bit in PLLCMD to 1 to initiate a new divider
+ * transition.
+ */
+ setbits_le32(®->pllcmd, PLLCMD_GOSTAT);
+
+ /*
+ * Wait for the GOSTAT bit in PLLSTAT to clear to 0
+ * (completion of phase alignment).
+ */
+ while ((readl(®->pllstat) & PLLCMD_GOSTAT) == PLLCMD_GOSTAT)
+ ;
+
+ /* Wait for PLL to reset properly. See PLL spec for PLL reset time */
+ da850_waitloop(200);
+
+ /* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */
+ setbits_le32(®->pllctl, PLLCTL_PLLRST);
+
+ /* Wait for PLL to lock. See PLL spec for PLL lock time */
+ da850_waitloop(2400);
+
+ /*
+ * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass
+ * mode
+ */
+ setbits_le32(®->pllctl, PLLCTL_PLLEN);
+
+
+ /*
+ * clear EMIFA and EMIFB clock source settings, let them
+ * run off SYSCLK
+ */
+ if (reg == davinci_pllc0_regs)
+ dv_maskbits(&davinci_syscfg_regs->cfgchip3,
+ ~(PLL_SCSCFG3_DIV45PENA | PLL_SCSCFG3_EMA_CLKSRC));
+
+ return 0;
+}
+
+int da850_ddr_setup(void)
+{
+ unsigned long tmp;
+
+ /* Enable the Clock to DDR2/mDDR */
+ lpsc_on(DAVINCI_LPSC_DDR_EMIF);
+
+ tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+ if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) {
+ /* Begin VTP Calibration */
+ clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
+ clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
+ setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+ clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+ setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+
+ /* Polling READY bit to see when VTP calibration is done */
+ tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+ while ((tmp & VTP_READY) != VTP_READY)
+ tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+
+ setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
+ setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
+
+ setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
+ }
+
+ writel(CONFIG_SYS_DA850_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
+ clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
+ (1 << DDR_SLEW_CMOSEN_BIT));
+
+ /*
+ * SDRAM Configuration Register (SDCR):
+ * First set the BOOTUNLOCK bit to make configuration bits
+ * writeable.
+ */
+ setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK);
+
+ /*
+ * Write the new value of these bits and clear BOOTUNLOCK.
+ * At the same time, set the TIMUNLOCK bit to allow changing
+ * the timing registers
+ */
+ tmp = CONFIG_SYS_DA850_DDR2_SDBCR;
+ tmp &= ~DV_DDR_BOOTUNLOCK;
+ tmp |= DV_DDR_TIMUNLOCK;
+ writel(tmp, &dv_ddr2_regs_ctrl->sdbcr);
+
+ /* write memory configuration and timing */
+ writel(CONFIG_SYS_DA850_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2);
+ writel(CONFIG_SYS_DA850_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
+ writel(CONFIG_SYS_DA850_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
+
+ /* clear the TIMUNLOCK bit and write the value of the CL field */
+ tmp &= ~DV_DDR_TIMUNLOCK;
+ writel(tmp, &dv_ddr2_regs_ctrl->sdbcr);
+
+ /*
+ * LPMODEN and MCLKSTOPEN must be set!
+ * Without this bits set, PSC don;t switch states !!
+ */
+ writel(CONFIG_SYS_DA850_DDR2_SDRCR |
+ (1 << DV_DDR_SRCR_LPMODEN_SHIFT) |
+ (1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT),
+ &dv_ddr2_regs_ctrl->sdrcr);
+
+ /* SyncReset the Clock to EMIF3A SDRAM */
+ lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF);
+ /* Enable the Clock to EMIF3A SDRAM */
+ lpsc_on(DAVINCI_LPSC_DDR_EMIF);
+
+ /* disable self refresh */
+ clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr,
+ DV_DDR_SDRCR_LPMODEN | DV_DDR_SDRCR_LPMODEN);
+ writel(CONFIG_SYS_DA850_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr);
+
+ return 0;
+}
+
+__attribute__((weak))
+void board_gpio_init(void)
+{
+ return;
+}
+
+/* pinmux_resource[] vector is defined in the board specific file */
+extern const struct pinmux_resource pinmuxes[];
+extern const int pinmuxes_size;
+
+int arch_cpu_init(void)
+{
+ /* Unlock kick registers */
+ writel(DV_SYSCFG_KICK0_UNLOCK, &davinci_syscfg_regs->kick0);
+ writel(DV_SYSCFG_KICK1_UNLOCK, &davinci_syscfg_regs->kick1);
+
+ dv_maskbits(&davinci_syscfg_regs->suspsrc,
+ CONFIG_SYS_DA850_SYSCFG_SUSPSRC);
+
+ /* configure pinmux settings */
+ if (davinci_configure_pin_mux_items(pinmuxes, pinmuxes_size))
+ return 1;
+
+ /* PLL setup */
+ da850_pll_init(davinci_pllc0_regs, CONFIG_SYS_DA850_PLL0_PLLM);
+ da850_pll_init(davinci_pllc1_regs, CONFIG_SYS_DA850_PLL1_PLLM);
+
+ /* GPIO setup */
+ board_gpio_init();
+
+ /* setup CSn config */
+#if defined(CONFIG_SYS_DA850_CS2CFG)
+ writel(CONFIG_SYS_DA850_CS2CFG, &davinci_emif_regs->ab1cr);
+#endif
+#if defined(CONFIG_SYS_DA850_CS3CFG)
+ writel(CONFIG_SYS_DA850_CS3CFG, &davinci_emif_regs->ab2cr);
+#endif
+
+ lpsc_on(CONFIG_SYS_DA850_LPSC_UART);
+ NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1),
+ CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
+
+ /*
+ * Fix Power and Emulation Management Register
+ * see sprufw3a.pdf page 37 Table 24
+ */
+ writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST |
+ DAVINCI_UART_PWREMU_MGMT_UTRST),
+ &davinci_uart2_ctrl_regs->pwremu_mgmt);
+
+ da850_ddr_setup();
+ return 0;
+}
--- /dev/null
+/*
+ * Pinmux configurations for the DA850 SoCs
+ *
+ * Copyright (C) 2011 OMICRON electronics 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <asm/arch/davinci_misc.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pinmux_defs.h>
+
+/* SPI pin muxer settings */
+const struct pinmux_config spi1_pins_base[] = {
+ { pinmux(5), 1, 2 }, /* SPI1_CLK */
+ { pinmux(5), 1, 4 }, /* SPI1_SOMI */
+ { pinmux(5), 1, 5 }, /* SPI1_SIMO */
+};
+
+const struct pinmux_config spi1_pins_scs0[] = {
+ { pinmux(5), 1, 1 }, /* SPI1_SCS[0] */
+};
+
+/* UART pin muxer settings */
+const struct pinmux_config uart1_pins_txrx[] = {
+ { pinmux(4), 2, 6 }, /* UART1_RXD */
+ { pinmux(4), 2, 7 }, /* UART1_TXD */
+};
+
+const struct pinmux_config uart2_pins_txrx[] = {
+ { pinmux(4), 2, 4 }, /* UART2_RXD */
+ { pinmux(4), 2, 5 }, /* UART2_TXD */
+};
+
+const struct pinmux_config uart2_pins_rtscts[] = {
+ { pinmux(0), 4, 6 }, /* UART2_RTS */
+ { pinmux(0), 4, 7 }, /* UART2_CTS */
+};
+
+/* EMAC pin muxer settings*/
+const struct pinmux_config emac_pins_rmii[] = {
+ { pinmux(14), 8, 2 }, /* RMII_TXD[1] */
+ { pinmux(14), 8, 3 }, /* RMII_TXD[0] */
+ { pinmux(14), 8, 4 }, /* RMII_TXEN */
+ { pinmux(14), 8, 5 }, /* RMII_RXD[1] */
+ { pinmux(14), 8, 6 }, /* RMII_RXD[0] */
+ { pinmux(14), 8, 7 }, /* RMII_RXER */
+ { pinmux(15), 8, 1 }, /* RMII_CRS_DV */
+};
+
+const struct pinmux_config emac_pins_mii[] = {
+ { pinmux(2), 8, 1 }, /* MII_TXEN */
+ { pinmux(2), 8, 2 }, /* MII_TXCLK */
+ { pinmux(2), 8, 3 }, /* MII_COL */
+ { pinmux(2), 8, 4 }, /* MII_TXD[3] */
+ { pinmux(2), 8, 5 }, /* MII_TXD[2] */
+ { pinmux(2), 8, 6 }, /* MII_TXD[1] */
+ { pinmux(2), 8, 7 }, /* MII_TXD[0] */
+ { pinmux(3), 8, 0 }, /* MII_RXCLK */
+ { pinmux(3), 8, 1 }, /* MII_RXDV */
+ { pinmux(3), 8, 2 }, /* MII_RXER */
+ { pinmux(3), 8, 3 }, /* MII_CRS */
+ { pinmux(3), 8, 4 }, /* MII_RXD[3] */
+ { pinmux(3), 8, 5 }, /* MII_RXD[2] */
+ { pinmux(3), 8, 6 }, /* MII_RXD[1] */
+ { pinmux(3), 8, 7 }, /* MII_RXD[0] */
+};
+
+const struct pinmux_config emac_pins_mdio[] = {
+ { pinmux(4), 8, 0 }, /* MDIO_CLK */
+ { pinmux(4), 8, 1 }, /* MDIO_D */
+};
+
+/* I2C pin muxer settings */
+const struct pinmux_config i2c0_pins[] = {
+ { pinmux(4), 2, 2 }, /* I2C0_SCL */
+ { pinmux(4), 2, 3 }, /* I2C0_SDA */
+};
+
+const struct pinmux_config i2c1_pins[] = {
+ { pinmux(4), 4, 4 }, /* I2C1_SCL */
+ { pinmux(4), 4, 5 }, /* I2C1_SDA */
+};
+
+/* EMIFA pin muxer settings */
+const struct pinmux_config emifa_pins_cs2[] = {
+ { pinmux(7), 1, 0 }, /* EMA_CS2 */
+};
+
+const struct pinmux_config emifa_pins_cs3[] = {
+ { pinmux(7), 1, 1 }, /* EMA_CS[3] */
+};
+
+const struct pinmux_config emifa_pins_cs4[] = {
+ { pinmux(7), 1, 2 }, /* EMA_CS[4] */
+};
+
+const struct pinmux_config emifa_pins_nand[] = {
+ { pinmux(7), 1, 4 }, /* EMA_WE */
+ { pinmux(7), 1, 5 }, /* EMA_OE */
+ { pinmux(9), 1, 0 }, /* EMA_D[7] */
+ { pinmux(9), 1, 1 }, /* EMA_D[6] */
+ { pinmux(9), 1, 2 }, /* EMA_D[5] */
+ { pinmux(9), 1, 3 }, /* EMA_D[4] */
+ { pinmux(9), 1, 4 }, /* EMA_D[3] */
+ { pinmux(9), 1, 5 }, /* EMA_D[2] */
+ { pinmux(9), 1, 6 }, /* EMA_D[1] */
+ { pinmux(9), 1, 7 }, /* EMA_D[0] */
+ { pinmux(12), 1, 5 }, /* EMA_A[2] */
+ { pinmux(12), 1, 6 }, /* EMA_A[1] */
+};
+
+/* NOR pin muxer settings */
+const struct pinmux_config emifa_pins_nor[] = {
+ { pinmux(5), 1, 6 }, /* EMA_BA[1] */
+ { pinmux(6), 1, 6 }, /* EMA_WAIT[1] */
+ { pinmux(7), 1, 4 }, /* EMA_WE */
+ { pinmux(7), 1, 5 }, /* EMA_OE */
+ { pinmux(8), 1, 0 }, /* EMA_D[15] */
+ { pinmux(8), 1, 1 }, /* EMA_D[14] */
+ { pinmux(8), 1, 2 }, /* EMA_D[13] */
+ { pinmux(8), 1, 3 }, /* EMA_D[12] */
+ { pinmux(8), 1, 4 }, /* EMA_D[11] */
+ { pinmux(8), 1, 5 }, /* EMA_D[10] */
+ { pinmux(8), 1, 6 }, /* EMA_D[9] */
+ { pinmux(8), 1, 7 }, /* EMA_D[8] */
+ { pinmux(9), 1, 0 }, /* EMA_D[7] */
+ { pinmux(9), 1, 1 }, /* EMA_D[6] */
+ { pinmux(9), 1, 2 }, /* EMA_D[5] */
+ { pinmux(9), 1, 3 }, /* EMA_D[4] */
+ { pinmux(9), 1, 4 }, /* EMA_D[3] */
+ { pinmux(9), 1, 5 }, /* EMA_D[2] */
+ { pinmux(9), 1, 6 }, /* EMA_D[1] */
+ { pinmux(9), 1, 7 }, /* EMA_D[0] */
+ { pinmux(10), 1, 1 }, /* EMA_A[22] */
+ { pinmux(10), 1, 2 }, /* EMA_A[21] */
+ { pinmux(10), 1, 3 }, /* EMA_A[20] */
+ { pinmux(10), 1, 4 }, /* EMA_A[19] */
+ { pinmux(10), 1, 5 }, /* EMA_A[18] */
+ { pinmux(10), 1, 6 }, /* EMA_A[17] */
+ { pinmux(10), 1, 7 }, /* EMA_A[16] */
+ { pinmux(11), 1, 0 }, /* EMA_A[15] */
+ { pinmux(11), 1, 1 }, /* EMA_A[14] */
+ { pinmux(11), 1, 2 }, /* EMA_A[13] */
+ { pinmux(11), 1, 3 }, /* EMA_A[12] */
+ { pinmux(11), 1, 4 }, /* EMA_A[11] */
+ { pinmux(11), 1, 5 }, /* EMA_A[10] */
+ { pinmux(11), 1, 6 }, /* EMA_A[9] */
+ { pinmux(11), 1, 7 }, /* EMA_A[8] */
+ { pinmux(12), 1, 0 }, /* EMA_A[7] */
+ { pinmux(12), 1, 1 }, /* EMA_A[6] */
+ { pinmux(12), 1, 2 }, /* EMA_A[5] */
+ { pinmux(12), 1, 3 }, /* EMA_A[4] */
+ { pinmux(12), 1, 4 }, /* EMA_A[3] */
+ { pinmux(12), 1, 5 }, /* EMA_A[2] */
+ { pinmux(12), 1, 6 }, /* EMA_A[1] */
+ { pinmux(12), 1, 7 }, /* EMA_A[0] */
+};
clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLPWRDN);
clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_RES_9);
- setbits_le32(&dv_pll0_regs->pllctl, clksrc << 8);
+ setbits_le32(&dv_pll0_regs->pllctl,
+ clksrc << PLLCTL_CLOCK_MODE_SHIFT);
/*
* Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll0_regs->secctl);
/* Program the PostDiv for PLL1 */
- writel(0x8000, &dv_pll0_regs->postdiv);
+ writel(PLL_POSTDEN, &dv_pll0_regs->postdiv);
/* Post divider setting for PLL1 */
writel(CONFIG_SYS_DM36x_PLL1_PLLDIV1, &dv_pll0_regs->plldiv1);
* VDB has input on MXI pin
*/
clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_RES_9);
- setbits_le32(&dv_pll1_regs->pllctl, clksrc << 8);
+ setbits_le32(&dv_pll1_regs->pllctl,
+ clksrc << PLLCTL_CLOCK_MODE_SHIFT);
/*
* Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
writel(pllm, &dv_pll1_regs->pllm);
writel(prediv, &dv_pll1_regs->prediv);
- writel(0x8000, &dv_pll1_regs->postdiv);
+ writel(PLL_POSTDEN, &dv_pll1_regs->postdiv);
/* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */
writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE |
VPSS_CLK_CTL_VPSS_CLKMD);
/* LPSC SyncReset DDR Clock Enable */
- writel(((readl(&dv_psc_regs->mdctl[47]) & ~PSC_MD_STATE_MSK) |
- PSC_SYNCRESET), &dv_psc_regs->mdctl[47]);
+ writel(((readl(&dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]) &
+ ~PSC_MD_STATE_MSK) | PSC_SYNCRESET),
+ &dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]);
writel((1 << PdNum), &dv_psc_regs->ptcmd);
while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) == 0))
;
- while (!((readl(&dv_psc_regs->mdstat[47]) & PSC_MD_STATE_MSK) ==
- PSC_SYNCRESET))
+ while (!((readl(&dv_psc_regs->mdstat[DAVINCI_LPSC_VPSSMASTER]) &
+ PSC_MD_STATE_MSK) == PSC_SYNCRESET))
;
}
void dm365_por_reset(void)
{
- if (readl(&dv_pll0_regs->rstype) & 3)
+ if (readl(&dv_pll0_regs->rstype) &
+ (PLL_RSTYPE_POR | PLL_RSTYPE_XWRST))
dm365_vpss_sync_reset();
}
for (lpscgroup = lpscmin; lpscgroup <= lpscmax; lpscgroup++) {
if (lpscgroup == 0) {
- lpsc_start = 0; /* Enabling LPSC 3 to 28 SCR first */
- lpsc_end = 28;
+ /* Enabling LPSC 3 to 28 SCR first */
+ lpsc_start = DAVINCI_LPSC_VPSSMSTR;
+ lpsc_end = DAVINCI_LPSC_TIMER1;
} else if (lpscgroup == 1) { /* Skip locked LPSCs [29-37] */
- lpsc_start = 38;
- lpsc_end = 47;
+ lpsc_start = DAVINCI_LPSC_CFG5;
+ lpsc_end = DAVINCI_LPSC_VPSSMASTER;
} else {
- lpsc_start = 50;
- lpsc_end = 51;
+ lpsc_start = DAVINCI_LPSC_MJCP;
+ lpsc_end = DAVINCI_LPSC_HDVICP;
}
/* NEXT=0x3, Enable LPSC's */
for (i = lpsc_start; i <= lpsc_end; i++)
- setbits_le32(&dv_psc_regs->mdctl[i], 0x3);
+ setbits_le32(&dv_psc_regs->mdctl[i], PSC_ENABLE);
/*
* Program goctl to start transition sequence for LPSCs
/* Wait for MODSTAT = ENABLE from LPSC's */
for (i = lpsc_start; i <= lpsc_end; i++)
while (!((readl(&dv_psc_regs->mdstat[i]) &
- PSC_MD_STATE_MSK) == 0x3))
+ PSC_MD_STATE_MSK) == PSC_ENABLE))
;
}
}
writel(CONFIG_SYS_DM36x_AWCCR, &davinci_emif_regs->awccr);
writel(CONFIG_SYS_DM36x_AB1CR, &davinci_emif_regs->ab1cr);
- setbits_le32(&davinci_emif_regs->nandfcr, 1);
+ setbits_le32(&davinci_emif_regs->nandfcr, DAVINCI_NANDFCR_CS2NAND);
writel(CONFIG_SYS_DM36x_AB2CR, &davinci_emif_regs->ab2cr);
void dm36x_lowlevel_init(ulong bootflag)
{
- /*
- * copied from arch/arm/cpu/arm926ejs/start.S
- *
- * flush v4 I/D caches
- */
- asm("mov r0, #0");
- asm("mcr p15, 0, r0, c7, c7, 0"); /* flush v3/v4 cache */
- asm("mcr p15, 0, r0, c8, c7, 0"); /* flush v4 TLB */
-
- /*
- * disable MMU stuff and caches
- */
- asm("mrc p15, 0, r0, c1, c0, 0");
- /* clear bits 13, 9:8 (--V- --RS) */
- asm("bic r0, r0, #0x00002300");
- /* clear bits 7, 2:0 (B--- -CAM) */
- asm("bic r0, r0, #0x00000087");
- /* set bit 2 (A) Align */
- asm("orr r0, r0, #0x00000002");
- /* set bit 12 (I) I-Cache */
- asm("orr r0, r0, #0x00001000");
- asm("mcr p15, 0, r0, c1, c0, 0");
+ struct davinci_uart_ctrl_regs *davinci_uart_ctrl_regs =
+ (struct davinci_uart_ctrl_regs *)(CONFIG_SYS_NS16550_COM1 +
+ DAVINCI_UART_CTRL_BASE);
/* Mask all interrupts */
- writel(0x04, &dv_aintc_regs->intctl);
+ writel(DV_AINTC_INTCTL_IDMODE, &dv_aintc_regs->intctl);
writel(0x0, &dv_aintc_regs->eabase);
writel(0x0, &dv_aintc_regs->eint0);
writel(0x0, &dv_aintc_regs->eint1);
* Fix Power and Emulation Management Register
* see sprufh2.pdf page 38 Table 22
*/
- writel(0x0000e003, (CONFIG_SYS_NS16550_COM1 + 0x30));
+ writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST |
+ DAVINCI_UART_PWREMU_MGMT_UTRST),
+ &davinci_uart_ctrl_regs->pwremu_mgmt);
+
puts("ddr init\n");
dm365_ddr_setup();
#include <net.h>
#include <dp83848.h>
#include <asm/arch/emac_defs.h>
+#include "../../../../../drivers/net/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
#include <net.h>
#include <miiphy.h>
#include <asm/arch/emac_defs.h>
+#include "../../../../../drivers/net/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
#include <net.h>
#include <asm/arch/emac_defs.h>
#include <asm/io.h>
+#include "../../../../../drivers/net/davinci_emac.h"
int ksz8873_is_phy_connected(int phy_addr)
{
#include <miiphy.h>
#include <lxt971a.h>
#include <asm/arch/emac_defs.h>
+#include "../../../../../drivers/net/davinci_emac.h"
#ifdef CONFIG_DRIVER_TI_EMAC
#endif
#ifdef CONFIG_DRIVER_TI_EMAC
-
-/* Read ethernet MAC address from EEPROM for DVEVM compatible boards.
+/*
+ * Read ethernet MAC address from EEPROM for DVEVM compatible boards.
* Returns 1 if found, 0 otherwise.
*/
int dvevm_read_mac_address(uint8_t *buf)
{
#ifdef CONFIG_SYS_I2C_EEPROM_ADDR
/* Read MAC address. */
- if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7F00, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
- (uint8_t *) &buf[0], 6))
+ if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0x7F00,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &buf[0], 6))
goto i2cerr;
/* Check that MAC address is valid. */
return 1; /* Found */
i2cerr:
- printf("Read from EEPROM @ 0x%02x failed\n", CONFIG_SYS_I2C_EEPROM_ADDR);
+ printf("Read from EEPROM @ 0x%02x failed\n",
+ CONFIG_SYS_I2C_EEPROM_ADDR);
err:
#endif /* CONFIG_SYS_I2C_EEPROM_ADDR */
eth_getenv_enetaddr_by_index("eth", 0, env_enetaddr);
if (!memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
- /* There is no MAC address in the environment, so we initialize
- * it from the value in the EEPROM. */
+ /*
+ * There is no MAC address in the environment, so we
+ * initialize it from the value in the EEPROM.
+ */
debug("### Setting environment from EEPROM MAC address = "
"\"%pM\"\n",
env_enetaddr);
eth_setenv_enetaddr("ethaddr", rom_enetaddr);
}
}
-
#endif /* CONFIG_DRIVER_TI_EMAC */
#if defined(CONFIG_SOC_DA8XX)
* Mask all IRQs by clearing the global enable and setting
* the enable clear for all the 90 interrupts.
*/
-
writel(0, &davinci_aintc_regs->ger);
writel(0, &davinci_aintc_regs->hier);
/*
* (C) Copyright 2007-2008
- * Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Stelian Pop <stelian@popies.net>
* Lead Tech Design <www.leadtechdesign.com>
*
* (C) Copyright 2010
-
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
include $(TOPDIR)/config.mk
-LIB = $(obj)lib$(BOARD).o
+LIB = $(obj)lib$(SOC).o
-COBJS := pleb2.o flash.o
+COBJS = clock.o mx28.o iomux.o timer.o
-SRCS := $(COBJS:.o=.c)
+SRCS := $(START:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(LIB)
-$(LIB): $(obj).depend $(OBJS)
+$(LIB): $(OBJS)
$(call cmd_link_o_target, $(OBJS))
#########################################################################
--- /dev/null
+/*
+ * Freescale 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
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+
+/* The PLL frequency is always 480MHz, see section 10.2 in iMX28 datasheet. */
+#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 mx28_get_pclk(void)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t clkctrl, clkseq, clkfrac;
+ uint32_t frac, div;
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu);
+
+ /* No support of fractional divider calculation */
+ if (clkctrl &
+ (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) {
+ return 0;
+ }
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
+ div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
+ CLKCTRL_CPU_DIV_XTAL_OFFSET;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ /* REF Path */
+ clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac0);
+ frac = clkfrac & CLKCTRL_FRAC0_CPUFRAC_MASK;
+ div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
+ return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
+}
+
+static uint32_t mx28_get_hclk(void)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t div;
+ uint32_t clkctrl;
+
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus);
+
+ /* No support of fractional divider calculation */
+ if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN)
+ return 0;
+
+ div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
+ return mx28_get_pclk() / div;
+}
+
+static uint32_t mx28_get_emiclk(void)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t frac, div;
+ uint32_t clkctrl, clkseq, clkfrac;
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_emi);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_EMI) {
+ div = (clkctrl & CLKCTRL_EMI_DIV_XTAL_MASK) >>
+ CLKCTRL_EMI_DIV_XTAL_OFFSET;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac0);
+
+ /* REF Path */
+ frac = (clkfrac & CLKCTRL_FRAC0_EMIFRAC_MASK) >>
+ CLKCTRL_FRAC0_EMIFRAC_OFFSET;
+ div = clkctrl & CLKCTRL_EMI_DIV_EMI_MASK;
+ return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
+}
+
+static uint32_t mx28_get_gpmiclk(void)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ uint32_t frac, div;
+ uint32_t clkctrl, clkseq, clkfrac;
+
+ clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+ clkctrl = readl(&clkctrl_regs->hw_clkctrl_gpmi);
+
+ /* XTAL Path */
+ if (clkseq & CLKCTRL_CLKSEQ_BYPASS_GPMI) {
+ div = clkctrl & CLKCTRL_GPMI_DIV_MASK;
+ return XTAL_FREQ_MHZ / div;
+ }
+
+ clkfrac = readl(&clkctrl_regs->hw_clkctrl_frac1);
+
+ /* REF Path */
+ frac = (clkfrac & CLKCTRL_FRAC1_GPMIFRAC_MASK) >>
+ CLKCTRL_FRAC1_GPMIFRAC_OFFSET;
+ 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)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t div;
+
+ if (freq == 0)
+ return;
+
+ if (io > MXC_IOCLK1)
+ return;
+
+ div = (PLL_FREQ_KHZ * PLL_FREQ_COEF) / freq;
+
+ if (div < 18)
+ div = 18;
+
+ if (div > 35)
+ div = 35;
+
+ if (io == MXC_IOCLK0) {
+ writel(CLKCTRL_FRAC0_CLKGATEIO0,
+ &clkctrl_regs->hw_clkctrl_frac0_set);
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
+ CLKCTRL_FRAC0_IO0FRAC_MASK,
+ div << CLKCTRL_FRAC0_IO0FRAC_OFFSET);
+ writel(CLKCTRL_FRAC0_CLKGATEIO0,
+ &clkctrl_regs->hw_clkctrl_frac0_clr);
+ } else {
+ writel(CLKCTRL_FRAC0_CLKGATEIO1,
+ &clkctrl_regs->hw_clkctrl_frac0_set);
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
+ CLKCTRL_FRAC0_IO1FRAC_MASK,
+ div << CLKCTRL_FRAC0_IO1FRAC_OFFSET);
+ writel(CLKCTRL_FRAC0_CLKGATEIO1,
+ &clkctrl_regs->hw_clkctrl_frac0_clr);
+ }
+}
+
+/*
+ * Get IO clock, returns IO clock in kHz
+ */
+static uint32_t mx28_get_ioclk(enum mxs_ioclock io)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t tmp, ret;
+
+ if (io > MXC_IOCLK1)
+ return 0;
+
+ tmp = readl(&clkctrl_regs->hw_clkctrl_frac0);
+
+ if (io == MXC_IOCLK0)
+ ret = (tmp & CLKCTRL_FRAC0_IO0FRAC_MASK) >>
+ CLKCTRL_FRAC0_IO0FRAC_OFFSET;
+ else
+ ret = (tmp & CLKCTRL_FRAC0_IO1FRAC_MASK) >>
+ CLKCTRL_FRAC0_IO1FRAC_OFFSET;
+
+ return (PLL_FREQ_KHZ * PLL_FREQ_COEF) / ret;
+}
+
+/*
+ * Configure SSP clock frequency, in kHz
+ */
+void mx28_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t clk, clkreg;
+
+ if (ssp > MXC_SSPCLK3)
+ return;
+
+ clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
+ (ssp * sizeof(struct mx28_register));
+
+ clrbits_le32(clkreg, CLKCTRL_SSP_CLKGATE);
+ while (readl(clkreg) & CLKCTRL_SSP_CLKGATE)
+ ;
+
+ if (xtal)
+ clk = XTAL_FREQ_KHZ;
+ else
+ clk = mx28_get_ioclk(ssp >> 1);
+
+ if (freq > clk)
+ return;
+
+ /* Calculate the divider and cap it if necessary */
+ clk /= freq;
+ if (clk > CLKCTRL_SSP_DIV_MASK)
+ clk = CLKCTRL_SSP_DIV_MASK;
+
+ clrsetbits_le32(clkreg, CLKCTRL_SSP_DIV_MASK, clk);
+ while (readl(clkreg) & CLKCTRL_SSP_BUSY)
+ ;
+
+ if (xtal)
+ writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+ else
+ writel(CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp,
+ &clkctrl_regs->hw_clkctrl_clkseq_clr);
+}
+
+/*
+ * Return SSP frequency, in kHz
+ */
+static uint32_t mx28_get_sspclk(enum mxs_sspclock ssp)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ uint32_t clkreg;
+ uint32_t clk, tmp;
+
+ if (ssp > MXC_SSPCLK3)
+ 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 mx28_register));
+
+ tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
+
+ if (tmp == 0)
+ return 0;
+
+ clk = mx28_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)
+{
+ struct mx28_ssp_regs *ssp_regs;
+ const uint32_t sspclk = mx28_get_sspclk(bus);
+ uint32_t reg;
+ uint32_t divide, rate, tgtclk;
+
+ ssp_regs = (struct mx28_ssp_regs *)(MXS_SSP0_BASE + (bus * 0x2000));
+
+ /*
+ * SSP bit rate = SSPCLK / (CLOCK_DIVIDE * (1 + CLOCK_RATE)),
+ * CLOCK_DIVIDE has to be an even value from 2 to 254, and
+ * CLOCK_RATE could be any integer from 0 to 255.
+ */
+ for (divide = 2; divide < 254; divide += 2) {
+ rate = sspclk / freq / divide;
+ if (rate <= 256)
+ break;
+ }
+
+ tgtclk = sspclk / divide / rate;
+ while (tgtclk > freq) {
+ rate++;
+ tgtclk = sspclk / divide / rate;
+ }
+ if (rate > 256)
+ rate = 256;
+
+ /* Always set timeout the maximum */
+ reg = SSP_TIMING_TIMEOUT_MASK |
+ (divide << SSP_TIMING_CLOCK_DIVIDE_OFFSET) |
+ ((rate - 1) << SSP_TIMING_CLOCK_RATE_OFFSET);
+ writel(reg, &ssp_regs->hw_ssp_timing);
+
+ debug("SPI%d: Set freq rate to %d KHz (requested %d KHz)\n",
+ bus, tgtclk, freq);
+}
+
+uint32_t mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return mx28_get_pclk() * 1000000;
+ case MXC_GPMI_CLK:
+ return mx28_get_gpmiclk() * 1000000;
+ case MXC_AHB_CLK:
+ case MXC_IPG_CLK:
+ return mx28_get_hclk() * 1000000;
+ case MXC_EMI_CLK:
+ return mx28_get_emiclk();
+ case MXC_IO0_CLK:
+ return mx28_get_ioclk(MXC_IOCLK0);
+ case MXC_IO1_CLK:
+ return mx28_get_ioclk(MXC_IOCLK1);
+ case MXC_SSP0_CLK:
+ return mx28_get_sspclk(MXC_SSPCLK0);
+ case MXC_SSP1_CLK:
+ return mx28_get_sspclk(MXC_SSPCLK1);
+ case MXC_SSP2_CLK:
+ return mx28_get_sspclk(MXC_SSPCLK2);
+ case MXC_SSP3_CLK:
+ return mx28_get_sspclk(MXC_SSPCLK3);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+
+#if defined(CONFIG_MX23)
+#define DRIVE_OFFSET 0x200
+#define PULL_OFFSET 0x400
+#elif defined(CONFIG_MX28)
+#define DRIVE_OFFSET 0x300
+#define PULL_OFFSET 0x600
+#else
+#error "Please select CONFIG_MX23 or CONFIG_MX28"
+#endif
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+ u32 reg, ofs, bp, bm;
+ void *iomux_base = (void *)MXS_PINCTRL_BASE;
+ struct mx28_register *mxs_reg;
+
+ /* muxsel */
+ ofs = 0x100;
+ ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+ bp = PAD_PIN(pad) % 16 * 2;
+ bm = 0x3 << bp;
+ reg = readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MUXSEL(pad) << bp;
+ writel(reg, iomux_base + ofs);
+
+ /* drive */
+ ofs = DRIVE_OFFSET;
+ ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+ /* mA */
+ if (PAD_MA_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4;
+ bm = 0x3 << bp;
+ reg = readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MA(pad) << bp;
+ writel(reg, iomux_base + ofs);
+ }
+ /* vol */
+ if (PAD_VOL_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4 + 2;
+ mxs_reg = (struct mx28_register *)(iomux_base + ofs);
+ if (PAD_VOL(pad))
+ writel(1 << bp, &mxs_reg->reg_set);
+ else
+ writel(1 << bp, &mxs_reg->reg_clr);
+ }
+
+ /* pull */
+ if (PAD_PULL_VALID(pad)) {
+ ofs = PULL_OFFSET;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ mxs_reg = (struct mx28_register *)(iomux_base + ofs);
+ if (PAD_PULL(pad))
+ writel(1 << bp, &mxs_reg->reg_set);
+ else
+ writel(1 << bp, &mxs_reg->reg_clr);
+ }
+
+ return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+ const iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Freescale 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
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* 1 second delay should be plenty of time for block reset. */
+#define RESET_MAX_TIMEOUT 1000000
+
+#define MX28_BLOCK_SFTRST (1 << 31)
+#define MX28_BLOCK_CLKGATE (1 << 30)
+
+/* Lowlevel init isn't used on i.MX28, so just have a dummy here */
+inline void lowlevel_init(void) {}
+
+void reset_cpu(ulong ignored) __attribute__((noreturn));
+
+void reset_cpu(ulong ignored)
+{
+
+ struct mx28_rtc_regs *rtc_regs =
+ (struct mx28_rtc_regs *)MXS_RTC_BASE;
+
+ /* Wait 1 uS before doing the actual watchdog reset */
+ writel(1, &rtc_regs->hw_rtc_watchdog);
+ writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
+
+ /* Endless loop, reset will exit from here */
+ for (;;)
+ ;
+}
+
+int mx28_wait_mask_set(struct mx28_register *reg, uint32_t mask, int timeout)
+{
+ while (--timeout) {
+ if ((readl(®->reg) & mask) == mask)
+ break;
+ udelay(1);
+ }
+
+ return !timeout;
+}
+
+int mx28_wait_mask_clr(struct mx28_register *reg, uint32_t mask, int timeout)
+{
+ while (--timeout) {
+ if ((readl(®->reg) & mask) == 0)
+ break;
+ udelay(1);
+ }
+
+ return !timeout;
+}
+
+int mx28_reset_block(struct mx28_register *reg)
+{
+ /* Clear SFTRST */
+ writel(MX28_BLOCK_SFTRST, ®->reg_clr);
+
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+ return 1;
+
+ /* Clear CLKGATE */
+ writel(MX28_BLOCK_CLKGATE, ®->reg_clr);
+
+ /* Set SFTRST */
+ writel(MX28_BLOCK_SFTRST, ®->reg_set);
+
+ /* Wait for CLKGATE being set */
+ if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+ return 1;
+
+ /* Clear SFTRST */
+ writel(MX28_BLOCK_SFTRST, ®->reg_clr);
+
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+ return 1;
+
+ /* Clear CLKGATE */
+ writel(MX28_BLOCK_CLKGATE, ®->reg_clr);
+
+ if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+ return 1;
+
+ return 0;
+}
+
+void mx28_fixup_vt(uint32_t start_addr)
+{
+ uint32_t *vt = (uint32_t *)0x20;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ vt[i] = start_addr + (4 * i);
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+ mx28_fixup_vt(gd->relocaddr);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init(void)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ extern uint32_t _start;
+
+ mx28_fixup_vt((uint32_t)&_start);
+
+ /*
+ * Enable NAND clock
+ */
+ /* Clear bypass bit */
+ writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+
+ /* Set GPMI clock to ref_gpmi / 12 */
+ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_gpmi,
+ CLKCTRL_GPMI_CLKGATE | CLKCTRL_GPMI_DIV_MASK, 1);
+
+ udelay(1000);
+
+ /*
+ * Configure GPIO unit
+ */
+ mxs_gpio_init();
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ printf("Freescale i.MX28 family\n");
+ return 0;
+}
+#endif
+
+int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ printf("CPU: %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
+ printf("BUS: %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
+ printf("EMI: %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
+ printf("GPMI: %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
+ return 0;
+}
+
+/*
+ * Initializes on-chip ethernet controllers.
+ */
+#ifdef CONFIG_CMD_NET
+int cpu_eth_init(bd_t *bis)
+{
+ struct mx28_clkctrl_regs *clkctrl_regs =
+ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+ /* Turn on ENET clocks */
+ clrbits_le32(&clkctrl_regs->hw_clkctrl_enet,
+ CLKCTRL_ENET_SLEEP | CLKCTRL_ENET_DISABLE);
+
+ /* Set up ENET PLL for 50 MHz */
+ /* Power on ENET PLL */
+ writel(CLKCTRL_PLL2CTRL0_POWER,
+ &clkctrl_regs->hw_clkctrl_pll2ctrl0_set);
+
+ udelay(10);
+
+ /* Gate on ENET PLL */
+ writel(CLKCTRL_PLL2CTRL0_CLKGATE,
+ &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
+
+ /* Enable pad output */
+ setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+
+ return 0;
+}
+#endif
+
+U_BOOT_CMD(
+ clocks, CONFIG_SYS_MAXARGS, 1, do_mx28_showclocks,
+ "display clocks",
+ ""
+);
--- /dev/null
+/*
+ * Freescale i.MX28 timer driver
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+/* Maximum fixed count */
+#define TIMER_LOAD_VAL 0xffffffff
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp (gd->tbl)
+#define lastdec (gd->lastinc)
+
+/*
+ * This driver uses 1kHz clock source.
+ */
+#define MX28_INCREMENTER_HZ 1000
+
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+ return tick / (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long time_to_tick(unsigned long time)
+{
+ return time * (MX28_INCREMENTER_HZ / CONFIG_SYS_HZ);
+}
+
+/* Calculate how many ticks happen in "us" microseconds */
+static inline unsigned long us_to_tick(unsigned long us)
+{
+ return (us * MX28_INCREMENTER_HZ) / 1000000;
+}
+
+int timer_init(void)
+{
+ struct mx28_timrot_regs *timrot_regs =
+ (struct mx28_timrot_regs *)MXS_TIMROT_BASE;
+
+ /* Reset Timers and Rotary Encoder module */
+ mx28_reset_block(&timrot_regs->hw_timrot_rotctrl_reg);
+
+ /* Set fixed_count to 0 */
+ writel(0, &timrot_regs->hw_timrot_fixed_count0);
+
+ /* 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 */
+ writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+
+ return 0;
+}
+
+ulong get_timer(ulong base)
+{
+ struct mx28_timrot_regs *timrot_regs =
+ (struct mx28_timrot_regs *)MXS_TIMROT_BASE;
+
+ /* Current tick value */
+ uint32_t now = readl(&timrot_regs->hw_timrot_running_count0);
+
+ if (lastdec >= now) {
+ /*
+ * normal mode (non roll)
+ * move stamp forward with absolut diff ticks
+ */
+ timestamp += (lastdec - now);
+ } else {
+ /* we have rollover of decrementer */
+ timestamp += (TIMER_LOAD_VAL - now) + lastdec;
+
+ }
+ lastdec = now;
+
+ return tick_to_time(timestamp) - base;
+}
+
+/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
+#define MX28_HW_DIGCTL_MICROSECONDS 0x8001c0c0
+
+void __udelay(unsigned long usec)
+{
+ uint32_t old, new, incr;
+ uint32_t counter = 0;
+
+ old = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+ while (counter < usec) {
+ new = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+ /* Check if the timer wrapped. */
+ if (new < old) {
+ incr = 0xffffffff - old;
+ incr += new;
+ } else {
+ incr = new - old;
+ }
+
+ /*
+ * Check if we are close to the maximum time and the counter
+ * would wrap if incremented. If that's the case, break out
+ * from the loop as the requested delay time passed.
+ */
+ if (counter + incr < counter)
+ break;
+
+ counter += incr;
+ old = new;
+ }
+}
#include <common.h>
#include <command.h>
+#include <linux/compiler.h>
#if defined(CONFIG_DISPLAY_CPUINFO) && defined(CONFIG_OMAP)
u8 die_rev;
u32 omap_id;
u8 cpu_type;
- u32 system_serial_high;
- u32 system_serial_low;
+ __maybe_unused u32 system_serial_high;
+ __maybe_unused u32 system_serial_low;
u32 system_rev = 0;
jtag_id = omap_get_jtag_id();
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
-#endif
/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
#endif
mov r2, #0x00000000 /* clear */
-clbss_l:str r2, [r0] /* clear loop... */
+clbss_l:cmp r0, r1 /* clear loop... */
+ bhs clbss_e /* if reached end of bss, exit */
+ str r2, [r0]
add r0, r0, #4
- cmp r0, r1
- bne clbss_l
+ b clbss_l
+clbss_e:
#ifndef CONFIG_SPL_BUILD
bl coloured_LED_init
*
*************************************************************************
*/
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* flush v4 I/D caches
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*
* Go setup Memory and board specific bits prior to relocation.
*/
mov ip, lr /* perserve link reg across call */
bl lowlevel_init /* go setup pll,mux,memory */
mov lr, ip /* restore link */
- mov pc, lr /* back to my caller */
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+ mov pc, lr /* back to my caller */
#ifndef CONFIG_SPL_BUILD
/*
ifndef CONFIG_SPL_BUILD
COBJS += cache_v7.o
-COBJS += cpu.o
endif
-COBJS += syslib.o
+COBJS += cpu.o
+COBJS += syslib.o
SRCS := $(START:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
* dcache_disable() in turn flushes the d-cache and disables MMU
*/
dcache_disable();
+ v7_outer_cache_disable();
/*
* After D-cache is flushed and before it is disabled there may
if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN)
refclk *= 2;
- refclk /= pdf + 1;
+ do_div(refclk, pdf + 1);
temp = refclk * mfn_abs;
do_div(temp, mfd + 1);
ret = refclk * mfi;
COBJS += gpio.o
endif
+ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+COBJS += hwinit-common.o
+COBJS += clocks-common.o
+COBJS += emif-common.o
+SOBJS += lowlevel_init.o
+endif
+
ifdef CONFIG_SPL_BUILD
COBJS += spl.o
ifdef CONFIG_SPL_NAND_SUPPORT
endif
endif
+ifndef CONFIG_SPL_BUILD
+ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
+COBJS += mem-common.o
+endif
+endif
+
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
--- /dev/null
+/*
+ *
+ * Clock initialization for OMAP4
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.com>
+ *
+ * Based on previous work by:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/omap_common.h>
+#include <asm/gpio.h>
+#include <asm/arch/clocks.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/utils.h>
+#include <asm/omap_gpio.h>
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ * printing to console doesn't work unless
+ * this code is executed from SPL
+ */
+#define printf(fmt, args...)
+#define puts(s)
+#endif
+
+static inline u32 __get_sys_clk_index(void)
+{
+ u32 ind;
+ /*
+ * For ES1 the ROM code calibration of sys clock is not reliable
+ * due to hw issue. So, use hard-coded value. If this value is not
+ * correct for any board over-ride this function in board file
+ * From ES2.0 onwards you will get this information from
+ * CM_SYS_CLKSEL
+ */
+ if (omap_revision() == OMAP4430_ES1_0)
+ ind = OMAP_SYS_CLK_IND_38_4_MHZ;
+ else {
+ /* SYS_CLKSEL - 1 to match the dpll param array indices */
+ ind = (readl(&prcm->cm_sys_clksel) &
+ CM_SYS_CLKSEL_SYS_CLKSEL_MASK) - 1;
+ }
+ return ind;
+}
+
+u32 get_sys_clk_index(void)
+ __attribute__ ((weak, alias("__get_sys_clk_index")));
+
+u32 get_sys_clk_freq(void)
+{
+ u8 index = get_sys_clk_index();
+ return sys_clk_array[index];
+}
+
+static inline void do_bypass_dpll(u32 *const base)
+{
+ struct dpll_regs *dpll_regs = (struct dpll_regs *)base;
+
+ clrsetbits_le32(&dpll_regs->cm_clkmode_dpll,
+ CM_CLKMODE_DPLL_DPLL_EN_MASK,
+ DPLL_EN_FAST_RELOCK_BYPASS <<
+ CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_bypass(u32 *const base)
+{
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+ if (!wait_on_value(ST_DPLL_CLK_MASK, 0, &dpll_regs->cm_idlest_dpll,
+ LDELAY)) {
+ printf("Bypassing DPLL failed %p\n", base);
+ }
+}
+
+static inline void do_lock_dpll(u32 *const base)
+{
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+ clrsetbits_le32(&dpll_regs->cm_clkmode_dpll,
+ CM_CLKMODE_DPLL_DPLL_EN_MASK,
+ DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
+}
+
+static inline void wait_for_lock(u32 *const base)
+{
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+ if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
+ &dpll_regs->cm_idlest_dpll, LDELAY)) {
+ printf("DPLL locking failed for %p\n", base);
+ hang();
+ }
+}
+
+inline u32 check_for_lock(u32 *const base)
+{
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+ u32 lock = readl(&dpll_regs->cm_idlest_dpll) & ST_DPLL_CLK_MASK;
+
+ return lock;
+}
+
+static void do_setup_dpll(u32 *const base, const struct dpll_params *params,
+ u8 lock, char *dpll)
+{
+ u32 temp, M, N;
+ struct dpll_regs *const dpll_regs = (struct dpll_regs *)base;
+
+ temp = readl(&dpll_regs->cm_clksel_dpll);
+
+ if (check_for_lock(base)) {
+ /*
+ * The Dpll has already been locked by rom code using CH.
+ * Check if M,N are matching with Ideal nominal opp values.
+ * If matches, skip the rest otherwise relock.
+ */
+ M = (temp & CM_CLKSEL_DPLL_M_MASK) >> CM_CLKSEL_DPLL_M_SHIFT;
+ N = (temp & CM_CLKSEL_DPLL_N_MASK) >> CM_CLKSEL_DPLL_N_SHIFT;
+ if ((M != (params->m)) || (N != (params->n))) {
+ debug("\n %s Dpll locked, but not for ideal M = %d,"
+ "N = %d values, current values are M = %d,"
+ "N= %d" , dpll, params->m, params->n,
+ M, N);
+ } else {
+ /* Dpll locked with ideal values for nominal opps. */
+ debug("\n %s Dpll already locked with ideal"
+ "nominal opp values", dpll);
+ goto setup_post_dividers;
+ }
+ }
+
+ bypass_dpll(base);
+
+ /* Set M & N */
+ temp &= ~CM_CLKSEL_DPLL_M_MASK;
+ temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
+
+ temp &= ~CM_CLKSEL_DPLL_N_MASK;
+ temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK;
+
+ writel(temp, &dpll_regs->cm_clksel_dpll);
+
+ /* Lock */
+ if (lock)
+ do_lock_dpll(base);
+
+setup_post_dividers:
+ setup_post_dividers(base, params);
+
+ /* Wait till the DPLL locks */
+ if (lock)
+ wait_for_lock(base);
+}
+
+u32 omap_ddr_clk(void)
+{
+ u32 ddr_clk, sys_clk_khz, omap_rev, divider;
+ const struct dpll_params *core_dpll_params;
+
+ omap_rev = omap_revision();
+ sys_clk_khz = get_sys_clk_freq() / 1000;
+
+ core_dpll_params = get_core_dpll_params();
+
+ debug("sys_clk %d\n ", sys_clk_khz * 1000);
+
+ /* Find Core DPLL locked frequency first */
+ ddr_clk = sys_clk_khz * 2 * core_dpll_params->m /
+ (core_dpll_params->n + 1);
+
+ if (omap_rev < OMAP5430_ES1_0) {
+ /*
+ * DDR frequency is PHY_ROOT_CLK/2
+ * PHY_ROOT_CLK = Fdpll/2/M2
+ */
+ divider = 4;
+ } else {
+ /*
+ * DDR frequency is PHY_ROOT_CLK
+ * PHY_ROOT_CLK = Fdpll/2/M2
+ */
+ divider = 2;
+ }
+
+ ddr_clk = ddr_clk / divider / core_dpll_params->m2;
+ ddr_clk *= 1000; /* convert to Hz */
+ debug("ddr_clk %d\n ", ddr_clk);
+
+ return ddr_clk;
+}
+
+/*
+ * Lock MPU dpll
+ *
+ * Resulting MPU frequencies:
+ * 4430 ES1.0 : 600 MHz
+ * 4430 ES2.x : 792 MHz (OPP Turbo)
+ * 4460 : 920 MHz (OPP Turbo) - DCC disabled
+ */
+void configure_mpu_dpll(void)
+{
+ const struct dpll_params *params;
+ struct dpll_regs *mpu_dpll_regs;
+ u32 omap_rev;
+ omap_rev = omap_revision();
+
+ /*