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);

Reply via email to