Module Name: src
Committed By: ryo
Date: Fri Jan 9 09:50:46 UTC 2015
Modified Files:
src/sys/arch/arm/imx: imx6_board.c imx6_ccm.c imx6_ccmreg.h
imx6_ccmvar.h
Log Message:
- add some clock source about IPU
- fix a9tmr frequency when changing clock of machdep.imx6.frequency.arm
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/imx6_board.c \
src/sys/arch/arm/imx/imx6_ccmreg.h src/sys/arch/arm/imx/imx6_ccmvar.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/imx6_ccm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/imx/imx6_board.c
diff -u src/sys/arch/arm/imx/imx6_board.c:1.2 src/sys/arch/arm/imx/imx6_board.c:1.3
--- src/sys/arch/arm/imx/imx6_board.c:1.2 Mon Oct 6 10:27:13 2014
+++ src/sys/arch/arm/imx/imx6_board.c Fri Jan 9 09:50:46 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_board.c,v 1.2 2014/10/06 10:27:13 ryo Exp $ */
+/* $NetBSD: imx6_board.c,v 1.3 2015/01/09 09:50:46 ryo Exp $ */
/*
* Copyright (c) 2012 Genetec Corporation. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: imx6_board.c,v 1.2 2014/10/06 10:27:13 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: imx6_board.c,v 1.3 2015/01/09 09:50:46 ryo Exp $");
#include "opt_imx.h"
#include "arml2cc.h"
@@ -46,19 +46,8 @@ __KERNEL_RCSID(1, "$NetBSD: imx6_board.c
#include <arm/imx/imx6_reg.h>
#include <arm/imx/imx6_mmdcreg.h>
#include <arm/imx/imx6_ccmreg.h>
-#include <arm/imx/imxclockvar.h>
#include <arm/imx/imxwdogreg.h>
-/*
- * PERIPHCLK_N is an arm root clock divider for MPcore interupt controller.
- * PERIPHCLK_N is equal to, or greater than two.
- * see "Cortex-A9 MPCore Technical Reference Manual" -
- * Chapter 5: Clocks, Resets, and Power Management, 5.1: Clocks.
- */
-#ifndef PERIPHCLK_N
-#define PERIPHCLK_N 2
-#endif
-
bus_space_tag_t imx6_ioreg_bst = &imx_bs_tag;
bus_space_handle_t imx6_ioreg_bsh;
bus_space_tag_t imx6_armcore_bst = &imx_bs_tag;
@@ -219,7 +208,7 @@ imx6_device_register(device_t self, void
*/
if (device_is_a(self, "a9tmr") || device_is_a(self, "a9wdt")) {
prop_dictionary_set_uint32(dict, "frequency",
- imx6_armrootclk() / PERIPHCLK_N);
+ imx6_armrootclk() / IMX6_PERIPHCLK_N);
return;
}
}
Index: src/sys/arch/arm/imx/imx6_ccmreg.h
diff -u src/sys/arch/arm/imx/imx6_ccmreg.h:1.2 src/sys/arch/arm/imx/imx6_ccmreg.h:1.3
--- src/sys/arch/arm/imx/imx6_ccmreg.h:1.2 Mon Oct 6 10:27:13 2014
+++ src/sys/arch/arm/imx/imx6_ccmreg.h Fri Jan 9 09:50:46 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ccmreg.h,v 1.2 2014/10/06 10:27:13 ryo Exp $ */
+/* $NetBSD: imx6_ccmreg.h,v 1.3 2015/01/09 09:50:46 ryo Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <[email protected]>
@@ -31,12 +31,21 @@
#include <sys/cdefs.h>
+/*
+ * PERIPHCLK_N is an arm root clock divider for MPcore interupt controller.
+ * PERIPHCLK_N is equal to, or greater than two.
+ * see "Cortex-A9 MPCore Technical Reference Manual" -
+ * Chapter 5: Clocks, Resets, and Power Management, 5.1: Clocks.
+ */
+#ifndef IMX6_PERIPHCLK_N
+#define IMX6_PERIPHCLK_N 2
+#endif
+
#ifndef IMX6_OSC_FREQ
#define IMX6_OSC_FREQ (24 * 1000 * 1000) /* 24MHz */
#endif
#define IMX6_CCM_SIZE 0x8000
-
/* 0x00000000 = 0x020c4000 */
#define CCM_CCR 0x00000000
#define CCM_CCDR 0x00000004
@@ -90,6 +99,13 @@
#define CCM_CSCMR1_SSI1_CLK_SEL __BITS(11, 10)
#define CCM_CSCMR1_PERCLK_PODF __BITS(5, 0)
+#define CCM_CSCMR2 0x00000020
+#define CCM_CSCMR2_ESAI_CLK_SEL __BITS(20, 19)
+#define CCM_CSCMR2_LDB_DI1_IPU_DIV __BIT(11)
+#define CCM_CSCMR2_LDB_DI0_IPU_DIV __BIT(10)
+#define CCM_CSCMR2_CAN_CLK_PODF __BITS(7, 2)
+
+
#define CCM_CSCDR1 0x00000024
#define CCM_CSCDR1_VPU_AXI_PODF __BITS(25, 27)
#define CCM_CSCDR1_USDHC4_PODF __BITS(22, 24)
@@ -98,6 +114,32 @@
#define CCM_CSCDR1_USDHC1_PODF __BITS(13, 11)
#define CCM_CSCDR1_UART_CLK_PODF __BITS(5, 0)
+#define CCM_CS1CDR 0x00000028
+#define CCM_CS2CDR 0x0000002c
+#define CCM_CS2CDR_ENFC_CLK_PODF __BITS(26, 21)
+#define CCM_CS2CDR_ENFC_CLK_PRED __BITS(20, 18)
+#define CCM_CS2CDR_ENFC_CLK_SEL __BITS(17, 16)
+#define CCM_CS2CDR_LDB_DI1_CLK_SEL __BITS(14, 12)
+#define CCM_CS2CDR_LDB_DI0_CLK_SEL __BITS(11, 9)
+#define CCM_CS2CDR_SSI2_CLK_PRED __BITS(8, 6)
+#define CCM_CS2CDR_SSI2_CLK_PODF __BITS(5, 0)
+#define CCM_CDCDR 0x00000030
+#define CCM_CHSCCDR 0x00000034
+#define CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL __BITS(17, 15)
+#define CCM_CHSCCDR_IPU1_DI1_PODF __BITS(14, 12)
+#define CCM_CHSCCDR_IPU1_DI1_CLK_SEL __BITS(11, 9)
+#define CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL __BITS(8, 6)
+#define CCM_CHSCCDR_IPU1_DI0_PODF __BITS(5, 3)
+#define CCM_CHSCCDR_IPU1_DI0_CLK_SEL __BITS(2, 0)
+
+
+#define CCM_CSCDR2 0x00000038
+#define CCM_CSCDR3 0x0000003c
+#define CCM_CSCDR3_IPU2_HSP_PODF __BITS(18, 16)
+#define CCM_CSCDR3_IPU2_HSP_CLK_SEL __BITS(15, 14)
+#define CCM_CSCDR3_IPU1_HSP_PODF __BITS(13, 11)
+#define CCM_CSCDR3_IPU1_HSP_CLK_SEL __BITS(10, 9)
+
#define CCM_CCGR5 0x0000007c
#define CCM_CCGR5_UART_SERIAL_CLK_ENABLE(n) __SHIFTIN(n, __BITS(27, 26))
#define CCM_CCGR5_UART_CLK_ENABLE(n) __SHIFTIN(n, __BITS(25, 24))
Index: src/sys/arch/arm/imx/imx6_ccmvar.h
diff -u src/sys/arch/arm/imx/imx6_ccmvar.h:1.2 src/sys/arch/arm/imx/imx6_ccmvar.h:1.3
--- src/sys/arch/arm/imx/imx6_ccmvar.h:1.2 Tue Oct 7 09:36:09 2014
+++ src/sys/arch/arm/imx/imx6_ccmvar.h Fri Jan 9 09:50:46 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ccmvar.h,v 1.2 2014/10/07 09:36:09 ryo Exp $ */
+/* $NetBSD: imx6_ccmvar.h,v 1.3 2015/01/09 09:50:46 ryo Exp $ */
/*
* Copyright (c) 2012 Genetec Corporation. All rights reserved.
* Written by Hashimoto Kenichi for Genetec Corporation.
@@ -53,6 +53,8 @@ enum imx6_clock {
IMX6CLK_AXI,
IMX6CLK_MMDC_CH0,
IMX6CLK_MMDC_CH1,
+ IMX6CLK_MMDC_CH0_CLK_ROOT,
+ IMX6CLK_MMDC_CH1_CLK_ROOT,
IMX6CLK_USDHC1,
IMX6CLK_USDHC2,
@@ -60,6 +62,15 @@ enum imx6_clock {
IMX6CLK_USDHC4,
IMX6CLK_PERCLK,
+
+ IMX6CLK_IPU1_HSP_CLK_ROOT,
+ IMX6CLK_IPU2_HSP_CLK_ROOT,
+ IMX6CLK_IPU1_DI0_CLK_ROOT,
+ IMX6CLK_IPU1_DI1_CLK_ROOT,
+ IMX6CLK_LDB_DI0_IPU,
+ IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT,
+ IMX6CLK_LDB_DI1_IPU,
+ IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT,
};
uint32_t imx6_get_clock(enum imx6_clock);
Index: src/sys/arch/arm/imx/imx6_ccm.c
diff -u src/sys/arch/arm/imx/imx6_ccm.c:1.3 src/sys/arch/arm/imx/imx6_ccm.c:1.4
--- src/sys/arch/arm/imx/imx6_ccm.c:1.3 Tue Oct 7 09:36:09 2014
+++ src/sys/arch/arm/imx/imx6_ccm.c Fri Jan 9 09:50:46 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_ccm.c,v 1.3 2014/10/07 09:36:09 ryo Exp $ */
+/* $NetBSD: imx6_ccm.c,v 1.4 2015/01/09 09:50:46 ryo Exp $ */
/*
* Copyright (c) 2010-2012, 2014 Genetec Corporation. All rights reserved.
@@ -27,11 +27,11 @@
*/
/*
- * Clock Controller Module (CCM) for i.MX5
+ * Clock Controller Module (CCM) for i.MX6
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.3 2014/10/07 09:36:09 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v 1.4 2015/01/09 09:50:46 ryo Exp $");
#include "opt_imx.h"
#include "opt_imx6clk.h"
@@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: imx6_ccm.c,v
#include <sys/param.h>
#include <machine/cpu.h>
+#include <arm/cortex/a9tmr_var.h>
#include <arm/imx/imx6_ccmvar.h>
#include <arm/imx/imx6_ccmreg.h>
@@ -282,7 +283,7 @@ imxccm_sysctl_setup(struct imxccm_softc
imxccm_sysctl_freq_helper, 0, (void *)sc, 0, CTL_CREATE, CTL_EOL);
if (rv != 0)
goto fail;
- sc->sc_sysctlnode_arm= node->sysctl_num;
+ sc->sc_sysctlnode_arm = node->sysctl_num;
rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node,
0, CTLTYPE_INT,
@@ -436,7 +437,9 @@ imx6_set_clock(enum imx6_clock clk, uint
v &= ~CCM_ANALOG_PLL_ARM_DIV_SELECT;
imx6_ccm_write(CCM_ANALOG_PLL_ARM, v | __SHIFTIN(pll, CCM_ANALOG_PLL_ARM_DIV_SELECT));
- cpufreq_set_all(imx6_get_clock(IMX6CLK_ARM_ROOT));
+ v = imx6_get_clock(IMX6CLK_ARM_ROOT);
+ cpufreq_set_all(v);
+ a9tmr_update_freq(v / IMX6_PERIPHCLK_N);
return 0;
}
}
@@ -665,6 +668,179 @@ imx6_get_clock(enum imx6_clock clk)
freq = freq / (__SHIFTOUT(v, CCM_CSCMR1_PERCLK_PODF) + 1);
break;
+ case IMX6CLK_MMDC_CH1_CLK_ROOT:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH1);
+ v = __SHIFTOUT(imx6_ccm_read(CCM_CBCDR), CCM_CBCDR_MMDC_CH1_AXI_PODF);
+ freq = freq / (v + 1);
+ break;
+
+ case IMX6CLK_MMDC_CH0_CLK_ROOT:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
+ v = __SHIFTOUT(imx6_ccm_read(CCM_CBCDR), CCM_CBCDR_MMDC_CH0_AXI_PODF);
+ freq = freq / (v + 1);
+ break;
+
+ case IMX6CLK_MMDC_CH0:
+ case IMX6CLK_MMDC_CH1:
+ v = imx6_ccm_read(CCM_CBCMR);
+ sel = (clk == IMX6CLK_MMDC_CH0) ?
+ __SHIFTOUT(v, CCM_CBCMR_PRE_PERIPH_CLK_SEL) :
+ __SHIFTOUT(v, CCM_CBCMR_PRE_PERIPH2_CLK_SEL);
+ switch (sel) {
+ case 0:
+ freq = imx6_get_clock(IMX6CLK_PLL2);
+ break;
+ case 1:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
+ break;
+ case 2:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2) / 2;
+ break;
+ }
+ break;
+
+ case IMX6CLK_IPU1_HSP_CLK_ROOT:
+ v = imx6_ccm_read(CCM_CSCDR3);
+ switch (__SHIFTOUT(v, CCM_CSCDR3_IPU1_HSP_CLK_SEL)) {
+ case 0:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
+ break;
+ case 1:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
+ break;
+ case 2:
+ freq = imx6_get_clock(IMX6CLK_PLL3) / 4;
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
+ break;
+ }
+ v = __SHIFTOUT(v, CCM_CSCDR3_IPU1_HSP_CLK_SEL);
+ freq = freq / (v + 1);
+ break;
+ case IMX6CLK_IPU2_HSP_CLK_ROOT:
+ v = imx6_ccm_read(CCM_CSCDR3);
+ switch (__SHIFTOUT(v, CCM_CSCDR3_IPU2_HSP_CLK_SEL)) {
+ case 0:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
+ break;
+ case 1:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
+ break;
+ case 2:
+ freq = imx6_get_clock(IMX6CLK_PLL3) / 4;
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
+ break;
+ }
+ v = __SHIFTOUT(v, CCM_CSCDR3_IPU2_HSP_CLK_SEL);
+ freq = freq / (v + 1);
+ break;
+
+ case IMX6CLK_IPU1_DI0_CLK_ROOT:
+ case IMX6CLK_IPU1_DI1_CLK_ROOT:
+ v = imx6_ccm_read(CCM_CHSCCDR);
+ sel = (clk == IMX6CLK_IPU1_DI0_CLK_ROOT) ?
+ __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_CLK_SEL) :
+ __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_CLK_SEL);
+ switch (sel) {
+ case 0:
+ sel = (clk == IMX6CLK_IPU1_DI0_CLK_ROOT) ?
+ __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL) :
+ __SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL);
+ switch (sel) {
+ case 0:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH0);
+ break;
+ case 1:
+ freq = imx6_get_clock(IMX6CLK_PLL3);
+ break;
+ case 2:
+ freq = imx6_get_clock(IMX6CLK_PLL5);
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
+ break;
+ case 4:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
+ break;
+ case 5:
+ freq = imx6_get_clock(IMX6CLK_PLL3_PFD1);
+ break;
+ default:
+ /* reserved */
+ freq = 0;
+ }
+ if (clk == IMX6CLK_IPU1_DI0_CLK_ROOT)
+ freq = freq / (__SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI0_PODF) + 1);
+ else
+ freq = freq / (__SHIFTOUT(v, CCM_CHSCCDR_IPU1_DI1_PODF) + 1);
+ break;
+ case 1:
+ case 2:
+ /* IPP_DI[01]_CLK is an external clock */
+ freq = 0;
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_LDB_DI0_IPU);
+ break;
+ case 4:
+ freq = imx6_get_clock(IMX6CLK_LDB_DI1_IPU);
+ break;
+ default:
+ /* reserved */
+ freq = 0;
+ }
+ break;
+
+ case IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT:
+ case IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT:
+ v = imx6_ccm_read(CCM_CS2CDR);
+ sel = (clk == IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT) ?
+ __SHIFTOUT(v, CCM_CS2CDR_LDB_DI0_CLK_SEL) :
+ __SHIFTOUT(v, CCM_CS2CDR_LDB_DI1_CLK_SEL);
+ switch (sel) {
+ case 0:
+ freq = imx6_get_clock(IMX6CLK_PLL5);
+ break;
+ case 1:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD0);
+ break;
+ case 2:
+ freq = imx6_get_clock(IMX6CLK_PLL2_PFD2);
+ break;
+ case 3:
+ freq = imx6_get_clock(IMX6CLK_MMDC_CH1);
+ break;
+ case 4:
+ freq = imx6_get_clock(IMX6CLK_PLL3);
+ break;
+ case 5:
+ default:
+ /* reserved */
+ freq = 0;
+ }
+ break;
+
+ case IMX6CLK_LDB_DI0_IPU:
+ freq = imx6_get_clock(IMX6CLK_LDB_DI0_SERIAL_CLK_ROOT);
+ v = imx6_ccm_read(CCM_CSCMR2);
+ if (!ISSET(v, CCM_CSCMR2_LDB_DI0_IPU_DIV))
+ freq *= 2;
+ freq /= 7;
+ break;
+ case IMX6CLK_LDB_DI1_IPU:
+ freq = imx6_get_clock(IMX6CLK_LDB_DI1_SERIAL_CLK_ROOT);
+ v = imx6_ccm_read(CCM_CSCMR2);
+ if (!ISSET(v, CCM_CSCMR2_LDB_DI1_IPU_DIV))
+ freq *= 2;
+ freq /= 7;
+ break;
+
default:
aprint_error_dev(ccm_softc->sc_dev,
"clock %d: not supported yet\n", clk);