summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c4
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c17
-rw-r--r--arch/arm/imx-common/iomux-v3.c15
-rw-r--r--arch/arm/imx-common/timer.c75
-rw-r--r--arch/arm/include/asm/arch-mx6/crm_regs.h12
-rw-r--r--arch/arm/include/asm/arch-mx6/mx6sl_pins.h19
-rw-r--r--arch/arm/include/asm/imx-common/iomux-v3.h5
8 files changed, 137 insertions, 14 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bd774d42a8..22eb2d5854 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -627,6 +627,9 @@ config TARGET_HUMMINGBOARD
bool "Support hummingboard"
select CPU_V7
+config TARGET_KOSAGI_NOVENA
+ bool "Support Kosagi Novena"
+
config TARGET_TQMA6
bool "TQ Systems TQMa6 board"
select CPU_V7
@@ -892,6 +895,7 @@ source "board/imx31_phycore/Kconfig"
source "board/isee/igep0033/Kconfig"
source "board/jornada/Kconfig"
source "board/karo/tx25/Kconfig"
+source "board/kosagi/novena/Kconfig"
source "board/logicpd/imx27lite/Kconfig"
source "board/logicpd/imx31_litekit/Kconfig"
source "board/maxbcm/Kconfig"
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index d200531030..6c9c78c11a 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -312,6 +312,10 @@ static u32 get_ipg_per_clk(void)
u32 reg, perclk_podf;
reg = __raw_readl(&imx_ccm->cscmr1);
+#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
+ if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK)
+ return MXC_HCLK; /* OSC 24Mhz */
+#endif
perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
return get_ipg_clk() / (perclk_podf + 1);
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index dd5aaa286a..affbf7f702 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -240,6 +240,18 @@ static void clear_mmdc_ch_mask(void)
writel(0, &mxc_ccm->ccdr);
}
+#ifdef CONFIG_MX6SL
+static void set_preclk_from_osc(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ u32 reg;
+
+ reg = readl(&mxc_ccm->cscmr1);
+ reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK;
+ writel(reg, &mxc_ccm->cscmr1);
+}
+#endif
+
int arch_cpu_init(void)
{
init_aips();
@@ -255,6 +267,11 @@ int arch_cpu_init(void)
if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
set_ahb_rate(132000000);
+ /* Set perclk to source from OSC 24MHz */
+#if defined(CONFIG_MX6SL)
+ set_preclk_from_osc();
+#endif
+
imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
#ifdef CONFIG_APBH_DMA
diff --git a/arch/arm/imx-common/iomux-v3.c b/arch/arm/imx-common/iomux-v3.c
index 22cd11aa04..e88e6e2a98 100644
--- a/arch/arm/imx-common/iomux-v3.c
+++ b/arch/arm/imx-common/iomux-v3.c
@@ -77,3 +77,18 @@ void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
p += stride;
}
}
+
+void imx_iomux_set_gpr_register(int group, int start_bit,
+ int num_bits, int value)
+{
+ int i = 0;
+ u32 reg;
+ reg = readl(base + group * 4);
+ while (num_bits) {
+ reg &= ~(1<<(start_bit + i));
+ i++;
+ num_bits--;
+ }
+ reg |= (value << start_bit);
+ writel(reg, base + group * 4);
+}
diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c
index c63f78f682..65ef60bf2e 100644
--- a/arch/arm/imx-common/timer.c
+++ b/arch/arm/imx-common/timer.c
@@ -12,6 +12,7 @@
#include <div64.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
/* General purpose timers registers */
struct mxc_gpt {
@@ -26,23 +27,59 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
/* General purpose timers bitfields */
#define GPTCR_SWR (1 << 15) /* Software reset */
+#define GPTCR_24MEN (1 << 10) /* Enable 24MHz clock input */
#define GPTCR_FRR (1 << 9) /* Freerun / restart */
-#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
+#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source 32khz */
+#define GPTCR_CLKSOURCE_OSC (5 << 6) /* Clock source OSC */
+#define GPTCR_CLKSOURCE_PRE (1 << 6) /* Clock source PRECLK */
+#define GPTCR_CLKSOURCE_MASK (0x7 << 6)
#define GPTCR_TEN 1 /* Timer enable */
+#define GPTPR_PRESCALER24M_SHIFT 12
+#define GPTPR_PRESCALER24M_MASK (0xF << GPTPR_PRESCALER24M_SHIFT)
+
DECLARE_GLOBAL_DATA_PTR;
+static inline int gpt_has_clk_source_osc(void)
+{
+#if defined(CONFIG_MX6)
+ if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) &&
+ (is_soc_rev(CHIP_REV_1_0) > 0)) || is_cpu_type(MXC_CPU_MX6DL) ||
+ is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX))
+ return 1;
+
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+static inline ulong gpt_get_clk(void)
+{
+#ifdef CONFIG_MXC_GPT_HCLK
+ if (gpt_has_clk_source_osc())
+ return MXC_HCLK >> 3;
+ else
+ return mxc_get_clock(MXC_IPG_PERCLK);
+#else
+ return MXC_CLK32;
+#endif
+}
static inline unsigned long long tick_to_time(unsigned long long tick)
{
+ ulong gpt_clk = gpt_get_clk();
+
tick *= CONFIG_SYS_HZ;
- do_div(tick, MXC_CLK32);
+ do_div(tick, gpt_clk);
return tick;
}
static inline unsigned long long us_to_tick(unsigned long long usec)
{
- usec = usec * MXC_CLK32 + 999999;
+ ulong gpt_clk = gpt_get_clk();
+
+ usec = usec * gpt_clk + 999999;
do_div(usec, 1000000);
return usec;
@@ -59,11 +96,31 @@ int timer_init(void)
for (i = 0; i < 100; i++)
__raw_writel(0, &cur_gpt->control);
- __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
-
- /* Freerun Mode, PERCLK1 input */
i = __raw_readl(&cur_gpt->control);
- __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
+ i &= ~GPTCR_CLKSOURCE_MASK;
+
+#ifdef CONFIG_MXC_GPT_HCLK
+ if (gpt_has_clk_source_osc()) {
+ i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN;
+
+ /* For DL/S, SX, set 24Mhz OSC Enable bit and prescaler */
+ if (is_cpu_type(MXC_CPU_MX6DL) ||
+ is_cpu_type(MXC_CPU_MX6SOLO) ||
+ is_cpu_type(MXC_CPU_MX6SX)) {
+ i |= GPTCR_24MEN;
+
+ /* Produce 3Mhz clock */
+ __raw_writel((7 << GPTPR_PRESCALER24M_SHIFT),
+ &cur_gpt->prescaler);
+ }
+ } else {
+ i |= GPTCR_CLKSOURCE_PRE | GPTCR_TEN;
+ }
+#else
+ __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
+ i |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
+#endif
+ __raw_writel(i, &cur_gpt->control);
gd->arch.tbl = __raw_readl(&cur_gpt->counter);
gd->arch.tbu = 0;
@@ -86,7 +143,7 @@ ulong get_timer_masked(void)
{
/*
* get_ticks() returns a long long (64 bit), it wraps in
- * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 2^64 / GPT_CLK = 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.
*/
@@ -117,5 +174,5 @@ void __udelay(unsigned long usec)
*/
ulong get_tbclk(void)
{
- return MXC_CLK32;
+ return gpt_get_clk();
}
diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
index e67b5b9e7d..39f3c0707b 100644
--- a/arch/arm/include/asm/arch-mx6/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
@@ -89,7 +89,7 @@ struct mxc_ccm_reg {
u32 analog_pll_video_tog;
u32 analog_pll_video_num; /* 0x40b0 */
u32 analog_reserved6[3];
- u32 analog_pll_vedio_denon; /* 0x40c0 */
+ u32 analog_pll_video_denom; /* 0x40c0 */
u32 analog_reserved7[7];
u32 analog_pll_enet; /* 0x40e0 */
u32 analog_pll_enet_set;
@@ -228,6 +228,8 @@ struct mxc_ccm_reg {
#ifdef CONFIG_MX6SX
#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK (0x7 << 7)
#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET 7
+#endif
+#if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
#define MXC_CCM_CSCMR1_PER_CLK_SEL_MASK (1 << 6)
#define MXC_CCM_CSCMR1_PER_CLK_SEL_OFFSET 6
#endif
@@ -931,10 +933,10 @@ struct mxc_ccm_reg {
#define BF_ANADIG_PLL_VIDEO_RSVD0(v) \
(((v) << 22) & BM_ANADIG_PLL_VIDEO_RSVD0)
#define BM_ANADIG_PLL_VIDEO_SSC_EN 0x00200000
-#define BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT 19
-#define BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT 0x00180000
-#define BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(v) \
- (((v) << 19) & BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
+#define BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT 19
+#define BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT 0x00180000
+#define BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(v) \
+ (((v) << 19) & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN 0x00040000
#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE 0x00020000
#define BM_ANADIG_PLL_VIDEO_BYPASS 0x00010000
diff --git a/arch/arm/include/asm/arch-mx6/mx6sl_pins.h b/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
index 045ccc4512..d9db58c9a3 100644
--- a/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
+++ b/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
@@ -14,12 +14,31 @@ enum {
MX6_PAD_ECSPI1_MOSI__ECSPI_MOSI = IOMUX_PAD(0x035C, 0x006C, 0, 0x0688, 0, 0),
MX6_PAD_ECSPI1_SCLK__ECSPI_SCLK = IOMUX_PAD(0x0360, 0x0070, 0, 0x067C, 0, 0),
MX6_PAD_ECSPI1_SS0__GPIO4_IO11 = IOMUX_PAD(0x0364, 0x0074, 5, 0x0000, 0, 0),
+ MX6_PAD_SD1_CLK__USDHC1_CLK = IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_CMD__USDHC1_CMD = IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT0__USDHC1_DAT0 = IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT1__USDHC1_DAT1 = IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT2__USDHC1_DAT2 = IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT3__USDHC1_DAT3 = IOMUX_PAD(0x0548, 0x0240, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT4__USDHC1_DAT4 = IOMUX_PAD(0x054C, 0x0244, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT5__USDHC1_DAT5 = IOMUX_PAD(0x0550, 0x0248, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT6__USDHC1_DAT6 = IOMUX_PAD(0x0554, 0x024C, 0, 0x0000, 0, 0),
+ MX6_PAD_SD1_DAT7__USDHC1_DAT7 = IOMUX_PAD(0x0558, 0x0250, 0, 0x0000, 0, 0),
+ MX6_PAD_KEY_ROW7__GPIO_4_7 = IOMUX_PAD(0x04B0, 0x01A8, 5, 0x0000, 0, 0),
MX6_PAD_SD2_CLK__USDHC2_CLK = IOMUX_PAD(0x055C, 0x0254, 0, 0x0000, 0, 0),
MX6_PAD_SD2_CMD__USDHC2_CMD = IOMUX_PAD(0x0560, 0x0258, 0, 0x0000, 0, 0),
MX6_PAD_SD2_DAT0__USDHC2_DAT0 = IOMUX_PAD(0x0564, 0x025C, 0, 0x0000, 0, 0),
MX6_PAD_SD2_DAT1__USDHC2_DAT1 = IOMUX_PAD(0x0568, 0x0260, 0, 0x0000, 0, 0),
MX6_PAD_SD2_DAT2__USDHC2_DAT2 = IOMUX_PAD(0x056C, 0x0264, 0, 0x0000, 0, 0),
MX6_PAD_SD2_DAT3__USDHC2_DAT3 = IOMUX_PAD(0x0570, 0x0268, 0, 0x0000, 0, 0),
+ MX6_PAD_SD2_DAT7__GPIO_5_0 = IOMUX_PAD(0x0580, 0x0278, 5, 0x0000, 0, 0),
+ MX6_PAD_SD3_CLK__USDHC3_CLK = IOMUX_PAD(0x0588, 0x0280, 0, 0x0000, 0, 0),
+ MX6_PAD_SD3_CMD__USDHC3_CMD = IOMUX_PAD(0x058C, 0x0284, 0, 0x0000, 0, 0),
+ MX6_PAD_SD3_DAT0__USDHC3_DAT0 = IOMUX_PAD(0x0590, 0x0288, 0, 0x0000, 0, 0),
+ MX6_PAD_SD3_DAT1__USDHC3_DAT1 = IOMUX_PAD(0x0594, 0x028C, 0, 0x0000, 0, 0),
+ MX6_PAD_SD3_DAT2__USDHC3_DAT2 = IOMUX_PAD(0x0598, 0x0290, 0, 0x0000, 0, 0),
+ MX6_PAD_SD3_DAT3__USDHC3_DAT3 = IOMUX_PAD(0x059C, 0x0294, 0, 0x0000, 0, 0),
+ MX6_PAD_REF_CLK_32K__GPIO_3_22 = IOMUX_PAD(0x0530, 0x0228, 5, 0x0000, 0, 0),
MX6_PAD_UART1_RXD__UART1_RXD = IOMUX_PAD(0x05A0, 0x0298, 0, 0x07FC, 0, 0),
MX6_PAD_UART1_TXD__UART1_TXD = IOMUX_PAD(0x05A4, 0x029C, 0, 0x0000, 0, 0),
diff --git a/arch/arm/include/asm/imx-common/iomux-v3.h b/arch/arm/include/asm/imx-common/iomux-v3.h
index a8ca49c343..e0a49be4ff 100644
--- a/arch/arm/include/asm/imx-common/iomux-v3.h
+++ b/arch/arm/include/asm/imx-common/iomux-v3.h
@@ -182,6 +182,11 @@ typedef u64 iomux_v3_cfg_t;
void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
unsigned count);
+/*
+* Set bits for general purpose registers
+*/
+void imx_iomux_set_gpr_register(int group, int start_bit,
+ int num_bits, int value);
/* macros for declaring and using pinmux array */
#if defined(CONFIG_MX6QDL)