summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
authorJason Liu <r64343@freescale.com>2010-07-07 05:33:19 +0800
committerJason Liu <r64343@freescale.com>2010-07-07 05:35:42 +0800
commit315847875c915dc4ee666743bf99235a4f9a4b8d (patch)
tree3826d1d2c017bc1ec39a8e6fcc440a9164c43254 /cpu
parent65d7ce607bd4a831c3da00884d7bf00fc412928f (diff)
downloadu-boot-imx-315847875c915dc4ee666743bf99235a4f9a4b8d.zip
u-boot-imx-315847875c915dc4ee666743bf99235a4f9a4b8d.tar.gz
u-boot-imx-315847875c915dc4ee666743bf99235a4f9a4b8d.tar.bz2
ENGR00124359 Add uboot support for MX50
Add initial support for MX50 -Support mddr200Mhz, lpddr2266Mhz ARM2 board, -Support boot from SD/MMC, -Support boot from SPI-NOR, -Support FEC, UART, -Support SD/MMC/SPI command within UBOOT Signed-off-by: Anish Trivedi <anish@freescale.com> Signed-off-by: Terry Lv <r65388@freescale.com> Signed-off-by: Jason Liu <r64343@freescale.com>
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm_cortexa8/mx50/Makefile48
-rw-r--r--cpu/arm_cortexa8/mx50/cache.c44
-rw-r--r--cpu/arm_cortexa8/mx50/crm_regs.h646
-rw-r--r--cpu/arm_cortexa8/mx50/generic.c1019
-rw-r--r--cpu/arm_cortexa8/mx50/interrupts.c39
-rw-r--r--cpu/arm_cortexa8/mx50/iomux.c137
-rw-r--r--cpu/arm_cortexa8/mx50/serial.c226
-rw-r--r--cpu/arm_cortexa8/mx50/timer.c127
8 files changed, 2286 insertions, 0 deletions
diff --git a/cpu/arm_cortexa8/mx50/Makefile b/cpu/arm_cortexa8/mx50/Makefile
new file mode 100644
index 0000000..460bdd9
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 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 $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+COBJS = interrupts.o serial.o generic.o iomux.o timer.o cache.o
+COBJS += $(COBJS-y)
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm_cortexa8/mx50/cache.c b/cpu/arm_cortexa8/mx50/cache.c
new file mode 100644
index 0000000..60df92f
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/cache.c
@@ -0,0 +1,44 @@
+/*
+ * 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/cache.h>
+
+void l2_cache_enable(void)
+{
+ asm("mrc 15, 0, r0, c1, c0, 1");
+ asm("orr r0, r0, #0x2");
+ asm("mcr 15, 0, r0, c1, c0, 1");
+}
+
+void l2_cache_disable(void)
+{
+ asm("mrc 15, 0, r0, c1, c0, 1");
+ asm("bic r0, r0, #0x2");
+ asm("mcr 15, 0, r0, c1, c0, 1");
+}
+
+/*dummy function for L2 ON*/
+u32 get_device_type(void)
+{
+ return 0;
+}
diff --git a/cpu/arm_cortexa8/mx50/crm_regs.h b/cpu/arm_cortexa8/mx50/crm_regs.h
new file mode 100644
index 0000000..eb94bbe
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/crm_regs.h
@@ -0,0 +1,646 @@
+/*
+ * Copyright (C) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX50_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX50_CRM_REGS_H__
+
+#define MXC_CCM_BASE CCM_BASE_ADDR
+#define MXC_DPLL1_BASE PLL1_BASE_ADDR
+#define MXC_DPLL2_BASE PLL2_BASE_ADDR
+#define MXC_DPLL3_BASE PLL3_BASE_ADDR
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04) /* Reserved */
+#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20) /* Reserved */
+#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30) /* Reserved */
+#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34) /* Reserved */
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C) /* Reserved */
+#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40) /* Reserved */
+#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44) /* Reserved */
+#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64) /* Reserved */
+#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80)
+#define MXC_CCM_CCGR7 (MXC_CCM_BASE + 0x84)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x88)
+#define MXC_CCM_CSR2 (MXC_CCM_BASE + 0x8C)
+#define MXC_CCM_CLKSEQ_BYPASS (MXC_CCM_BASE + 0x90)
+#define MXC_CCM_CLK_SYS (MXC_CCM_BASE + 0x94)
+#define MXC_CCM_CLK_DDR (MXC_CCM_BASE + 0x98)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_CAMP1_EN (1 << 9)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY (1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE (1 << 4)
+#define MXC_CCM_CSR_CAMP1_READY (1 << 2)
+#define MXC_CCM_CSR_TEMP_MON_ALARM (1 << 1)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_PLL3_PFD_EN (0x1 << 13)
+#define MXC_CCM_CCSR_PLL2_PFD_EN (0x1 << 12)
+#define MXC_CCM_CCSR_PLL1_PFD_EN (0x1 << 11)
+#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 10)
+#define MXC_CCM_CCSR_LP_APM_SEL_OFFSET (1)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_WEIM_CLK_SEL (0x1 << 27)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL_OFFSET (25)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL_MASK (0x3 << 25)
+#define MXC_CCM_CBCDR_WEIM_PODF_OFFSET (22)
+#define MXC_CCM_CBCDR_WEIM_PODF_MASK (7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0)
+#define MXC_CCM_CBCMR_LP_APM_SEL_OFFSET (0x1)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET (21)
+#define MXC_CCM_CSCMR1_ESDHC1_CLK_SEL_MASK (0x3 << 21)
+#define MXC_CCM_CSCMR1_ESDHC2_CLK_SEL (0x1 << 20)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MASK (0x7 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC3_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC3_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC3_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC3_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR1_ESDHC1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_CLK_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_ESDHC1_CLK_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_WEIM_CLK_SEL_BUSY (1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_WEIM_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
+
+/* Define the bits in register CDCR */
+
+#define MXC_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ_STATUS (0x1 << 7)
+#define MXC_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ (0x1 << 6)
+#define MXC_CCM_CDCR_SW_DVFS_EN (0x1 << 5)
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 25)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 24)
+#define MXC_CCM_CLPCR_BYPASS_RNGB_LPM_HS (0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_WEIM_LPM_HS (0x1 << 19)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY (0x1 << 2)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 26)
+#define MXC_CCM_CISR_TEMP_MON_ALARM (0x1 << 25)
+#define MXC_CCM_CISR_WEIM_CLK_SEL_LOADED (0x1 << 23)
+#define MXC_CCM_CISR_PER_CLK_SEL_LOADED (0x1 << 22)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CISR_WEIM_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY (0x1 << 6)
+#define MXC_CCM_CISR_CAMP1_READY (0x1 << 4)
+#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1 (0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 26)
+#define MXC_CCM_CIMR_MASK_TEMP_MON_ALARM (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_WEIM_CLK_SEL_LOADED (0x1 << 23)
+#define MXC_CCM_CIMR_MASK_PER_CLK_SEL_LOADED (0x1 << 22)
+#define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_WEIM_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 6)
+#define MXC_CCM_CIMR_MASK_CAMP1_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKO1_SLOW_SEL (0x1 << 8)
+#define MXC_CCM_CCOSR_CKO1_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKO1_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKO1_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKO1_SEL_OFFSET (0)
+#define MXC_CCM_CCOSR_CKO1_SEL_MASK (0xF)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGR_CG_MASK 0x3
+
+#define MXC_CCM_CCGR0_CG15_OFFSET 30
+#define MXC_CCM_CCGR0_CG15_MASK (0x3 << 30)
+#define MXC_CCM_CCGR0_CG14_OFFSET 28
+#define MXC_CCM_CCGR0_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR0_CG13_OFFSET 26
+#define MXC_CCM_CCGR0_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR0_CG12_OFFSET 24
+#define MXC_CCM_CCGR0_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR0_CG11_OFFSET 22
+#define MXC_CCM_CCGR0_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR0_CG10_OFFSET 20
+#define MXC_CCM_CCGR0_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR0_CG9_OFFSET 18
+#define MXC_CCM_CCGR0_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR0_CG8_OFFSET 16
+#define MXC_CCM_CCGR0_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR0_CG7_OFFSET 14
+#define MXC_CCM_CCGR0_CG6_OFFSET 12
+#define MXC_CCM_CCGR0_CG5_OFFSET 10
+#define MXC_CCM_CCGR0_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGR0_CG4_OFFSET 8
+#define MXC_CCM_CCGR0_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGR0_CG3_OFFSET 6
+#define MXC_CCM_CCGR0_CG3_MASK (0x3 << 6)
+#define MXC_CCM_CCGR0_CG2_OFFSET 4
+#define MXC_CCM_CCGR0_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR0_CG1_OFFSET 2
+#define MXC_CCM_CCGR0_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGR0_CG0_OFFSET 0
+#define MXC_CCM_CCGR0_CG0_MASK 0x3
+
+#define MXC_CCM_CCGR1_CG15_OFFSET 30
+#define MXC_CCM_CCGR1_CG14_OFFSET 28
+#define MXC_CCM_CCGR1_CG13_OFFSET 26
+#define MXC_CCM_CCGR1_CG12_OFFSET 24
+#define MXC_CCM_CCGR1_CG11_OFFSET 22
+#define MXC_CCM_CCGR1_CG10_OFFSET 20
+#define MXC_CCM_CCGR1_CG9_OFFSET 18
+#define MXC_CCM_CCGR1_CG8_OFFSET 16
+#define MXC_CCM_CCGR1_CG7_OFFSET 14
+#define MXC_CCM_CCGR1_CG6_OFFSET 12
+#define MXC_CCM_CCGR1_CG5_OFFSET 10
+#define MXC_CCM_CCGR1_CG4_OFFSET 8
+#define MXC_CCM_CCGR1_CG3_OFFSET 6
+#define MXC_CCM_CCGR1_CG2_OFFSET 4
+#define MXC_CCM_CCGR1_CG1_OFFSET 2
+#define MXC_CCM_CCGR1_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR2_CG15_OFFSET 30
+#define MXC_CCM_CCGR2_CG14_OFFSET 28
+#define MXC_CCM_CCGR2_CG13_OFFSET 26
+#define MXC_CCM_CCGR2_CG12_OFFSET 24
+#define MXC_CCM_CCGR2_CG11_OFFSET 22
+#define MXC_CCM_CCGR2_CG10_OFFSET 20
+#define MXC_CCM_CCGR2_CG9_OFFSET 18
+#define MXC_CCM_CCGR2_CG8_OFFSET 16
+#define MXC_CCM_CCGR2_CG7_OFFSET 14
+#define MXC_CCM_CCGR2_CG6_OFFSET 12
+#define MXC_CCM_CCGR2_CG5_OFFSET 10
+#define MXC_CCM_CCGR2_CG4_OFFSET 8
+#define MXC_CCM_CCGR2_CG3_OFFSET 6
+#define MXC_CCM_CCGR2_CG2_OFFSET 4
+#define MXC_CCM_CCGR2_CG1_OFFSET 2
+#define MXC_CCM_CCGR2_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR3_CG15_OFFSET 30
+#define MXC_CCM_CCGR3_CG14_OFFSET 28
+#define MXC_CCM_CCGR3_CG13_OFFSET 26
+#define MXC_CCM_CCGR3_CG12_OFFSET 24
+#define MXC_CCM_CCGR3_CG11_OFFSET 22
+#define MXC_CCM_CCGR3_CG10_OFFSET 20
+#define MXC_CCM_CCGR3_CG9_OFFSET 18
+#define MXC_CCM_CCGR3_CG8_OFFSET 16
+#define MXC_CCM_CCGR3_CG7_OFFSET 14
+#define MXC_CCM_CCGR3_CG6_OFFSET 12
+#define MXC_CCM_CCGR3_CG5_OFFSET 10
+#define MXC_CCM_CCGR3_CG4_OFFSET 8
+#define MXC_CCM_CCGR3_CG3_OFFSET 6
+#define MXC_CCM_CCGR3_CG2_OFFSET 4
+#define MXC_CCM_CCGR3_CG1_OFFSET 2
+#define MXC_CCM_CCGR3_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR4_CG15_OFFSET 30
+#define MXC_CCM_CCGR4_CG14_OFFSET 28
+#define MXC_CCM_CCGR4_CG13_OFFSET 26
+#define MXC_CCM_CCGR4_CG12_OFFSET 24
+#define MXC_CCM_CCGR4_CG11_OFFSET 22
+#define MXC_CCM_CCGR4_CG10_OFFSET 20
+#define MXC_CCM_CCGR4_CG9_OFFSET 18
+#define MXC_CCM_CCGR4_CG8_OFFSET 16
+#define MXC_CCM_CCGR4_CG7_OFFSET 14
+#define MXC_CCM_CCGR4_CG6_OFFSET 12
+#define MXC_CCM_CCGR4_CG5_OFFSET 10
+#define MXC_CCM_CCGR4_CG4_OFFSET 8
+#define MXC_CCM_CCGR4_CG3_OFFSET 6
+#define MXC_CCM_CCGR4_CG2_OFFSET 4
+#define MXC_CCM_CCGR4_CG1_OFFSET 2
+#define MXC_CCM_CCGR4_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR5_CG15_OFFSET 30
+#define MXC_CCM_CCGR5_CG14_OFFSET 28
+#define MXC_CCM_CCGR5_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR5_CG13_OFFSET 26
+#define MXC_CCM_CCGR5_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR5_CG12_OFFSET 24
+#define MXC_CCM_CCGR5_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR5_CG11_OFFSET 22
+#define MXC_CCM_CCGR5_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR5_CG10_OFFSET 20
+#define MXC_CCM_CCGR5_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR5_CG9_OFFSET 18
+#define MXC_CCM_CCGR5_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR5_CG8_OFFSET 16
+#define MXC_CCM_CCGR5_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR5_CG7_OFFSET 14
+#define MXC_CCM_CCGR5_CG7_MASK (0x3 << 14)
+#define MXC_CCM_CCGR5_CG6_1_OFFSET 12
+#define MXC_CCM_CCGR5_CG6_2_OFFSET 13
+#define MXC_CCM_CCGR5_CG6_OFFSET 12
+#define MXC_CCM_CCGR5_CG6_MASK (0x3 << 12)
+#define MXC_CCM_CCGR5_CG5_OFFSET 10
+#define MXC_CCM_CCGR5_CG4_OFFSET 8
+#define MXC_CCM_CCGR5_CG3_OFFSET 6
+#define MXC_CCM_CCGR5_CG2_OFFSET 4
+#define MXC_CCM_CCGR5_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR5_CG1_OFFSET 2
+#define MXC_CCM_CCGR5_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR6_CG15_OFFSET 30
+#define MXC_CCM_CCGR6_CG14_OFFSET 28
+#define MXC_CCM_CCGR6_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR6_CG13_OFFSET 26
+#define MXC_CCM_CCGR6_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR6_CG12_OFFSET 24
+#define MXC_CCM_CCGR6_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR6_CG11_OFFSET 22
+#define MXC_CCM_CCGR6_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR6_CG10_OFFSET 20
+#define MXC_CCM_CCGR6_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR6_CG9_OFFSET 18
+#define MXC_CCM_CCGR6_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR6_CG8_OFFSET 16
+#define MXC_CCM_CCGR6_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR6_CG7_OFFSET 14
+#define MXC_CCM_CCGR6_CG7_MASK (0x3 << 14)
+#define MXC_CCM_CCGR6_CG6_OFFSET 12
+#define MXC_CCM_CCGR6_CG6_MASK (0x3 << 12)
+#define MXC_CCM_CCGR6_CG5_OFFSET 10
+#define MXC_CCM_CCGR6_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGR6_CG4_OFFSET 8
+#define MXC_CCM_CCGR6_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGR6_CG3_OFFSET 6
+#define MXC_CCM_CCGR6_CG2_OFFSET 4
+#define MXC_CCM_CCGR6_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR6_CG1_OFFSET 2
+#define MXC_CCM_CCGR6_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR7_CG15_OFFSET 30
+#define MXC_CCM_CCGR7_CG14_OFFSET 28
+#define MXC_CCM_CCGR7_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR7_CG13_OFFSET 26
+#define MXC_CCM_CCGR7_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR7_CG12_OFFSET 24
+#define MXC_CCM_CCGR7_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR7_CG11_OFFSET 22
+#define MXC_CCM_CCGR7_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR7_CG10_OFFSET 20
+#define MXC_CCM_CCGR7_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR7_CG9_OFFSET 18
+#define MXC_CCM_CCGR7_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR7_CG8_OFFSET 16
+#define MXC_CCM_CCGR7_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR7_CG7_OFFSET 14
+#define MXC_CCM_CCGR7_CG7_MASK (0x3 << 14)
+#define MXC_CCM_CCGR7_CG6_OFFSET 12
+#define MXC_CCM_CCGR7_CG6_MASK (0x3 << 12)
+#define MXC_CCM_CCGR7_CG5_OFFSET 10
+#define MXC_CCM_CCGR7_CG4_OFFSET 8
+#define MXC_CCM_CCGR7_CG3_OFFSET 6
+#define MXC_CCM_CCGR7_CG2_OFFSET 4
+#define MXC_CCM_CCGR7_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR7_CG1_OFFSET 2
+#define MXC_CCM_CCGR7_CG0_OFFSET 0
+
+/* Define the bits in registers CLKSEQ_BYPASS */
+#define MXC_CCM_CLKSEQ_BYPASS_ELCDIF_PIX_OFFSET 14
+#define MXC_CCM_CLKSEQ_BYPASS_ELCDIF_PIX_MASK (0x3 << 14)
+#define MXC_CCM_CLKSEQ_BYPASS_EPDC_PIX_OFFSET 12
+#define MXC_CCM_CLKSEQ_BYPASS_EPDC_PIX_MASK (0x3 << 12)
+#define MXC_CCM_CLKSEQ_BYPASS_MSHCX_OFFSET 10
+#define MXC_CCM_CLKSEQ_BYPASS_MSHCX_MASK (0x3 << 10)
+#define MXC_CCM_CLKSEQ_BYPASS_BCH_OFFSET 8
+#define MXC_CCM_CLKSEQ_BYPASS_BCH_MASK (0x3 << 8)
+#define MXC_CCM_CLKSEQ_BYPASS_GPMI_OFFSET 6
+#define MXC_CCM_CLKSEQ_BYPASS_GPMI_MASK (0x3 << 6)
+#define MXC_CCM_CLKSEQ_BYPASS_EPDC_OFFSET 4
+#define MXC_CCM_CLKSEQ_BYPASS_EPDC_MASK (0x3 << 4)
+#define MXC_CCM_CLKSEQ_BYPASS_DISPLY_AXI_OFFSET 2
+#define MXC_CCM_CLKSEQ_BYPASS_DISPLY_AXI_MASK (0x3 << 2)
+#define MXC_CCM_CLKSEQ_BYPASS_SYS_CLK_1 (0x1 << 1)
+#define MXC_CCM_CLKSEQ_BYPASS_SYS_CLK_0 (0x1 << 0)
+
+/* Define the bits in registers CLK_SYS */
+#define MXC_CCM_CLK_SYS_XTAL_CLKGATE_OFFSET 30
+#define MXC_CCM_CLK_SYS_XTAL_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_CLK_SYS_PLL_CLKGATE_OFFSET 28
+#define MXC_CCM_CLK_SYS_PLL_CLKGATE_MASK (0x3 << 28)
+#define MXC_CCM_CLK_SYS_DIV_XTAL_OFFSET 6
+#define MXC_CCM_CLK_SYS_DIV_XTAL_MASK (0xf << 6)
+#define MXC_CCM_CLK_SYS_DIV_PLL_OFFSET 0
+#define MXC_CCM_CLK_SYS_DIV_PLL_MASK (0x3f << 0)
+
+/* Define the bits in registers CLK_DDR */
+#define MXC_CCM_CLK_DDR_DDR_CLKGATE_OFFSET (30)
+#define MXC_CCM_CLK_DDR_DDR_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_CLK_DDR_DDR_PFD_SEL (1 << 6)
+#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_OFFSET (0)
+#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK (0x3F)
+
+
+#define MXC_GPC_BASE (IO_ADDRESS(GPC_BASE_ADDR))
+#define MXC_DPTC_LP_BASE (MXC_GPC_BASE + 0x80)
+#define MXC_DPTC_GP_BASE (MXC_GPC_BASE + 0x100)
+#define MXC_DVFS_CORE_BASE (MXC_GPC_BASE + 0x180)
+#define MXC_DVFS_PER_BASE (MXC_GPC_BASE + 0x1C4)
+#define MXC_PGC_IPU_BASE (MXC_GPC_BASE + 0x220)
+#define MXC_PGC_VPU_BASE (MXC_GPC_BASE + 0x240)
+#define MXC_PGC_GPU_BASE (MXC_GPC_BASE + 0x260)
+#define MXC_SRPG_NEON_BASE (MXC_GPC_BASE + 0x280)
+#define MXC_SRPG_ARM_BASE (MXC_GPC_BASE + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE (MXC_GPC_BASE + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE (MXC_GPC_BASE + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE (MXC_GPC_BASE + 0x2E0)
+#define MXC_SRPG_EMI_BASE (MXC_GPC_BASE + 0x300)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
+
+/* DVFS PER */
+#define MXC_DVFSPER_LTR0 (MXC_DVFS_PER_BASE)
+#define MXC_DVFSPER_LTR1 (MXC_DVFS_PER_BASE + 0x04)
+#define MXC_DVFSPER_LTR2 (MXC_DVFS_PER_BASE + 0x08)
+#define MXC_DVFSPER_LTR3 (MXC_DVFS_PER_BASE + 0x0C)
+#define MXC_DVFSPER_LTBR0 (MXC_DVFS_PER_BASE + 0x10)
+#define MXC_DVFSPER_LTBR1 (MXC_DVFS_PER_BASE + 0x14)
+#define MXC_DVFSPER_PMCR0 (MXC_DVFS_PER_BASE + 0x18)
+#define MXC_DVFSPER_PMCR1 (MXC_DVFS_PER_BASE + 0x1C)
+
+/* GPC */
+#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
+#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
+#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
+#define MXC_GPC_ALL_PU (MXC_GPC_BASE + 0xC)
+#define MXC_GPC_NEON (MXC_GPC_BASE + 0x10)
+
+/* PGC */
+#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC)
+#define MXC_PGC_GPU_PGCR (MXC_PGC_GPU_BASE + 0x0)
+#define MXC_PGC_GPU_PGSR (MXC_PGC_GPU_BASE + 0xC)
+
+#define MXC_PGCR_PCR 1
+#define MXC_SRPGCR_PCR 1
+#define MXC_EMPGCR_PCR 1
+#define MXC_PGSR_PSR 1
+
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif /* __ARCH_ARM_MACH_MX50_CRM_REGS_H__ */
diff --git a/cpu/arm_cortexa8/mx50/generic.c b/cpu/arm_cortexa8/mx50/generic.c
new file mode 100644
index 0000000..79a803c
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/generic.c
@@ -0,0 +1,1019 @@
+/*
+ * 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/arch/mx50.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include "crm_regs.h"
+#ifdef CONFIG_CMD_CLOCK
+#include <asm/clock.h>
+#endif
+#include <div64.h>
+#ifdef CONFIG_ARCH_CPU_INIT
+#include <asm/cache-cp15.h>
+#endif
+
+enum pll_clocks {
+ PLL1_CLK = MXC_DPLL1_BASE,
+ PLL2_CLK = MXC_DPLL2_BASE,
+ PLL3_CLK = MXC_DPLL3_BASE,
+};
+
+enum pll_sw_clocks {
+ PLL1_SW_CLK,
+ PLL2_SW_CLK,
+ PLL3_SW_CLK,
+};
+
+#define AHB_CLK_ROOT 133333333
+#define IPG_CLK_ROOT 66666666
+#define IPG_PER_CLK_ROOT 40000000
+
+#ifdef CONFIG_CMD_CLOCK
+#define SZ_DEC_1M 1000000
+#define PLL_PD_MAX 16 /* Actual pd+1 */
+#define PLL_MFI_MAX 15
+#define PLL_MFI_MIN 5
+#define ARM_DIV_MAX 8
+#define IPG_DIV_MAX 4
+#define AHB_DIV_MAX 8
+#define EMI_DIV_MAX 8
+#define NFC_DIV_MAX 8
+
+struct fixed_pll_mfd {
+ u32 ref_clk_hz;
+ u32 mfd;
+};
+
+const struct fixed_pll_mfd fixed_mfd[4] = {
+ {0, 0}, /* reserved */
+ {0, 0}, /* reserved */
+ {CONFIG_MX50_HCLK_FREQ, 24 * 16}, /* 384 */
+ {0, 0}, /* reserved */
+};
+
+struct pll_param {
+ u32 pd;
+ u32 mfi;
+ u32 mfn;
+ u32 mfd;
+};
+
+#define PLL_FREQ_MAX(_ref_clk_) \
+ (4 * _ref_clk_ * PLL_MFI_MAX)
+#define PLL_FREQ_MIN(_ref_clk_) \
+ ((2 * _ref_clk_ * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
+#define MAX_DDR_CLK 420000000
+#define AHB_CLK_MAX 133333333
+#define IPG_CLK_MAX (AHB_CLK_MAX / 2)
+#define NFC_CLK_MAX 25000000
+#define HSP_CLK_MAX 133333333
+#endif
+
+static u32 __decode_pll(enum pll_clocks pll, u32 infreq)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ s64 temp;
+
+ dp_ctl = __REG(pll + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __REG(pll + MXC_PLL_DP_OP);
+ dp_mfd = __REG(pll + MXC_PLL_DP_MFD);
+ dp_mfn = __REG(pll + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __REG(pll + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __REG(pll + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __REG(pll + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * infreq;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static u32 __get_mcu_main_clk(void)
+{
+ u32 reg, freq;
+ reg = (__REG(MXC_CCM_CACRR) & MXC_CCM_CACRR_ARM_PODF_MASK) >>
+ MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ freq = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ return freq / (reg + 1);
+}
+
+/*
+ * This function returns the low power audio clock.
+ */
+u32 __get_lp_apm(void)
+{
+ u32 ret_val = 0;
+ u32 cbcmr = __REG(MXC_CCM_CBCMR);
+
+ if (((cbcmr >> MXC_CCM_CBCMR_LP_APM_SEL_OFFSET) & 0x1) == 0)
+ ret_val = CONFIG_MX50_HCLK_FREQ;
+ else
+ ret_val = ((32768 * 1024));
+
+ return ret_val;
+}
+
+static u32 __get_periph_clk(void)
+{
+ u32 reg;
+ reg = __REG(MXC_CCM_CBCDR);
+
+ switch ((reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL_MASK) >>
+ MXC_CCM_CBCDR_PERIPH_CLK_SEL_OFFSET) {
+ case 0:
+ return __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ case 1:
+ return __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ);
+ case 2:
+ return __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ);
+ default:
+ return __get_lp_apm();
+ }
+}
+
+static u32 __get_ipg_clk(void)
+{
+ u32 ahb_podf, ipg_podf;
+
+ ahb_podf = __REG(MXC_CCM_CBCDR);
+ ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET;
+ ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ return __get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1));
+}
+
+static u32 __get_ipg_per_clk(void)
+{
+ u32 pred1, pred2, podf, clk;
+ if (__REG(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL)
+ return __get_ipg_clk();
+
+ clk = __REG(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL ?
+ __get_lp_apm() : __get_periph_clk();
+
+ podf = __REG(MXC_CCM_CBCDR);
+ pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET;
+ pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET;
+ podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET;
+
+ return clk / ((pred1 + 1) * (pred2 + 1) * (podf + 1));
+}
+
+static u32 __get_uart_clk(void)
+{
+ u32 freq = 0, reg, pred, podf;
+ reg = __REG(MXC_CCM_CSCMR1);
+ switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >>
+ MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) {
+ case 0x0:
+ freq = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 0x1:
+ freq = __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 0x2:
+ freq = __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 0x3:
+ freq = __get_lp_apm();
+ break;
+ default:
+ break;
+ }
+
+ reg = __REG(MXC_CCM_CSCDR1);
+
+ pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET;
+
+ podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
+ freq /= (pred + 1) * (podf + 1);
+
+ return freq;
+}
+
+
+static u32 __get_cspi_clk(void)
+{
+ u32 ret_val = 0, pdf, pre_pdf, clk_sel, div;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr2 = __REG(MXC_CCM_CSCDR2);
+
+ pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET;
+ pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET;
+ clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \
+ >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+
+ div = (pre_pdf + 1) * (pdf + 1);
+
+ switch (clk_sel) {
+ case 0:
+ ret_val = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ) / div;
+ break;
+ case 1:
+ ret_val = __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ) / div;
+ break;
+ case 2:
+ ret_val = __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ) / div;
+ break;
+ default:
+ ret_val = __get_lp_apm() / div;
+ break;
+ }
+
+ return ret_val;
+}
+
+static u32 __get_axi_a_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_A_PODF_MASK) \
+ >> MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
+
+ return __get_periph_clk() / (pdf + 1);
+}
+
+static u32 __get_axi_b_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_B_PODF_MASK) \
+ >> MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
+
+ return __get_periph_clk() / (pdf + 1);
+}
+
+static u32 __get_ahb_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 pdf = (cbcdr & MXC_CCM_CBCDR_AHB_PODF_MASK) \
+ >> MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+
+ return __get_periph_clk() / (pdf + 1);
+}
+
+
+static u32 __get_emi_slow_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_WEIM_CLK_SEL;
+ u32 pdf = (cbcdr & MXC_CCM_CBCDR_WEIM_PODF_MASK) \
+ >> MXC_CCM_CBCDR_WEIM_PODF_OFFSET;
+
+ if (emi_clk_sel)
+ return __get_ahb_clk() / (pdf + 1);
+
+ return __get_periph_clk() / (pdf + 1);
+}
+
+static u32 __get_sys_clk(void)
+{
+ u32 ret_val = 0, clk, sys_pll_div;
+ u32 clkseq_bypass = __REG(MXC_CCM_CLKSEQ_BYPASS);
+
+ /* Fixme Not handle OSC and PFD1 mux */
+ if ((clkseq_bypass & MXC_CCM_CLKSEQ_BYPASS_SYS_CLK_1) &&
+ clkseq_bypass & MXC_CCM_CLKSEQ_BYPASS_SYS_CLK_0) {
+ sys_pll_div = __REG(MXC_CCM_CLK_SYS) \
+ & MXC_CCM_CLK_SYS_DIV_PLL_MASK;
+ clk = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ if (sys_pll_div)
+ clk /= sys_pll_div;
+ ret_val = clk;
+ } else if ((clkseq_bypass & MXC_CCM_CLKSEQ_BYPASS_SYS_CLK_0) == 0) {
+ ret_val = CONFIG_MX50_HCLK_FREQ; /* OSC */
+ } else {
+
+ printf("Warning, Fixme Not handle PFD1 mux\n");
+ }
+
+ return ret_val;
+
+}
+static u32 __get_ddr_clk(void)
+{
+ u32 ret_val = 0, clk, ddr_pll_div;
+ u32 clk_ddr = __REG(MXC_CCM_CLK_DDR);
+ u32 ddr_clk_sel = clk_ddr & MXC_CCM_CLK_DDR_DDR_PFD_SEL;
+
+ if (!ddr_clk_sel) {
+ ddr_pll_div = clk_ddr & \
+ MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK;
+ clk = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ if (ddr_pll_div)
+ clk /= ddr_pll_div;
+ ret_val = clk;
+ } else {
+
+ printf("Warning, Fixme Not handle PFD1 mux\n");
+ }
+
+ return ret_val;
+}
+
+#ifdef CONFIG_CMD_MMC
+static u32 __get_esdhc1_clk(void)
+{
+ u32 ret_val = 0, div, pre_pdf, pdf;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 esdh1_clk_sel;
+
+ esdh1_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC1_CLK_SEL_MASK) \
+ >> MXC_CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
+ pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC1_CLK_PRED_OFFSET;
+ pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC1_CLK_PODF_OFFSET ;
+
+ div = (pre_pdf + 1) * (pdf + 1);
+
+ switch (esdh1_clk_sel) {
+ case 0:
+ ret_val = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 1:
+ ret_val = __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 2:
+ ret_val = __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 3:
+ ret_val = __get_lp_apm();
+ break;
+ default:
+ break;
+ }
+
+ ret_val /= div;
+
+ return ret_val;
+}
+
+static u32 __get_esdhc3_clk(void)
+{
+ u32 ret_val = 0, div, pre_pdf, pdf;
+ u32 esdh3_clk_sel;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ esdh3_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MASK) \
+ >> MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_OFFSET;
+ pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC3_CLK_PRED_OFFSET;
+ pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR1_ESDHC3_CLK_PODF_OFFSET ;
+
+ div = (pre_pdf + 1) * (pdf + 1);
+
+ switch (esdh3_clk_sel) {
+ case 0:
+ ret_val = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 1:
+ ret_val = __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 2:
+ ret_val = __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ);
+ break;
+ case 3:
+ ret_val = __get_lp_apm();
+ break;
+ case 5 ... 8:
+ puts("Warning, Fixme,not handle PFD mux\n");
+
+ break;
+ default:
+ break;
+ }
+
+ ret_val /= div;
+
+ return ret_val;
+}
+
+static u32 __get_esdhc2_clk(void)
+{
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 esdh2_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ if (esdh2_clk_sel)
+ return __get_esdhc3_clk();
+
+ return __get_esdhc1_clk();
+}
+
+static u32 __get_esdhc4_clk(void)
+{
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 esdh4_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ if (esdh4_clk_sel)
+ return __get_esdhc3_clk();
+
+ return __get_esdhc1_clk();
+}
+#endif
+
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+ switch (clk) {
+ case MXC_ARM_CLK:
+ return __get_mcu_main_clk();
+ case MXC_PER_CLK:
+ return __get_periph_clk();
+ case MXC_AHB_CLK:
+ return __get_ahb_clk();
+ case MXC_IPG_CLK:
+ return __get_ipg_clk();
+ case MXC_IPG_PERCLK:
+ return __get_ipg_per_clk();
+ case MXC_UART_CLK:
+ return __get_uart_clk();
+#ifdef CONFIG_IMX_CSPI
+ case MXC_CSPI_CLK:
+ return __get_cspi_clk();
+#endif
+ case MXC_AXI_A_CLK:
+ return __get_axi_a_clk();
+ case MXC_AXI_B_CLK:
+ return __get_axi_b_clk();
+ case MXC_EMI_SLOW_CLK:
+ return __get_emi_slow_clk();
+ case MXC_DDR_CLK:
+ return __get_ddr_clk();
+#ifdef CONFIG_CMD_MMC
+ case MXC_ESDHC_CLK:
+ return __get_esdhc1_clk();
+ case MXC_ESDHC2_CLK:
+ return __get_esdhc2_clk();
+ case MXC_ESDHC3_CLK:
+ return __get_esdhc3_clk();
+ case MXC_ESDHC4_CLK:
+ return __get_esdhc4_clk();
+#endif
+ default:
+ break;
+ }
+ return -1;
+}
+
+void mxc_dump_clocks(void)
+{
+ u32 freq;
+ freq = __decode_pll(PLL1_CLK, CONFIG_MX50_HCLK_FREQ);
+ printf("mx50 pll1: %dMHz\n", freq / 1000000);
+ freq = __decode_pll(PLL2_CLK, CONFIG_MX50_HCLK_FREQ);
+ printf("mx50 pll2: %dMHz\n", freq / 1000000);
+ freq = __decode_pll(PLL3_CLK, CONFIG_MX50_HCLK_FREQ);
+ printf("mx50 pll3: %dMHz\n", freq / 1000000);
+ printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK));
+ printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK));
+ printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
+#ifdef CONFIG_IMX_ECSPI
+ printf("cspi clock : %dHz\n", mxc_get_clock(MXC_CSPI_CLK));
+#endif
+ printf("ahb clock : %dHz\n", mxc_get_clock(MXC_AHB_CLK));
+ printf("axi_a clock : %dHz\n", mxc_get_clock(MXC_AXI_A_CLK));
+ printf("axi_b clock : %dHz\n", mxc_get_clock(MXC_AXI_B_CLK));
+ printf("weim_clock : %dHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK));
+ printf("ddr clock : %dHz\n", mxc_get_clock(MXC_DDR_CLK));
+#ifdef CONFIG_CMD_MMC
+ printf("esdhc1 clock : %dHz\n", mxc_get_clock(MXC_ESDHC_CLK));
+ printf("esdhc2 clock : %dHz\n", mxc_get_clock(MXC_ESDHC2_CLK));
+ printf("esdhc3 clock : %dHz\n", mxc_get_clock(MXC_ESDHC3_CLK));
+ printf("esdhc4 clock : %dHz\n", mxc_get_clock(MXC_ESDHC4_CLK));
+#endif
+}
+
+#ifdef CONFIG_CMD_CLOCK
+/* precondition: m>0 and n>0. Let g=gcd(m,n). */
+static int gcd(int m, int n)
+{
+ int t;
+ while (m > 0) {
+ if (n > m) {
+ t = m;
+ m = n;
+ n = t;
+ } /* swap */
+ m -= n;
+ }
+ return n;
+}
+
+/*!
+ * This is to calculate various parameters based on reference clock and
+ * targeted clock based on the equation:
+ * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
+ * This calculation is based on a fixed MFD value for simplicity.
+ *
+ * @param ref reference clock freq in Hz
+ * @param target targeted clock in Hz
+ * @param pll pll_param structure.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ */
+static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
+{
+ u64 pd, mfi = 1, mfn, mfd, t1;
+ u32 n_target = target;
+ u32 n_ref = ref, i;
+
+ /*
+ * Make sure targeted freq is in the valid range.
+ * Otherwise the following calculation might be wrong!!!
+ */
+ if (n_target < PLL_FREQ_MIN(ref) ||
+ n_target > PLL_FREQ_MAX(ref)) {
+ printf("Targeted peripheral clock should be"
+ "within [%d - %d]\n",
+ PLL_FREQ_MIN(ref) / SZ_DEC_1M,
+ PLL_FREQ_MAX(ref) / SZ_DEC_1M);
+ return -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) {
+ if (fixed_mfd[i].ref_clk_hz == ref) {
+ mfd = fixed_mfd[i].mfd;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(fixed_mfd))
+ return -1;
+
+ /* Use n_target and n_ref to avoid overflow */
+ for (pd = 1; pd <= PLL_PD_MAX; pd++) {
+ t1 = n_target * pd;
+ do_div(t1, (4 * n_ref));
+ mfi = t1;
+ if (mfi > PLL_MFI_MAX)
+ return -1;
+ else if (mfi < 5)
+ continue;
+ break;
+ }
+ /* Now got pd and mfi already */
+ /*
+ mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
+ */
+ t1 = n_target * pd;
+ do_div(t1, 4);
+ t1 -= n_ref * mfi;
+ t1 *= mfd;
+ do_div(t1, n_ref);
+ mfn = t1;
+#ifdef CMD_CLOCK_DEBUG
+ printf("%d: ref=%d, target=%d, pd=%d,"
+ "mfi=%d,mfn=%d, mfd=%d\n",
+ __LINE__, ref, (u32)n_target,
+ (u32)pd, (u32)mfi, (u32)mfn,
+ (u32)mfd);
+#endif
+ i = 1;
+ if (mfn != 0)
+ i = gcd(mfd, mfn);
+ pll->pd = (u32)pd;
+ pll->mfi = (u32)mfi;
+ do_div(mfn, i);
+ pll->mfn = (u32)mfn;
+ do_div(mfd, i);
+ pll->mfd = (u32)mfd;
+
+ return 0;
+}
+
+int clk_info(u32 clk_type)
+{
+ switch (clk_type) {
+ case CPU_CLK:
+ printf("CPU Clock: %dHz\n",
+ mxc_get_clock(MXC_ARM_CLK));
+ break;
+ case PERIPH_CLK:
+ printf("Peripheral Clock: %dHz\n",
+ mxc_get_clock(MXC_PER_CLK));
+ break;
+ case AHB_CLK:
+ printf("AHB Clock: %dHz\n",
+ mxc_get_clock(MXC_AHB_CLK));
+ break;
+ case IPG_CLK:
+ printf("IPG Clock: %dHz\n",
+ mxc_get_clock(MXC_IPG_CLK));
+ break;
+ case IPG_PERCLK:
+ printf("IPG_PER Clock: %dHz\n",
+ mxc_get_clock(MXC_IPG_PERCLK));
+ break;
+ case UART_CLK:
+ printf("UART Clock: %dHz\n",
+ mxc_get_clock(MXC_UART_CLK));
+ break;
+ case CSPI_CLK:
+ printf("CSPI Clock: %dHz\n",
+ mxc_get_clock(MXC_CSPI_CLK));
+ break;
+ case DDR_CLK:
+ printf("DDR Clock: %dHz\n",
+ mxc_get_clock(MXC_DDR_CLK));
+ break;
+ case ALL_CLK:
+ printf("cpu clock: %dMHz\n",
+ mxc_get_clock(MXC_ARM_CLK) / SZ_DEC_1M);
+ mxc_dump_clocks();
+ break;
+ default:
+ printf("Unsupported clock type! :(\n");
+ }
+
+ return 0;
+}
+
+#define calc_div(target_clk, src_clk, limit) ({ \
+ u32 tmp = 0; \
+ if ((src_clk % target_clk) <= 100) \
+ tmp = src_clk / target_clk; \
+ else \
+ tmp = (src_clk / target_clk) + 1; \
+ if (tmp > limit) \
+ tmp = limit; \
+ (tmp - 1); \
+ })
+
+u32 calc_per_cbcdr_val(u32 per_clk, u32 cbcmr)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 tmp_clk = 0, div = 0, clk_sel = 0;
+
+ cbcdr &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+
+ /* emi_slow_podf divider */
+ tmp_clk = __get_emi_slow_clk();
+ clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
+ if (clk_sel) {
+ div = calc_div(tmp_clk, per_clk, 8);
+ cbcdr &= ~MXC_CCM_CBCDR_EMI_PODF_MASK;
+ cbcdr |= (div << MXC_CCM_CBCDR_EMI_PODF_OFFSET);
+ }
+
+ /* axi_b_podf divider */
+ tmp_clk = __get_axi_b_clk();
+ div = calc_div(tmp_clk, per_clk, 8);
+ cbcdr &= ~MXC_CCM_CBCDR_AXI_B_PODF_MASK;
+ cbcdr |= (div << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET);
+
+ /* axi_b_podf divider */
+ tmp_clk = __get_axi_a_clk();
+ div = calc_div(tmp_clk, per_clk, 8);
+ cbcdr &= ~MXC_CCM_CBCDR_AXI_A_PODF_MASK;
+ cbcdr |= (div << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET);
+
+ /* ahb podf divider */
+ tmp_clk = AHB_CLK_ROOT;
+ div = calc_div(tmp_clk, per_clk, 8);
+ cbcdr &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ cbcdr |= (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET);
+
+ return cbcdr;
+}
+
+#define CHANGE_PLL_SETTINGS(base, pd, mfi, mfn, mfd) \
+ { \
+ writel(0x1232, base + PLL_DP_CTL); \
+ writel(0x2, base + PLL_DP_CONFIG); \
+ writel(((pd - 1) << 0) | (mfi << 4), \
+ base + PLL_DP_OP); \
+ writel(mfn, base + PLL_DP_MFN); \
+ writel(mfd - 1, base + PLL_DP_MFD); \
+ writel(((pd - 1) << 0) | (mfi << 4), \
+ base + PLL_DP_HFS_OP); \
+ writel(mfn, base + PLL_DP_HFS_MFN); \
+ writel(mfd - 1, base + PLL_DP_HFS_MFD); \
+ writel(0x1232, base + PLL_DP_CTL); \
+ while (!readl(base + PLL_DP_CTL) & 0x1) \
+ ; \
+ }
+
+int config_pll_clk(enum pll_clocks pll, struct pll_param *pll_param)
+{
+ u32 ccsr = readl(CCM_BASE_ADDR + CLKCTL_CCSR);
+ u32 pll_base = pll;
+
+ switch (pll) {
+ case PLL1_CLK:
+ /* Switch ARM to PLL2 clock */
+ writel(ccsr | 0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
+ CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
+ pll_param->mfi, pll_param->mfn,
+ pll_param->mfd);
+ /* Switch back */
+ writel(ccsr & ~0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
+ break;
+ case PLL2_CLK:
+ /* Switch to pll2 bypass clock */
+ writel(ccsr | 0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
+ CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
+ pll_param->mfi, pll_param->mfn,
+ pll_param->mfd);
+ /* Switch back */
+ writel(ccsr & ~0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
+ break;
+ case PLL3_CLK:
+ /* Switch to pll3 bypass clock */
+ writel(ccsr | 0x1, CCM_BASE_ADDR + CLKCTL_CCSR);
+ CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
+ pll_param->mfi, pll_param->mfn,
+ pll_param->mfd);
+ /* Switch back */
+ writel(ccsr & ~0x1, CCM_BASE_ADDR + CLKCTL_CCSR);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int config_core_clk(u32 ref, u32 freq)
+{
+ int ret = 0;
+ u32 pll = 0;
+ struct pll_param pll_param;
+
+ memset(&pll_param, 0, sizeof(struct pll_param));
+
+ /* The case that periph uses PLL1 is not considered here */
+ pll = freq;
+ ret = calc_pll_params(ref, pll, &pll_param);
+ if (ret != 0) {
+ printf("Can't find pll parameters: %d\n",
+ ret);
+ return ret;
+ }
+
+ return config_pll_clk(PLL1_CLK, &pll_param);
+}
+
+int config_periph_clk(u32 ref, u32 freq)
+{
+ int ret = 0;
+ u32 pll = freq;
+ struct pll_param pll_param;
+
+ memset(&pll_param, 0, sizeof(struct pll_param));
+
+ if (__REG(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
+ /* Actually this case is not considered here */
+ ret = calc_pll_params(ref, pll, &pll_param);
+ if (ret != 0) {
+ printf("Can't find pll parameters: %d\n",
+ ret);
+ return ret;
+ }
+ switch ((__REG(MXC_CCM_CBCMR) & \
+ MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >>
+ MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
+ case 0:
+ return config_pll_clk(PLL1_CLK, &pll_param);
+ break;
+ case 1:
+ return config_pll_clk(PLL3_CLK, &pll_param);
+ break;
+ default:
+ return -1;
+ }
+ } else {
+ u32 old_cbcmr = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
+ u32 new_cbcdr = calc_per_cbcdr_val(pll, old_cbcmr);
+
+ /* Switch peripheral to PLL3 */
+ writel(0x00015154, CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(0x02888945, CCM_BASE_ADDR + CLKCTL_CBCDR);
+
+ /* Make sure change is effective */
+ while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
+ ;
+
+ /* Setup PLL2 */
+ ret = calc_pll_params(ref, pll, &pll_param);
+ if (ret != 0) {
+ printf("Can't find pll parameters: %d\n",
+ ret);
+ return ret;
+ }
+ config_pll_clk(PLL2_CLK, &pll_param);
+
+ /* Switch peripheral back */
+ writel(new_cbcdr, CCM_BASE_ADDR + CLKCTL_CBCDR);
+ writel(old_cbcmr, CCM_BASE_ADDR + CLKCTL_CBCMR);
+
+ /* Make sure change is effective */
+ while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
+ ;
+ puts("\n");
+ }
+
+ return 0;
+}
+
+int config_ddr_clk(u32 emi_clk)
+{
+ u32 clk_src;
+ s32 shift = 0, clk_sel, div = 1;
+ u32 cbcmr = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
+ u32 cbcdr = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
+
+ if (emi_clk > MAX_DDR_CLK) {
+ printf("DDR clock should be less than"
+ "%d MHz, assuming max value \n",
+ (MAX_DDR_CLK / SZ_DEC_1M));
+ emi_clk = MAX_DDR_CLK;
+ }
+
+ clk_src = __get_periph_clk();
+ /* Find DDR clock input */
+ clk_sel = (cbcmr >> 10) & 0x3;
+ switch (clk_sel) {
+ case 0:
+ shift = 16;
+ break;
+ case 1:
+ shift = 19;
+ break;
+ case 2:
+ shift = 22;
+ break;
+ case 3:
+ shift = 10;
+ break;
+ default:
+ return -1;
+ }
+
+ if ((clk_src % emi_clk) == 0)
+ div = clk_src / emi_clk;
+ else
+ div = (clk_src / emi_clk) + 1;
+ if (div > 8)
+ div = 8;
+
+ cbcdr = cbcdr & ~(0x7 << shift);
+ cbcdr |= ((div - 1) << shift);
+ writel(cbcdr, CCM_BASE_ADDR + CLKCTL_CBCDR);
+ while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
+ ;
+ writel(0x0, CCM_BASE_ADDR + CLKCTL_CCDR);
+
+ return 0;
+}
+
+/*!
+ * This function assumes the expected core clock has to be changed by
+ * modifying the PLL. This is NOT true always but for most of the times,
+ * it is. So it assumes the PLL output freq is the same as the expected
+ * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
+ * In the latter case, it will try to increase the presc value until
+ * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
+ * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
+ * on the targeted PLL and reference input clock to the PLL. Lastly,
+ * it sets the register based on these values along with the dividers.
+ * Note 1) There is no value checking for the passed-in divider values
+ * so the caller has to make sure those values are sensible.
+ * 2) Also adjust the NFC divider such that the NFC clock doesn't
+ * exceed NFC_CLK_MAX.
+ * 3) IPU HSP clock is independent of AHB clock. Even it can go up to
+ * 177MHz for higher voltage, this function fixes the max to 133MHz.
+ * 4) This function should not have allowed diag_printf() calls since
+ * the serial driver has been stoped. But leave then here to allow
+ * easy debugging by NOT calling the cyg_hal_plf_serial_stop().
+ *
+ * @param ref pll input reference clock (24MHz)
+ * @param freq core clock in Hz
+ * @param clk_type clock type, e.g CPU_CLK, DDR_CLK, etc.
+ * @return 0 if successful; non-zero otherwise
+ */
+int clk_config(u32 ref, u32 freq, u32 clk_type)
+{
+ freq *= SZ_DEC_1M;
+
+ switch (clk_type) {
+ case CPU_CLK:
+ if (config_core_clk(ref, freq))
+ return -1;
+ break;
+ case PERIPH_CLK:
+ if (config_periph_clk(ref, freq))
+ return -1;
+ break;
+ case DDR_CLK:
+ if (config_ddr_clk(freq))
+ return -1;
+ break;
+ default:
+ printf("Unsupported or invalid clock type! :(\n");
+ }
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ printf("CPU: Freescale i.MX50 family %d.%dV at %d MHz\n",
+ (get_board_rev() & 0xFF) >> 4,
+ (get_board_rev() & 0xF),
+ __get_mcu_main_clk() / 1000000);
+#ifndef CONFIG_CMD_CLOCK
+ mxc_dump_clocks();
+#endif
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MXC_FEC)
+extern int mxc_fec_initialize(bd_t *bis);
+extern void mxc_fec_set_mac_from_env(char *mac_addr);
+#endif
+
+int cpu_eth_init(bd_t *bis)
+{
+ int rc = -ENODEV;
+#if defined(CONFIG_MXC_FEC)
+ char *env = NULL;
+
+ rc = mxc_fec_initialize(bis);
+
+ env = getenv("fec_addr");
+ if (env)
+ mxc_fec_set_mac_from_env(env);
+#endif
+ return rc;
+}
+
+#if defined(CONFIG_ARCH_CPU_INIT)
+int arch_cpu_init(void)
+{
+ icache_enable();
+ dcache_enable();
+
+#ifdef CONFIG_L2_OFF
+ l2_cache_disable();
+#else
+ l2_cache_enable();
+#endif
+ return 0;
+}
+#endif
+
diff --git a/cpu/arm_cortexa8/mx50/interrupts.c b/cpu/arm_cortexa8/mx50/interrupts.c
new file mode 100644
index 0000000..4576507
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/interrupts.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * 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/io.h>
+#include <asm/arch/mx50.h>
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int interrupt_init(void)
+{
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ __REG16(WDOG1_BASE_ADDR) = 4;
+}
diff --git a/cpu/arm_cortexa8/mx50/iomux.c b/cpu/arm_cortexa8/mx50/iomux.c
new file mode 100644
index 0000000..66f1bf7
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/iomux.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mx50.h>
+#include <asm/arch/mx50_pins.h>
+#include <asm/arch/iomux.h>
+
+/*!
+ * IOMUX register (base) addresses
+ */
+enum iomux_reg_addr {
+ IOMUXGPR0 = IOMUXC_BASE_ADDR,
+ IOMUXGPR1 = IOMUXC_BASE_ADDR + 0x004,
+ IOMUXGPR2 = IOMUXC_BASE_ADDR + 0x008,
+ IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR,
+ IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + MUX_I_END,
+ IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + PAD_I_START,
+ IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR + INPUT_CTL_START,
+};
+
+static inline u32 _get_mux_reg(iomux_pin_name_t pin)
+{
+ u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
+
+ mux_reg += IOMUXSW_MUX_CTL;
+
+ return mux_reg;
+}
+
+static inline u32 _get_pad_reg(iomux_pin_name_t pin)
+{
+ u32 pad_reg = PIN_TO_IOMUX_PAD(pin);
+
+ pad_reg += IOMUXSW_PAD_CTL;
+
+ return pad_reg;
+}
+
+static inline u32 _get_mux_end(void)
+{
+ return IOMUXSW_MUX_END;
+}
+
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ * FIXED ME: for backward compatible. Will be static function!
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param cfg an output function as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+ u32 mux_reg = _get_mux_reg(pin);
+
+ if ((mux_reg > _get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL))
+ return -1;
+ if (cfg == IOMUX_CONFIG_GPIO)
+ writel(PIN_TO_ALT_GPIO(pin), mux_reg);
+ else
+ writel(cfg, mux_reg);
+
+ return 0;
+}
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+ int ret = iomux_config_mux(pin, cfg);
+
+ return ret;
+}
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+}
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
+{
+ u32 pad_reg = _get_pad_reg(pin);
+
+ writel(config, pad_reg);
+}
+
+unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin)
+{
+ u32 pad_reg = _get_pad_reg(pin);
+
+ return readl(pad_reg);
+}
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b
+ * #iomux_input_select_t
+ * @param config the binary value of elements defined in \b
+ * #iomux_input_config_t
+ */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
+{
+ u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
+
+ writel(config, reg);
+}
diff --git a/cpu/arm_cortexa8/mx50/serial.c b/cpu/arm_cortexa8/mx50/serial.c
new file mode 100644
index 0000000..a0cef25
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/serial.c
@@ -0,0 +1,226 @@
+/*
+ * (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+
+#if defined CONFIG_MX50_UART
+
+#include <asm/arch/mx50.h>
+
+#ifdef CONFIG_MX50_UART1
+#define UART_PHYS UART1_BASE_ADDR
+#elif defined(CONFIG_MX50_UART2)
+#define UART_PHYS UART2_BASE_ADDR
+#elif defined(CONFIG_MX50_UART3)
+#define UART_PHYS UART3_BASE_ADDR
+#else
+#error "define CFG_MX50_UARTx to use the mx50 UART driver"
+#endif
+
+/* Register definitions */
+#define URXD 0x0 /* Receiver Register */
+#define UTXD 0x40 /* Transmitter Register */
+#define UCR1 0x80 /* Control Register 1 */
+#define UCR2 0x84 /* Control Register 2 */
+#define UCR3 0x88 /* Control Register 3 */
+#define UCR4 0x8c /* Control Register 4 */
+#define UFCR 0x90 /* FIFO Control Register */
+#define USR1 0x94 /* Status Register 1 */
+#define USR2 0x98 /* Status Register 2 */
+#define UESC 0x9c /* Escape Character Register */
+#define UTIM 0xa0 /* Escape Timer Register */
+#define UBIR 0xa4 /* BRM Incremental Register */
+#define UBMR 0xa8 /* BRM Modulator Register */
+#define UBRC 0xac /* Baud Rate Count Register */
+#define UTS 0xb4 /* UART Test Register (mx31) */
+
+/* UART Control Register Bit Fields.*/
+#define URXD_CHARRDY (1<<15)
+#define URXD_ERR (1<<14)
+#define URXD_OVRRUN (1<<13)
+#define URXD_FRMERR (1<<12)
+#define URXD_BRK (1<<11)
+#define URXD_PRERR (1<<10)
+#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
+#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
+#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
+#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
+#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
+#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
+#define UCR1_IREN (1<<7) /* Infrared interface enable */
+#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
+#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
+#define UCR1_SNDBRK (1<<4) /* Send break */
+#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
+#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
+#define UCR1_DOZE (1<<1) /* Doze */
+#define UCR1_UARTEN (1<<0) /* UART enabled */
+#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
+#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
+#define UCR2_CTSC (1<<13) /* CTS pin control */
+#define UCR2_CTS (1<<12) /* Clear to send */
+#define UCR2_ESCEN (1<<11) /* Escape enable */
+#define UCR2_PREN (1<<8) /* Parity enable */
+#define UCR2_PROE (1<<7) /* Parity odd/even */
+#define UCR2_STPB (1<<6) /* Stop */
+#define UCR2_WS (1<<5) /* Word size */
+#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
+#define UCR2_TXEN (1<<2) /* Transmitter enabled */
+#define UCR2_RXEN (1<<1) /* Receiver enabled */
+#define UCR2_SRST (1<<0) /* SW reset */
+#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
+#define UCR3_PARERREN (1<<12) /* Parity enable */
+#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
+#define UCR3_DSR (1<<10) /* Data set ready */
+#define UCR3_DCD (1<<9) /* Data carrier detect */
+#define UCR3_RI (1<<8) /* Ring indicator */
+#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
+#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
+#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
+#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
+#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
+#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
+#define UCR3_BPEN (1<<0) /* Preset registers enable */
+#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
+#define UCR4_INVR (1<<9) /* Inverted infrared reception */
+#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
+#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
+#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
+#define UCR4_IRSC (1<<5) /* IR special case */
+#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
+#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
+#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
+#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
+#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
+#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
+#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
+#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
+#define USR1_RTSS (1<<14) /* RTS pin status */
+#define USR1_TRDY (1<<13)/* Transmitter ready interrupt/dma flag */
+#define USR1_RTSD (1<<12) /* RTS delta */
+#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
+#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
+#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
+#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
+#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
+#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
+#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
+#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
+#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
+#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
+#define USR2_IDLE (1<<12) /* Idle condition */
+#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
+#define USR2_WAKE (1<<7) /* Wake */
+#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
+#define USR2_TXDC (1<<3) /* Transmitter complete */
+#define USR2_BRCD (1<<2) /* Break condition */
+#define USR2_ORE (1<<1) /* Overrun error */
+#define USR2_RDR (1<<0) /* Recv data ready */
+#define UTS_FRCPERR (1<<13) /* Force parity error */
+#define UTS_LOOP (1<<12) /* Loop tx and rx */
+#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
+#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
+#define UTS_TXFULL (1<<4) /* TxFIFO full */
+#define UTS_RXFULL (1<<3) /* RxFIFO full */
+#define UTS_SOFTRST (1<<0) /* Software reset */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void serial_setbrg(void)
+{
+ u32 clk = mxc_get_clock(MXC_UART_CLK);
+
+ if (!gd->baudrate)
+ gd->baudrate = CONFIG_BAUDRATE;
+ __REG(UART_PHYS + UFCR) = 0x4 << 7; /* divide input clock by 2 */
+ __REG(UART_PHYS + UBIR) = 0xf;
+ __REG(UART_PHYS + UBMR) = clk / (2 * gd->baudrate);
+}
+
+int serial_getc(void)
+{
+ while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
+ ;
+ return __REG(UART_PHYS + URXD);
+}
+
+void serial_putc(const char c)
+{
+ __REG(UART_PHYS + UTXD) = c;
+
+ /* wait for transmitter to be ready */
+ while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
+ ;
+
+ /* If \n, also do \r */
+ if (c == '\n')
+ serial_putc('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc(void)
+{
+ /* If receive fifo is empty, return false */
+ if (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
+ return 0;
+ return 1;
+}
+
+void serial_puts(const char *s)
+{
+ while (*s)
+ serial_putc(*s++);
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init(void)
+{
+ __REG(UART_PHYS + UCR1) = 0x0;
+ __REG(UART_PHYS + UCR2) = 0x0;
+
+ while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST))
+ ;
+
+ __REG(UART_PHYS + UCR3) = 0x0704;
+ __REG(UART_PHYS + UCR4) = 0x8000;
+ __REG(UART_PHYS + UESC) = 0x002b;
+ __REG(UART_PHYS + UTIM) = 0x0;
+
+ __REG(UART_PHYS + UTS) = 0x0;
+
+ serial_setbrg();
+
+ __REG(UART_PHYS + UCR2) =
+ UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST;
+
+ __REG(UART_PHYS + UCR1) = UCR1_UARTEN;
+
+ return 0;
+}
+
+#endif /* CONFIG_MX50_UART */
diff --git a/cpu/arm_cortexa8/mx50/timer.c b/cpu/arm_cortexa8/mx50/timer.c
new file mode 100644
index 0000000..00150ab
--- /dev/null
+++ b/cpu/arm_cortexa8/mx50/timer.c
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * 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/arch/mx50.h>
+
+/* General purpose timers registers */
+#define GPTCR __REG(GPT1_BASE_ADDR) /* Control register */
+#define GPTPR __REG(GPT1_BASE_ADDR + 0x4) /* Prescaler register */
+#define GPTSR __REG(GPT1_BASE_ADDR + 0x8) /* Status register */
+#define GPTCNT __REG(GPT1_BASE_ADDR + 0x24) /* Counter register */
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1<<15) /* Software reset */
+#define GPTCR_FRR (1<<9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (0x100<<6) /* Clock source */
+#define GPTCR_CLKSOURCE_IPG (0x001<<6) /* Clock source */
+#define GPTCR_TEN (1) /* Timer enable */
+#define GPTPR_VAL (50)
+
+static inline void setup_gpt(void)
+{
+ int i;
+ static int init_done;
+
+ if (init_done)
+ return;
+
+ init_done = 1;
+
+ /* setup GP Timer 1 */
+ GPTCR = GPTCR_SWR;
+ for (i = 0; i < 100; i++)
+ GPTCR = 0; /* We have no udelay by now */
+ GPTPR = GPTPR_VAL; /* 50Mhz / 50 */
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR |= GPTCR_CLKSOURCE_IPG | GPTCR_TEN;
+}
+
+int timer_init(void)
+{
+ setup_gpt();
+
+ return 0;
+}
+
+void reset_timer_masked(void)
+{
+ GPTCR = 0;
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR = GPTCR_CLKSOURCE_IPG | GPTCR_TEN;
+}
+
+inline ulong get_timer_masked(void)
+{
+ ulong val = GPTCNT;
+
+ return val;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ ulong tmp;
+
+ tmp = get_timer_masked();
+
+ if (tmp <= (base * 1000)) {
+ /* Overflow */
+ tmp += (0xffffffff - base);
+ }
+
+ return (tmp / 1000) - base;
+}
+
+void set_timer(ulong t)
+{
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+/* GPTCNT is now supposed to tick 1 by 1 us. */
+void udelay(unsigned long usec)
+{
+ ulong tmp;
+
+ setup_gpt();
+
+ tmp = get_timer_masked(); /* get current timestamp */
+
+ /* if setting this forward will roll time stamp */
+ if ((usec + tmp + 1) < tmp) {
+ /* reset "advancing" timestamp to 0, set lastinc value */
+ reset_timer_masked();
+ } else {
+ /* else, set advancing stamp wake up time */
+ tmp += usec;
+ }
+
+ while (get_timer_masked() < tmp) /* loop till event */
+ /*NOP*/;
+}