summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm_cortexa8/mx6/Makefile48
-rw-r--r--cpu/arm_cortexa8/mx6/crm_regs.h530
-rw-r--r--cpu/arm_cortexa8/mx6/generic.c788
-rw-r--r--cpu/arm_cortexa8/mx6/interrupts.c39
-rw-r--r--cpu/arm_cortexa8/mx6/iomux-v3.c76
-rw-r--r--cpu/arm_cortexa8/mx6/timer.c181
6 files changed, 1662 insertions, 0 deletions
diff --git a/cpu/arm_cortexa8/mx6/Makefile b/cpu/arm_cortexa8/mx6/Makefile
new file mode 100644
index 0000000..2a4337a
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2011 Freescale Semiconductor, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(SOC).a
+
+COBJS = interrupts.o generic.o iomux-v3.o timer.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/mx6/crm_regs.h b/cpu/arm_cortexa8/mx6/crm_regs.h
new file mode 100644
index 0000000..71e249b
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/crm_regs.h
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2010-2011 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_MX6_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX6_CRM_REGS_H__
+
+#define MXC_CCM_BASE CCM_BASE_ADDR
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
+#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)
+#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)
+#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44)
+#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)
+#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 + 0x80)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x88)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_RBC_EN (1 << 27)
+#define MXC_CCM_CCR_REG_BYPASS_CNT_MASK (0x3F << 21)
+#define MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET (21)
+#define MXC_CCM_CCR_WB_COUNT_MASK (0x7)
+#define MXC_CCM_CCR_WB_COUNT_OFFSET (1 << 16)
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_MMDC_CH1_HS_MASK (1 << 16)
+#define MXC_CCM_CCDR_MMDC_CH0_HS_MASK (1 << 17)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSC_READY (1 << 5)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_PDF_540M_AUTO_DIS (1 << 15)
+#define MXC_CCM_CCSR_PDF_720M_AUTO_DIS (1 << 14)
+#define MXC_CCM_CCSR_PDF_454M_AUTO_DIS (1 << 13)
+#define MXC_CCM_CCSR_PDF_508M_AUTO_DIS (1 << 12)
+#define MXC_CCM_CCSR_PDF_594M_AUTO_DIS (1 << 11)
+#define MXC_CCM_CCSR_PDF_352M_AUTO_DIS (1 << 10)
+#define MXC_CCM_CCSR_PDF_400M_AUTO_DIS (1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL (1 << 8)
+#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_PERIPH_CLK2_PODF_MASK (0x7 << 27)
+#define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET (27)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_SEL (1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (1 << 25)
+#define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_AXI_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_AXI_ALT_SEL (1 << 7)
+#define MXC_CCM_CBCDR_AXI_SEL (1 << 6)
+#define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET (3)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK (0x7 << 0)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET (0)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK (0x7 << 29)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET (29)
+#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK (0x7 << 26)
+#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET (26)
+#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK (0x7 << 23)
+#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET (23)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK (0x3 << 21)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET (21)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK2_SEL (1 << 20)
+#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK (0x3 << 18)
+#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET (12)
+#define MXC_CCM_CBCMR_VDOAXI_CLK_SEL (1 << 11)
+#define MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL (1 << 10)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL (1 << 1)
+#define MXC_CCM_CBCMR_GPU2D_AXI_CLK_SEL (1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK (0x3 << 29)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET (29)
+#define MXC_CCM_CSCMR1_ACLK_EMI_MASK (0x3 << 27)
+#define MXC_CCM_CSCMR1_ACLK_EMI_OFFSET (27)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK (0x7 << 23)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET (23)
+#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK (0x7 << 20)
+#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET (20)
+#define MXC_CCM_CSCMR1_USDHC4_CLK_SEL (1 << 19)
+#define MXC_CCM_CSCMR1_USDHC3_CLK_SEL (1 << 18)
+#define MXC_CCM_CSCMR1_USDHC2_CLK_SEL (1 << 17)
+#define MXC_CCM_CSCMR1_USDHC1_CLK_SEL (1 << 16)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CSCMR1_PERCLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK (0x3 << 19)
+#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET (19)
+#define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV (1 << 11)
+#define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV (1 << 10)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK (0x3F << 2)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET (2)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET (25)
+#define MXC_CCM_CSCDR1_USDHC4_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET (22)
+#define MXC_CCM_CSCDR1_USDHC3_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_USDHC2_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET (16)
+#define MXC_CCM_CSCDR1_USDHC1_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CS1CDR */
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK (0x3F << 25)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET (25)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK (0x3 << 9)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET (9)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CS2CDR */
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK (0x3F << 21)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET (21)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK (0x7 << 18)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET (18)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK (0x7 << 12)
+#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_HSI_TX_PODF_MASK (0x7 << 29)
+#define MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET (29)
+#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL (1 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 12)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (12)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x7 << 9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET (7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK (0x7 << 15)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET (15)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET (12)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK (0x7)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET (0)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_MASK (0x7 << 15)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_OFFSET (15)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_OFFSET (12)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_MASK (0x7)
+#define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_OFFSET (0)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET (16)
+#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK (0x3 << 9)
+#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET (9)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_MMDC_CH0_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_PODF_BUSY (1)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_MASK_L2CC_IDLE (1 << 27)
+#define MXC_CCM_CLPCR_MASK_SCU_IDLE (1 << 26)
+#define MXC_CCM_CLPCR_MASK_CORE3_WFI (1 << 25)
+#define MXC_CCM_CLPCR_MASK_CORE2_WFI (1 << 24)
+#define MXC_CCM_CLPCR_MASK_CORE1_WFI (1 << 23)
+#define MXC_CCM_CLPCR_MASK_CORE0_WFI (1 << 22)
+#define MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS (1 << 21)
+#define MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS (1 << 19)
+#define MXC_CCM_CLPCR_WB_CORE_AT_LPM (1 << 17)
+#define MXC_CCM_CLPCR_WB_PER_AT_LPM (1 << 17)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_VSTBY (1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY (1 << 2)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (1 << 26)
+#define MXC_CCM_CISR_MMDC_CH0_PODF_LOADED (1 << 23)
+#define MXC_CCM_CISR_PERIPH_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CISR_MMDC_CH1_PODF_LOADED (1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (1 << 20)
+#define MXC_CCM_CISR_PERIPH2_CLK_SEL_LOADED (1 << 19)
+#define MXC_CCM_CISR_AXI_PODF_LOADED (1 << 17)
+#define MXC_CCM_CISR_COSC_READY (1 << 6)
+#define MXC_CCM_CISR_LRF_PLL (1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (1 << 26)
+#define MXC_CCM_CIMR_MASK_MMDC_CH0_PODF_LOADED (1 << 23)
+#define MXC_CCM_CIMR_MASK_PERIPH_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CIMR_MASK_MMDC_CH1_PODF_LOADED (1 << 21)
+#define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED (1 << 20)
+#define MXC_CCM_CIMR_MASK_PERIPH2_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CIMR_MASK_AXI_PODF_LOADED (1 << 17)
+#define MXC_CCM_CIMR_MASK_COSC_READY (1 << 6)
+#define MXC_CCM_CIMR_MASK_LRF_PLL (1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (1 << 4)
+#define MXC_CCM_CGPR_MMDC_EXT_CLK_DIS (1 << 2)
+#define MXC_CCM_CGPR_PMIC_DELAY_SCALER (1)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGR_CG_MASK 3
+
+#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 3
+
+#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_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_CG4_OFFSET 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
+
+#endif /* __ARCH_ARM_MACH_MX6_CRM_REGS_H__ */
diff --git a/cpu/arm_cortexa8/mx6/generic.c b/cpu/arm_cortexa8/mx6/generic.c
new file mode 100644
index 0000000..c2540e1
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/generic.c
@@ -0,0 +1,788 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/mx6.h>
+#include <asm/arch/regs-anadig.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 {
+ CPU_PLL1, /* System PLL */
+ BUS_PLL2, /* System Bus PLL*/
+ USBOTG_PLL3, /* OTG USB PLL */
+ AUD_PLL4, /* Audio PLL */
+ VID_PLL5, /* Video PLL */
+ MLB_PLL6, /* MLB PLL */
+ USBHOST_PLL7, /* Host USB PLL */
+ ENET_PLL8, /* ENET PLL */
+};
+
+#define SZ_DEC_1M 1000000
+
+/* Out-of-reset PFDs and clock source definitions */
+#define PLL2_PFD0_FREQ 352000000
+#define PLL2_PFD1_FREQ 594000000
+#define PLL2_PFD2_FREQ 400000000
+#define PLL2_PFD2_DIV_FREQ 200000000
+#define PLL3_PFD0_FREQ 720000000
+#define PLL3_PFD1_FREQ 540000000
+#define PLL3_PFD2_FREQ 508200000
+#define PLL3_PFD3_FREQ 454700000
+#define PLL3_80M 80000000
+#define PLL3_60M 60000000
+
+#define AHB_CLK_ROOT 132000000
+#define IPG_CLK_ROOT 66000000
+#define ENET_FREQ_0 25000000
+#define ENET_FREQ_1 50000000
+#define ENET_FREQ_2 100000000
+#define ENET_FREQ_3 125000000
+
+#ifdef CONFIG_CMD_CLOCK
+#define PLL1_FREQ_MAX 1300000000
+#define PLL1_FREQ_MIN 650000000
+#define PLL2_FREQ_MAX 528000000
+#define PLL2_FREQ_MIN 480000000
+#define MAX_DDR_CLK PLL2_FREQ_MAX
+#define AHB_CLK_MAX 132000000
+#define IPG_CLK_MAX (AHB_CLK_MAX >> 1)
+#define NFC_CLK_MAX PLL2_FREQ_MAX
+#endif
+
+static u32 __decode_pll(enum pll_clocks pll, u32 infreq)
+{
+ u32 div;
+
+ switch (pll) {
+ case CPU_PLL1:
+ div = REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS) &
+ BM_ANADIG_PLL_SYS_DIV_SELECT;
+ return infreq * (div >> 1);
+ case BUS_PLL2:
+ div = REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528) &
+ BM_ANADIG_PLL_528_DIV_SELECT;
+ return infreq * (20 + (div << 1));
+ case USBOTG_PLL3:
+ div = REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_USB2_PLL_480_CTRL) &
+ BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
+ return infreq * (20 + (div << 1));
+ case ENET_PLL8:
+ div = REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET) &
+ BM_ANADIG_PLL_ENET_DIV_SELECT;
+ switch (div) {
+ default:
+ case 0:
+ return ENET_FREQ_0;
+ case 1:
+ return ENET_FREQ_1;
+ case 2:
+ return ENET_FREQ_2;
+ case 3:
+ return ENET_FREQ_3;
+ }
+ case AUD_PLL4:
+ case VID_PLL5:
+ case MLB_PLL6:
+ case USBHOST_PLL7:
+ default:
+ return 0;
+ }
+}
+
+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(CPU_PLL1, CONFIG_MX6_HCLK_FREQ);
+ return freq / (reg + 1);
+}
+
+static u32 __get_periph_clk(void)
+{
+ u32 reg;
+ reg = __REG(MXC_CCM_CBCDR);
+ if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
+ reg = __REG(MXC_CCM_CBCMR);
+ switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK) >>
+ MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET) {
+ case 0:
+ return __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ);
+ case 1:
+ case 2:
+ return CONFIG_MX6_HCLK_FREQ;
+ default:
+ return 0;
+ }
+ } else {
+ reg = __REG(MXC_CCM_CBCMR);
+ switch ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) >>
+ MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET) {
+ default:
+ case 0:
+ return __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ);
+ case 1:
+ return PLL2_PFD2_FREQ;
+ case 2:
+ return PLL2_PFD0_FREQ;
+ case 3:
+ return PLL2_PFD2_DIV_FREQ;
+ }
+ }
+}
+
+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 podf;
+ u32 clk_root = __get_ipg_clk();
+
+ podf = __REG(MXC_CCM_CSCMR1) & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
+ return clk_root / (podf + 1);
+}
+
+static u32 __get_uart_clk(void)
+{
+ u32 freq = PLL3_80M, reg, podf;
+
+ reg = __REG(MXC_CCM_CSCDR1);
+ podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
+ freq /= (podf + 1);
+
+ return freq;
+}
+
+
+static u32 __get_cspi_clk(void)
+{
+ u32 freq = PLL3_60M, reg, podf;
+
+ reg = __REG(MXC_CCM_CSCDR2);
+ podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
+ freq /= (podf + 1);
+
+ return freq;
+}
+
+static u32 __get_axi_clk(void)
+{
+ u32 clkroot;
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 podf = (cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_PODF_OFFSET;
+
+ if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
+ if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
+ clkroot = PLL2_PFD2_FREQ;
+ else
+ clkroot = PLL3_PFD1_FREQ;;
+ } else
+ clkroot = __get_periph_clk();
+
+ return clkroot / (podf + 1);
+}
+
+static u32 __get_ahb_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 podf = (cbcdr & MXC_CCM_CBCDR_AHB_PODF_MASK) \
+ >> MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+
+ return __get_periph_clk() / (podf + 1);
+}
+
+static u32 __get_emi_slow_clk(void)
+{
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 emi_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
+ u32 podf = (cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
+
+ switch (emi_clk_sel) {
+ default:
+ case 0:
+ return __get_axi_clk() / (podf + 1);
+ case 1:
+ return __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ) /
+ (podf + 1);
+ case 2:
+ return PLL2_PFD2_FREQ / (podf + 1);
+ case 3:
+ return PLL2_PFD0_FREQ / (podf + 1);
+ }
+}
+
+static u32 __get_nfc_clk(void)
+{
+ u32 clkroot;
+ u32 cs2cdr = __REG(MXC_CCM_CS2CDR);
+ u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) \
+ >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+ u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) \
+ >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+
+ switch ((cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
+ MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET) {
+ default:
+ case 0:
+ clkroot = PLL2_PFD0_FREQ;
+ break;
+ case 1:
+ clkroot = __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ);
+ break;
+ case 2:
+ clkroot = __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ);
+ break;
+ case 3:
+ clkroot = PLL2_PFD2_FREQ;
+ break;
+ }
+
+ return clkroot / pred / podf;
+}
+
+static u32 __get_ddr_clk(void)
+{
+ u32 cbcdr = __REG(MXC_CCM_CBCDR);
+ u32 podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
+ MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
+
+ return __get_periph_clk() / (podf + 1);
+}
+
+static u32 __get_usdhc1_clk(void)
+{
+ u32 clkroot;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
+
+ if (cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL)
+ clkroot = PLL2_PFD0_FREQ;
+ else
+ clkroot = PLL2_PFD2_FREQ;
+
+ return clkroot / (podf + 1);
+}
+
+static u32 __get_usdhc2_clk(void)
+{
+ u32 clkroot;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
+
+ if (cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL)
+ clkroot = PLL2_PFD0_FREQ;
+ else
+ clkroot = PLL2_PFD2_FREQ;
+
+ return clkroot / (podf + 1);
+}
+
+static u32 __get_usdhc3_clk(void)
+{
+ u32 clkroot;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
+
+ if (cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL)
+ clkroot = PLL2_PFD0_FREQ;
+ else
+ clkroot = PLL2_PFD2_FREQ;
+
+ return clkroot / (podf + 1);
+}
+
+static u32 __get_usdhc4_clk(void)
+{
+ u32 clkroot;
+ u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
+ u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
+ u32 podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
+
+ if (cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL)
+ clkroot = PLL2_PFD0_FREQ;
+ else
+ clkroot = PLL2_PFD2_FREQ;
+
+ return clkroot / (podf + 1);
+}
+
+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();
+ case MXC_CSPI_CLK:
+ return __get_cspi_clk();
+ case MXC_AXI_CLK:
+ return __get_axi_clk();
+ case MXC_EMI_SLOW_CLK:
+ return __get_emi_slow_clk();
+ case MXC_DDR_CLK:
+ return __get_ddr_clk();
+ case MXC_ESDHC_CLK:
+ return __get_usdhc1_clk();
+ case MXC_ESDHC2_CLK:
+ return __get_usdhc2_clk();
+ case MXC_ESDHC3_CLK:
+ return __get_usdhc3_clk();
+ case MXC_ESDHC4_CLK:
+ return __get_usdhc4_clk();
+ case MXC_SATA_CLK:
+ return __get_ahb_clk();
+ case MXC_NFC_CLK:
+ return __get_nfc_clk();
+ default:
+ break;
+ }
+ return -1;
+}
+
+void mxc_dump_clocks(void)
+{
+ u32 freq;
+ freq = __decode_pll(CPU_PLL1, CONFIG_MX6_HCLK_FREQ);
+ printf("mx6q pll1: %dMHz\n", freq / SZ_DEC_1M);
+ freq = __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ);
+ printf("mx6q pll2: %dMHz\n", freq / SZ_DEC_1M);
+ freq = __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ);
+ printf("mx6q pll3: %dMHz\n", freq / SZ_DEC_1M);
+ freq = __decode_pll(ENET_PLL8, CONFIG_MX6_HCLK_FREQ);
+ printf("mx6q pll8: %dMHz\n", freq / SZ_DEC_1M);
+ 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));
+ printf("cspi clock : %dHz\n", mxc_get_clock(MXC_CSPI_CLK));
+ printf("ahb clock : %dHz\n", mxc_get_clock(MXC_AHB_CLK));
+ printf("axi clock : %dHz\n", mxc_get_clock(MXC_AXI_CLK));
+ printf("emi_slow clock: %dHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK));
+ printf("ddr clock : %dHz\n", mxc_get_clock(MXC_DDR_CLK));
+ printf("usdhc1 clock : %dHz\n", mxc_get_clock(MXC_ESDHC_CLK));
+ printf("usdhc2 clock : %dHz\n", mxc_get_clock(MXC_ESDHC2_CLK));
+ printf("usdhc3 clock : %dHz\n", mxc_get_clock(MXC_ESDHC3_CLK));
+ printf("usdhc4 clock : %dHz\n", mxc_get_clock(MXC_ESDHC4_CLK));
+ printf("nfc clock : %dHz\n", mxc_get_clock(MXC_NFC_CLK));
+}
+
+#ifdef CONFIG_CMD_CLOCK
+
+/*!
+ * This is to calculate divider based on reference clock and
+ * targeted clock based on the equation for each PLL.
+ *
+ * @param pll pll number
+ * @param ref reference clock freq in Hz
+ * @param target targeted clock in Hz
+ *
+ * @return divider if successful; -1 otherwise.
+ */
+static int calc_pll_divider(enum pll_clocks pll, u32 ref, u32 target)
+{
+ int i, div;
+
+ switch (pll) {
+ case CPU_PLL1:
+ if (target < PLL1_FREQ_MIN || target > PLL1_FREQ_MAX) {
+ printf("PLL1 frequency should be"
+ "within [%d - %d] MHz\n", PLL1_FREQ_MIN / SZ_DEC_1M,
+ PLL1_FREQ_MAX / SZ_DEC_1M);
+ return -1;
+ }
+ for (i = 54, div = i; i < 109; i++) {
+ if ((ref * (i >> 1)) > target)
+ break;
+ div = i;
+ }
+ break;
+ case BUS_PLL2:
+ if (target < PLL2_FREQ_MIN || target > PLL2_FREQ_MAX) {
+ printf("PLL2 frequency should be"
+ "within [%d - %d] MHz\n", PLL2_FREQ_MIN / SZ_DEC_1M,
+ PLL2_FREQ_MAX / SZ_DEC_1M);
+ return -1;
+ }
+ for (i = 0, div = i; i < 2; i++) {
+ if (ref * (20 + (i << 1)) > target)
+ break;
+ div = i;
+ }
+ break;
+ default:
+ printf("Changing this PLL not supported\n");
+ return -1;
+ break;
+ }
+
+ return div;
+}
+
+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 NFC_CLK:
+ printf("NFC Clock: %dHz\n",
+ mxc_get_clock(MXC_NFC_CLK));
+ 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;
+}
+
+
+
+static int config_pll_clk(enum pll_clocks pll, u32 divider)
+{
+ u32 ccsr = readl(CCM_BASE_ADDR + CLKCTL_CCSR);
+
+ switch (pll) {
+ case CPU_PLL1:
+ /* Switch ARM to PLL2 clock */
+ writel(ccsr | 0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
+
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS,
+ BM_ANADIG_PLL_SYS_DIV_SELECT);
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS,
+ BF_ANADIG_PLL_SYS_DIV_SELECT(divider));
+ /* Enable CPU PLL1 */
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS,
+ BM_ANADIG_PLL_SYS_ENABLE);
+ /* Wait for PLL lock */
+ while (REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS) &
+ BM_ANADIG_PLL_SYS_LOCK)
+ udelay(10);
+ /* Clear bypass bit */
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_SYS,
+ BM_ANADIG_PLL_SYS_BYPASS);
+
+ /* Switch back */
+ writel(ccsr & ~0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
+ break;
+ case BUS_PLL2:
+ /* Switch to pll2 bypass clock */
+ writel(ccsr | 0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
+
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528,
+ BM_ANADIG_PLL_528_DIV_SELECT);
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528,
+ divider);
+ /* Enable BUS PLL2 */
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528,
+ BM_ANADIG_PLL_528_ENABLE);
+ /* Wait for PLL lock */
+ while (REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528) &
+ BM_ANADIG_PLL_528_LOCK)
+ udelay(10);
+ /* Clear bypass bit */
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_528,
+ BM_ANADIG_PLL_528_BYPASS);
+
+ /* Switch back */
+ writel(ccsr & ~0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int config_core_clk(u32 ref, u32 freq)
+{
+ int div = calc_pll_divider(CPU_PLL1, ref, freq);
+ if (div < 0) {
+ printf("Can't find pll parameters\n");
+ return div;
+ }
+
+ return config_pll_clk(CPU_PLL1, div);
+}
+
+static int config_nfc_clk(u32 nfc_clk)
+{
+ /* TBD */
+ return -1;
+}
+static int config_periph_clk(u32 ref, u32 freq)
+{
+ u32 cbcdr = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
+ u32 cbcmr = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
+ u32 pll2_freq = __decode_pll(BUS_PLL2, CONFIG_MX6_HCLK_FREQ);
+ u32 pll3_freq = __decode_pll(USBOTG_PLL3, CONFIG_MX6_HCLK_FREQ);
+
+ if (freq >= pll2_freq) {
+ /* PLL2 */
+ writel(cbcmr & ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,
+ CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(cbcdr & ~MXC_CCM_CBCDR_PERIPH_CLK_SEL,
+ CCM_BASE_ADDR + CLKCTL_CBCDR);
+ } else if (freq < pll2_freq && freq >= pll3_freq) {
+ /* PLL3 */
+ writel(cbcmr & ~MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK,
+ CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(cbcdr | MXC_CCM_CBCDR_PERIPH_CLK_SEL,
+ CCM_BASE_ADDR + CLKCTL_CBCDR);
+ } else if (freq < pll3_freq && freq >= PLL2_PFD2_FREQ) {
+ /* 400M PLL2 PFD */
+ cbcmr = (cbcmr & ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) |
+ (1 << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
+ writel(cbcmr, CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(cbcdr & ~MXC_CCM_CBCDR_PERIPH_CLK_SEL,
+ CCM_BASE_ADDR + CLKCTL_CBCDR);
+ } else if (freq < PLL2_PFD2_FREQ && freq >= PLL2_PFD0_FREQ) {
+ /* 352M PLL2 PFD */
+ cbcmr = (cbcmr & ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) |
+ (2 << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
+ writel(cbcmr, CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(cbcdr & ~MXC_CCM_CBCDR_PERIPH_CLK_SEL,
+ CCM_BASE_ADDR + CLKCTL_CBCDR);
+ } else if (freq == PLL2_PFD2_DIV_FREQ) {
+ /* 200M PLL2 PFD */
+ cbcmr = (cbcmr & ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) |
+ (3 << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
+ writel(cbcmr, CCM_BASE_ADDR + CLKCTL_CBCMR);
+ writel(cbcdr & ~MXC_CCM_CBCDR_PERIPH_CLK_SEL,
+ CCM_BASE_ADDR + CLKCTL_CBCDR);
+ } else {
+ printf("Frequency requested not within range [%d-%d] MHz\n",
+ PLL2_PFD2_DIV_FREQ / SZ_DEC_1M, pll2_freq / SZ_DEC_1M);
+ return -1;
+ }
+ puts("\n");
+
+ return 0;
+}
+
+static int config_ddr_clk(u32 ddr_clk)
+{
+ u32 clk_src = __get_periph_clk();
+ u32 i, podf;
+ u32 cbcdr = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
+
+ if (ddr_clk > MAX_DDR_CLK) {
+ printf("DDR clock should be less than"
+ "%d MHz, assuming max value\n",
+ (MAX_DDR_CLK / SZ_DEC_1M));
+ ddr_clk = MAX_DDR_CLK;
+ }
+
+ for (i = 1; i < 9; i++)
+ if ((clk_src / i) <= ddr_clk)
+ break;
+
+ podf = i - 1;
+
+ cbcdr &= ~MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK;
+ cbcdr |= podf << MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
+ 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 (arm_podf=0) unless the core clock is less than PLL_FREQ_MIN.
+ *
+ * @param ref pll input reference clock (24MHz)
+ * @param freq targeted freq 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;
+ case NFC_CLK:
+ if (config_nfc_clk(freq))
+ return -1;
+ break;
+ default:
+ printf("Unsupported or invalid clock type! :(\n");
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ printf("CPU: Freescale i.MX 6 family %d.%dV at %d MHz\n",
+ (get_board_rev() & 0xFF) >> 4,
+ (get_board_rev() & 0xF),
+ __get_mcu_main_clk() / SZ_DEC_1M);
+ mxc_dump_clocks();
+ 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);
+void enet_board_init(void);
+#endif
+
+int cpu_eth_init(bd_t *bis)
+{
+ int rc = -ENODEV;
+#if defined(CONFIG_MXC_FEC)
+ printf("cpu_eth_init\n");
+ rc = mxc_fec_initialize(bis);
+
+ /* Set up ENET PLL for 50 MHz */
+
+ /* Clear power down bit */
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET,
+ BM_ANADIG_PLL_ENET_POWERDOWN);
+ /* Set ENET clock to 50M, Anson need to check */
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET,
+ BF_ANADIG_PLL_ENET_DIV_SELECT(0x11));
+ /* Enable ENET PLL */
+ REG_SET(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET,
+ BM_ANADIG_PLL_ENET_ENABLE);
+ printf("before while\n");
+ /* Wait for PLL lock */
+ while ((REG_RD(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET) &
+ BM_ANADIG_PLL_ENET_LOCK) == 0)
+ udelay(100);
+ /* Clear bypass bit */
+ REG_CLR(ANATOP_BASE_ADDR, HW_ANADIG_PLL_ENET,
+ BM_ANADIG_PLL_ENET_BYPASS);
+
+ printf("before enent_board_init\n");
+
+ /* Board level init */
+ enet_board_init();
+
+#endif
+ return rc;
+}
+
+#if defined(CONFIG_ARCH_CPU_INIT)
+int arch_cpu_init(void)
+{
+ icache_enable();
+ dcache_enable();
+
+#ifndef CONFIG_L2_OFF
+ l2_cache_enable();
+#endif
+ return 0;
+}
+#endif
+
diff --git a/cpu/arm_cortexa8/mx6/interrupts.c b/cpu/arm_cortexa8/mx6/interrupts.c
new file mode 100644
index 0000000..d5e4fc1
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/interrupts.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mx6.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/mx6/iomux-v3.c b/cpu/arm_cortexa8/mx6/iomux-v3.c
new file mode 100644
index 0000000..4f31567
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/iomux-v3.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * Copyright (C) 2004-2011 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mx6.h>
+#include <asm/arch/mx6_pins.h>
+#include <asm/arch/iomux-v3.h>
+
+static void *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
+{
+ u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+ u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+ u32 sel_input_ofs =
+ (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+ u32 sel_input =
+ (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+ u32 pad_ctrl_ofs =
+ (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+ u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+
+ if (mux_ctrl_ofs)
+ __raw_writel(mux_mode, base + mux_ctrl_ofs);
+
+ if (sel_input_ofs)
+ __raw_writel(sel_input, base + sel_input_ofs);
+
+ if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+ __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
+
+ return 0;
+}
+
+int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count)
+{
+ iomux_v3_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxc_iomux_v3_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+ return 0;
+}
+
+void mxc_iomux_v3_init(void *iomux_v3_base)
+{
+ base = iomux_v3_base;
+}
+
diff --git a/cpu/arm_cortexa8/mx6/timer.c b/cpu/arm_cortexa8/mx6/timer.c
new file mode 100644
index 0000000..e4a5a8f
--- /dev/null
+++ b/cpu/arm_cortexa8/mx6/timer.c
@@ -0,0 +1,181 @@
+/*
+ * (C) Copyright 2007
+ * Sascha Hauer, Pengutronix
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/mx6.h>
+#include <div64.h>
+
+#define TIMER_BASE GPT_BASE_ADDR /* General purpose timer 1 */
+
+/* General purpose timers registers */
+#define GPTCR __REG(TIMER_BASE) /* Control register */
+#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
+#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
+#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
+
+/* General purpose timers bitfields */
+#define GPTCR_SWR (1 << 15) /* Software reset */
+#define GPTCR_FRR (1 << 9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
+#define GPTCR_TEN (1) /* Timer enable */
+
+static ulong timestamp;
+static ulong lastinc;
+
+/* "time" is measured in 1 / CONFIG_SYS_HZ seconds,
+ * "tick" is internal timer period */
+#ifdef CONFIG_TIMER_HIGH_PRECISION
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, CONFIG_MX6_CLK32);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ time *= CONFIG_MX6_CLK32;
+ do_div(time, CONFIG_SYS_HZ);
+ return time;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us = us * CONFIG_MX6_CLK32 + 999999;
+ do_div(us, 1000000);
+ return us;
+}
+#else
+/* ~2% error */
+#define TICK_PER_TIME ((CONFIG_MX6_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ)
+#define US_PER_TICK (1000000 / CONFIG_MX6_CLK32)
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ do_div(tick, TICK_PER_TIME);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ return time * TICK_PER_TIME;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us += US_PER_TICK - 1;
+ do_div(us, US_PER_TICK);
+ return us;
+}
+#endif
+
+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 = 0; /* 32KHz */
+ /* Freerun Mode, CLK32 input */
+ GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
+}
+
+int timer_init(void)
+{
+ setup_gpt();
+
+ return 0;
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastinc = GPTCNT; /* capture current incrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+unsigned long long get_ticks(void)
+{
+ ulong now = GPTCNT; /* current tick value */
+
+ if (now >= lastinc) /* normal mode (non roll) */
+ /* move stamp forward with absolut diff ticks */
+ timestamp += (now - lastinc);
+ else /* we have rollover of incrementer */
+ timestamp += (0xFFFFFFFF - lastinc) + now;
+ lastinc = now;
+ return timestamp;
+}
+
+ulong get_timer_masked(void)
+{
+ /*
+ * get_ticks() returns a long long (64 bit), it wraps in
+ * 2^64 / CONFIG_MX31_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+ * 5 * 10^6 days - long enough.
+ */
+ return tick_to_time(get_ticks());
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = time_to_tick(t);
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+/* GPTCNT is now supposed to tick 1 by 1 us. */
+void udelay(unsigned long usec)
+{
+ unsigned long long tmp;
+ ulong tmo;
+
+ setup_gpt();
+
+ tmo = us_to_tick(usec);
+ tmp = get_ticks() + tmo; /* get current timestamp */
+
+ while (get_ticks() < tmp) /* loop till event */
+ /*NOP*/;
+}