* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
@ 2010-11-15 14:36 Shawn Guo
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
` (11 more replies)
0 siblings, 12 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
This patchset adds the initial support of i.MX28, and the target device
is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
and adding codes into arch/arm/mxc and arch/arm/mach-imx.
git://git.pengutronix.de/git/imx/linux-2.6.git imx-single-kernel
Please take the time to review the patchset. Thanks.
Regards,
Shawn
Shawn Guo (11):
arch/arm/mach-imx/Kconfig | 20 +
arch/arm/mach-imx/Makefile | 4 +
arch/arm/mach-imx/Makefile.boot | 4 +
arch/arm/mach-imx/clock-imx28.c | 733 +++++++++++++++++++++++
arch/arm/mach-imx/devices-imx28.h | 20 +
arch/arm/mach-imx/devices.c | 27 +-
arch/arm/mach-imx/mach-mx28evk.c | 109 ++++
arch/arm/mach-imx/mm-imx28.c | 50 ++
arch/arm/mach-imx/regs-clkctrl-mx28.h | 662 ++++++++++++++++++++
arch/arm/plat-mxc/Kconfig | 12 +
arch/arm/plat-mxc/Makefile | 4 +-
arch/arm/plat-mxc/devices/Kconfig | 3 +
arch/arm/plat-mxc/devices/Makefile | 1 +
arch/arm/plat-mxc/devices/platform-duart.c | 42 ++
arch/arm/plat-mxc/devices/platform-fec.c | 5 +
arch/arm/plat-mxc/gpio.c | 186 +++++-
arch/arm/plat-mxc/icoll.c | 79 +++
arch/arm/plat-mxc/include/mach/common.h | 5 +
arch/arm/plat-mxc/include/mach/devices-common.h | 11 +
arch/arm/plat-mxc/include/mach/entry-macro.S | 22 +-
arch/arm/plat-mxc/include/mach/hardware.h | 9 +-
arch/arm/plat-mxc/include/mach/iomux-mx28.h | 50 ++
arch/arm/plat-mxc/include/mach/iomux-pinctrl.h | 91 +++
arch/arm/plat-mxc/include/mach/irqs.h | 11 +-
arch/arm/plat-mxc/include/mach/memory.h | 5 +-
arch/arm/plat-mxc/include/mach/mx28.h | 232 +++++++
arch/arm/plat-mxc/include/mach/mxc.h | 14 +
arch/arm/plat-mxc/include/mach/uncompress.h | 20 +-
arch/arm/plat-mxc/iomux-pinctrl.c | 94 +++
arch/arm/plat-mxc/system.c | 104 ++++-
arch/arm/plat-mxc/time.c | 120 +++-
31 files changed, 2674 insertions(+), 75 deletions(-)
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:25 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
` (10 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/include/mach/hardware.h | 9 +-
arch/arm/plat-mxc/include/mach/irqs.h | 11 +-
arch/arm/plat-mxc/include/mach/memory.h | 5 +-
arch/arm/plat-mxc/include/mach/mx28.h | 232 +++++++++++++++++++++++++++++
arch/arm/plat-mxc/include/mach/mxc.h | 14 ++
5 files changed, 264 insertions(+), 7 deletions(-)
create mode 100644 arch/arm/plat-mxc/include/mach/mx28.h
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 2f59b63..499b14c 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel at pengutronix.de
*
* This program is free software; you can redistribute it and/or
@@ -63,6 +63,9 @@
* AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
* SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
* X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000
+ * mx28:
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
* mx31:
* AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
* AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
@@ -127,6 +130,10 @@
# include <mach/mx25.h>
#endif
+#ifdef CONFIG_ARCH_MX28
+# include <mach/mx28.h>
+#endif
+
#ifdef CONFIG_ARCH_MXC91231
# include <mach/mxc91231.h>
#endif
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 86781f7..2f810c5 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -12,12 +12,13 @@
#define __ASM_ARCH_MXC_IRQS_H__
/*
- * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
+ * SoCs with AVIC interrupt controller have 64 IRQs,
+ * those with TZIC and ICOLL have 128.
*/
-#ifdef CONFIG_MXC_TZIC
-#define MXC_INTERNAL_IRQS 128
-#else
+#ifdef CONFIG_MXC_AVIC
#define MXC_INTERNAL_IRQS 64
+#else
+#define MXC_INTERNAL_IRQS 128
#endif
#define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 564ec9d..af090e3 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -15,6 +15,7 @@
#define MX21_PHYS_OFFSET UL(0xc0000000)
#define MX25_PHYS_OFFSET UL(0x80000000)
#define MX27_PHYS_OFFSET UL(0xa0000000)
+#define MX28_PHYS_OFFSET UL(0x40000000)
#define MX3x_PHYS_OFFSET UL(0x80000000)
#define MX51_PHYS_OFFSET UL(0x90000000)
#define MXC91231_PHYS_OFFSET UL(0x90000000)
@@ -28,6 +29,8 @@
# define PHYS_OFFSET MX25_PHYS_OFFSET
# elif defined CONFIG_MACH_MX27
# define PHYS_OFFSET MX27_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX28
+# define PHYS_OFFSET MX28_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX3
# define PHYS_OFFSET MX3x_PHYS_OFFSET
# elif defined CONFIG_ARCH_MXC91231
diff --git a/arch/arm/plat-mxc/include/mach/mx28.h b/arch/arm/plat-mxc/include/mach/mx28.h
new file mode 100644
index 0000000..6f73888
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx28.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009-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 __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+#define SET_ADDR 0x4
+#define CLR_ADDR 0x8
+#define TOG_ADDR 0xc
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR 0x00000000
+#define MX28_OCRAM_SIZE SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR 0x80000000
+#define MX28_IO_SIZE SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR (MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR (MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR (MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_FEC_BASE_ADDR MX28_ENET_BASE_ADDR
+
+#define MX28_IO_P2V(x) IMX_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX27_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT 0
+#define MX28_INT_VDDD_BRNOUT 1
+#define MX28_INT_VDDIO_BRNOUT 2
+#define MX28_INT_VDDA_BRNOUT 3
+#define MX28_INT_VDD5V_DROOP 4
+#define MX28_INT_DCDC4P2_BRNOUT 5
+#define MX28_INT_VDD5V 6
+#define MX28_INT_RESV7 7
+#define MX28_INT_CAN0 8
+#define MX28_INT_CAN1 9
+#define MX28_INT_LRADC_TOUCH 10
+#define MX28_INT_RESV11 11
+#define MX28_INT_RESV12 12
+#define MX28_INT_HSADC 13
+#define MX28_INT_IRADC_THRESH0 14
+#define MX28_INT_IRADC_THRESH1 15
+#define MX28_INT_LRADC_CH0 16
+#define MX28_INT_LRADC_CH1 17
+#define MX28_INT_LRADC_CH2 18
+#define MX28_INT_LRADC_CH3 19
+#define MX28_INT_LRADC_CH4 20
+#define MX28_INT_LRADC_CH5 21
+#define MX28_INT_LRADC_CH6 22
+#define MX28_INT_LRADC_CH7 23
+#define MX28_INT_LRADC_BUTTON0 24
+#define MX28_INT_LRADC_BUTTON1 25
+#define MX28_INT_RESV26 26
+#define MX28_INT_PERFMON 27
+#define MX28_INT_RTC_1MSEC 28
+#define MX28_INT_RTC_ALARM 29
+#define MX28_INT_RESV30 30
+#define MX28_INT_COMMS 31
+#define MX28_INT_EMI_ERR 32
+#define MX28_INT_RESV33 33
+#define MX28_INT_RESV34 34
+#define MX28_INT_RESV35 35
+#define MX28_INT_RESV36 36
+#define MX28_INT_RESV37 37
+#define MX28_INT_LCDIF 38
+#define MX28_INT_PXP 39
+#define MX28_INT_RESV40 40
+#define MX28_INT_BCH 41
+#define MX28_INT_GPMI 42
+#define MX28_INT_RESV43 43
+#define MX28_INT_RESV44 44
+#define MX28_INT_SPDIF_ERROR 45
+#define MX28_INT_RESV46 46
+#define MX28_INT_DUART 47
+#define MX28_INT_TIMER0 48
+#define MX28_INT_TIMER1 49
+#define MX28_INT_TIMER2 50
+#define MX28_INT_TIMER3 51
+#define MX28_INT_DCP_VMI 52
+#define MX28_INT_DCP 53
+#define MX28_INT_DCP_SECURE 54
+#define MX28_INT_RESV55 55
+#define MX28_INT_RESV56 56
+#define MX28_INT_RESV57 57
+#define MX28_INT_SAIF1 58
+#define MX28_INT_SAIF0 59
+#define MX28_INT_RESV60 60
+#define MX28_INT_RESV61 61
+#define MX28_INT_RESV62 62
+#define MX28_INT_RESV63 63
+#define MX28_INT_RESV64 64
+#define MX28_INT_RESV65 65
+#define MX28_INT_SPDIF_DMA 66
+#define MX28_INT_RESV67 67
+#define MX28_INT_I2C0_DMA 68
+#define MX28_INT_I2C1_DMA 69
+#define MX28_INT_AUART0_RX_DMA 70
+#define MX28_INT_AUART0_TX_DMA 71
+#define MX28_INT_AUART1_RX_DMA 72
+#define MX28_INT_AUART1_TX_DMA 73
+#define MX28_INT_AUART2_RX_DMA 74
+#define MX28_INT_AUART2_TX_DMA 75
+#define MX28_INT_AUART3_RX_DMA 76
+#define MX28_INT_AUART3_TX_DMA 77
+#define MX28_INT_AUART4_RX_DMA 78
+#define MX28_INT_AUART4_TX_DMA 79
+#define MX28_INT_SAIF0_DMA 80
+#define MX28_INT_SAIF1_DMA 81
+#define MX28_INT_SSP0_DMA 82
+#define MX28_INT_SSP1_DMA 83
+#define MX28_INT_SSP2_DMA 84
+#define MX28_INT_SSP3_DMA 85
+#define MX28_INT_LCDIF_DMA 86
+#define MX28_INT_HSADC_DMA 87
+#define MX28_INT_GPMI_DMA 88
+#define MX28_INT_DIGCTL_DEBUG_TRAP 89
+#define MX28_INT_RESV90 90
+#define MX28_INT_RESV91 91
+#define MX28_INT_USB1 92
+#define MX28_INT_USB0 93
+#define MX28_INT_USB1_WAKEUP 94
+#define MX28_INT_USB0_WAKEUP 95
+#define MX28_INT_SSP0 96
+#define MX28_INT_SSP1 97
+#define MX28_INT_SSP2 98
+#define MX28_INT_SSP3 99
+#define MX28_INT_ENET_SWI 100
+#define MX28_INT_ENET_MAC0 101
+#define MX28_INT_ENET_MAC1 102
+#define MX28_INT_ENET_MAC0_1588 103
+#define MX28_INT_ENET_MAC1_1588 104
+#define MX28_INT_RESV105 105
+#define MX28_INT_RESV106 106
+#define MX28_INT_RESV107 107
+#define MX28_INT_RESV108 108
+#define MX28_INT_RESV109 109
+#define MX28_INT_I2C1_ERROR 110
+#define MX28_INT_I2C0_ERROR 111
+#define MX28_INT_AUART0 112
+#define MX28_INT_AUART1 113
+#define MX28_INT_AUART2 114
+#define MX28_INT_AUART3 115
+#define MX28_INT_AUART4 116
+#define MX28_INT_RESV117 117
+#define MX28_INT_RESV118 118
+#define MX28_INT_RESV119 119
+#define MX28_INT_RESV120 120
+#define MX28_INT_RESV121 121
+#define MX28_INT_RESV122 122
+#define MX28_INT_GPIO4 123
+#define MX28_INT_GPIO3 124
+#define MX28_INT_GPIO2 125
+#define MX28_INT_GPIO1 126
+#define MX28_INT_GPIO0 127
+#define MX28_INT_FEC MX28_INT_ENET_MAC0
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 3432b78..563901f 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -30,6 +30,7 @@
#define MXC_CPU_MX21 21
#define MXC_CPU_MX25 25
#define MXC_CPU_MX27 27
+#define MXC_CPU_MX28 28
#define MXC_CPU_MX31 31
#define MXC_CPU_MX35 35
#define MXC_CPU_MX51 51
@@ -87,6 +88,18 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mx27() (0)
#endif
+#ifdef CONFIG_ARCH_MX28
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX28
+# endif
+# define cpu_is_mx28() (mxc_cpu_type == MXC_CPU_MX28)
+#else
+# define cpu_is_mx28() (0)
+#endif
+
#ifdef CONFIG_ARCH_MX31
# ifdef mxc_cpu_type
# undef mxc_cpu_type
@@ -161,5 +174,6 @@ extern void __iomem *mxc_irq_base;
#define MXC_IRQ_TYPE_AVIC 1
#define MXC_IRQ_TYPE_TZIC 2
+#define MXC_IRQ_TYPE_ICOLL 3
#endif /* __ASM_ARCH_MXC_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:33 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
` (9 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
MX28 uses Interrupt Collector (ICOLL) as the interrupt
controller. So ICOLL becomes the third interrupt controller
for MXC besides AVIC and TZIC.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/icoll.c | 79 ++++++++++++++++++++++++++
arch/arm/plat-mxc/include/mach/entry-macro.S | 22 ++++++-
2 files changed, 97 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/plat-mxc/icoll.c
diff --git a/arch/arm/plat-mxc/icoll.c b/arch/arm/plat-mxc/icoll.c
new file mode 100644
index 0000000..e9a9e42
--- /dev/null
+++ b/arch/arm/plat-mxc/icoll.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009-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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR 0x0000
+#define HW_ICOLL_LEVELACK 0x0010
+#define HW_ICOLL_CTRL 0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
+
+void __iomem *icoll_base;
+
+static void icoll_ack_irq(unsigned int irq)
+{
+ __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
+
+ /* ACK current interrupt (level 0) */
+ __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+ icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxc_icoll_chip = {
+ .ack = icoll_ack_irq,
+ .mask = icoll_mask_irq,
+ .unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void __iomem *irqbase)
+{
+ int i;
+
+ icoll_base = irqbase;
+ mxc_irq_base = irqbase;
+ mxc_irq_controller_type = MXC_IRQ_TYPE_ICOLL;
+
+ /* Reset icoll */
+ mxc_reset_block(irqbase + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxc_icoll_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index a7dd008..a66e804 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -73,25 +73,39 @@
#endif
.endm
+ .macro icoll_get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x70]
+ cmp \irqnr, #0x7F
+ moveqs \irqnr, #0
+ .endm
+
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC
+#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC && defined CONFIG_MXC_ICOLL
ldr \tmp, =mxc_irq_controller_type
ldr \tmp, [\tmp]
cmp \tmp, #MXC_IRQ_TYPE_AVIC
beq 3001f
+ cmp \tmp, #MXC_IRQ_TYPE_ICOLL
+ beq 3002f
tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
- b 3002f
+ b 3003f
3001:
avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+ b 3003f
3002:
+ icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+ b 3003f
+3003:
#elif defined CONFIG_MXC_TZIC
tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
#elif defined CONFIG_MXC_AVIC
avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#elif defined CONFIG_MXC_ICOLL
+ icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
#else
-#error no tzic and no avic?
+#error none of tzic, avic, icoll?
#endif
.endm
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:36 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
` (8 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
1. The wdog reset is implemented in RTC block on MX28.
2. Implement the common reset routine for most blocks on MX28,
so that the blocks can call it to get a software reset.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/system.c | 104 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index c3972c5..257b426 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel at pengutronix.de
* Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
*
@@ -36,6 +36,7 @@ static void __iomem *wdog_base;
void arch_reset(char mode, const char *cmd)
{
unsigned int wcr_enable;
+ struct clk *clk;
#ifdef CONFIG_ARCH_MXC91231
if (cpu_is_mxc91231()) {
@@ -52,9 +53,18 @@ void arch_reset(char mode, const char *cmd)
if (cpu_is_mx1()) {
wcr_enable = (1 << 0);
- } else {
- struct clk *clk;
+ } else if (cpu_is_mx28()) {
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+ /* set wdog count */
+ __raw_writel(1, wdog_base + 0x50);
+ /* wdog enbable bit */
+ wcr_enable = (1 << 4);
+ /* shift to SET address */
+ wdog_base += 0x4;
+ } else {
clk = clk_get_sys("imx-wdt.0", NULL);
if (!IS_ERR(clk))
clk_enable(clk);
@@ -80,3 +90,91 @@ void mxc_arch_reset_init(void __iomem *base)
{
wdog_base = base;
}
+
+#ifdef CONFIG_ARCH_MX28
+int mxc_reset_block(void __iomem *reg_addr)
+{
+ u32 reg;
+ int timeout;
+
+ /*
+ * The process of software reset of IP block is done
+ * in several steps:
+ *
+ * 1) clear SFTRST and wait it cleared;
+ * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
+ * 3) clear SFTRST and wait it cleared;
+ * 4) clear CLKGATE and wait it cleared.
+ */
+
+ /* Clear SFTRST */
+ reg = __raw_readl(reg_addr);
+ reg &= ~(1 << 31);
+ __raw_writel(reg, reg_addr);
+ /* Wait SFTRST cleared */
+ timeout = 1000;
+ do {
+ mdelay(1);
+ if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
+ break;
+ } while (--timeout > 0);
+ if (timeout <= 0) {
+ pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
+ return -ETIMEDOUT;
+ }
+
+ /* Clear CLKGATE */
+ reg = __raw_readl(reg_addr);
+ reg &= ~(1 << 30);
+ __raw_writel(reg, reg_addr);
+ /* Set SFTRST to reset the block */
+ reg = __raw_readl(reg_addr);
+ reg |= (1 << 31);
+ __raw_writel(reg, reg_addr);
+ /* Poll CLKGATE set */
+ timeout = 1000;
+ do {
+ mdelay(1);
+ if (__raw_readl(reg_addr) & (1 << 30))
+ break;
+ } while (--timeout > 0);
+ if (timeout <= 0) {
+ pr_err("%s(%p): poll CLKGATE timeout\n", __func__, reg_addr);
+ return -ETIMEDOUT;
+ }
+
+ /* Clear SFTRST */
+ reg = __raw_readl(reg_addr);
+ reg &= ~(1 << 31);
+ __raw_writel(reg, reg_addr);
+ /* Wait SFTRST cleared */
+ timeout = 1000;
+ do {
+ mdelay(1);
+ if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
+ break;
+ } while (--timeout > 0);
+ if (timeout <= 0) {
+ pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
+ return -ETIMEDOUT;
+ }
+
+ /* Clear CLKGATE */
+ reg = __raw_readl(reg_addr);
+ reg &= ~(1 << 30);
+ __raw_writel(reg, reg_addr);
+ /* Wait CLKGATE cleared */
+ timeout = 1000;
+ do {
+ mdelay(1);
+ if ((__raw_readl(reg_addr) & (1 << 30)) == 0)
+ break;
+ } while (--timeout > 0);
+ if (timeout <= 0) {
+ pr_err("%s(%p): clear CLKGATE timeout\n", __func__, reg_addr);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 04/11] ARM: imx: Add timer support for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (2 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:40 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
` (7 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
SoC i.MX28 implements the timer in block TIMROT. It adds the
support in the same file with GPT, and uses timer_is_timrot()
to distinguish the IP block.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/time.c | 120 ++++++++++++++++++++++++++++++++++++++--------
1 files changed, 100 insertions(+), 20 deletions(-)
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index f9a1b05..3e1f09d 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -5,6 +5,7 @@
* Copyright (C) 2002 Shane Nay (shane at minirl.com)
* Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
* Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ * 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
@@ -63,8 +64,22 @@
#define V2_TCN 0x24
#define V2_TCMP 0x10
-#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
-#define timer_is_v2() (!timer_is_v1())
+/* TIMROT */
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRL0 0x20
+#define HW_TIMROT_TIMCTRL0_SET 0x24
+#define HW_TIMROT_TIMCTRL0_CLR 0x28
+#define HW_TIMROT_RUNNING_COUNT0 0x30
+#define HW_TIMROT_MATCH_COUNT0 0x50
+#define BM_TIMROT_TIMCTRL0_IRQ_EN 0x00004000
+#define BM_TIMROT_TIMCTRL0_IRQ 0x00008000
+#define BM_TIMROT_TIMCTRL0_MATCH_MODE 0x00000800
+#define BP_TIMROT_TIMCTRL0_SELECT 0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+
+#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#define timer_is_v2() (!timer_is_v1())
+#define timer_is_timrot() (cpu_is_mx28())
static struct clock_event_device clockevent_mxc;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
@@ -105,6 +120,24 @@ static void gpt_irq_acknowledge(void)
__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
}
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRL0_CLR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRL0_SET);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRL0_IRQ,
+ timer_base + HW_TIMROT_TIMCTRL0_CLR);
+}
+
static cycle_t mx1_2_get_cycles(struct clocksource *cs)
{
return __raw_readl(timer_base + MX1_2_TCN);
@@ -115,6 +148,11 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
return __raw_readl(timer_base + V2_TCN);
}
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+ return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNT0);
+}
+
static struct clocksource clocksource_mxc = {
.name = "mxc_timer1",
.rating = 200,
@@ -128,8 +166,12 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
- if (timer_is_v2())
+ if (timer_is_timrot()) {
+ clocksource_mxc.read = timrot_get_cycles;
+ clocksource_mxc.shift = 10;
+ } else if (timer_is_v2()) {
clocksource_mxc.read = v2_get_cycles;
+ }
clocksource_mxc.mult = clocksource_hz2mult(c,
clocksource_mxc.shift);
@@ -166,6 +208,18 @@ static int v2_set_next_event(unsigned long evt,
-ETIME : 0;
}
+static int timrot_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ unsigned long match;
+
+ match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNT0) - evt;
+ __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNT0);
+
+ return (int)(match - __raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNT0)) > 0 ? -ETIME : 0;
+}
+
#ifdef DEBUG
static const char *clock_event_mode_label[] = {
[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
@@ -186,12 +240,19 @@ static void mxc_set_mode(enum clock_event_mode mode,
*/
local_irq_save(flags);
- /* Disable interrupt in GPT module */
- gpt_irq_disable();
+ /* Disable interrupt in timer module */
+ if (timer_is_timrot())
+ timrot_irq_disable();
+ else
+ gpt_irq_disable();
if (mode != clockevent_mode) {
/* Set event time into far-far future */
- if (timer_is_v2())
+ if (timer_is_timrot())
+ __raw_writel(__raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNT0) + 3,
+ timer_base + HW_TIMROT_MATCH_COUNT0);
+ else if (timer_is_v2())
__raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
timer_base + V2_TCMP);
else
@@ -199,7 +260,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
timer_base + MX1_2_TCMP);
/* Clear pending interrupt */
- gpt_irq_acknowledge();
+ if (timer_is_timrot())
+ timrot_irq_acknowledge();
+ else
+ gpt_irq_acknowledge();
}
#ifdef DEBUG
@@ -225,7 +289,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
* mode switching
*/
local_irq_save(flags);
- gpt_irq_enable();
+ if (timer_is_timrot())
+ timrot_irq_enable();
+ else
+ gpt_irq_enable();
local_irq_restore(flags);
break;
case CLOCK_EVT_MODE_SHUTDOWN:
@@ -249,7 +316,10 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
else
tstat = __raw_readl(timer_base + MX1_2_TSTAT);
- gpt_irq_acknowledge();
+ if (timer_is_timrot())
+ timrot_irq_acknowledge();
+ else
+ gpt_irq_acknowledge();
evt->event_handler(evt);
@@ -275,7 +345,9 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
- if (timer_is_v2())
+ if (timer_is_timrot())
+ clockevent_mxc.set_next_event = timrot_set_next_event;
+ else if (timer_is_v2())
clockevent_mxc.set_next_event = v2_set_next_event;
clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -303,16 +375,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
/*
* Initialise to a known state (all timers off, and timing reset)
*/
-
- __raw_writel(0, timer_base + MXC_TCTL);
- __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
-
- if (timer_is_v2())
- tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
- else
- tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
-
- __raw_writel(tctl_val, timer_base + MXC_TCTL);
+ if (timer_is_timrot()) {
+ mxc_reset_block(base + HW_TIMROT_ROTCTRL);
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRL0_IRQ_EN |
+ BM_TIMROT_TIMCTRL0_MATCH_MODE,
+ timer_base + HW_TIMROT_TIMCTRL0); /* timer0*/
+ } else {
+ __raw_writel(0, timer_base + MXC_TCTL);
+ __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
+ if (timer_is_v2())
+ tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR |
+ V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ else
+ tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 |
+ MXC_TCTL_TEN;
+ __raw_writel(tctl_val, timer_base + MXC_TCTL);
+ }
/* init and register the timer to the framework */
mxc_clocksource_init(timer_clk);
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 05/11] ARM: imx: Add GPIO support for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (3 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:43 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
` (6 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
SoC i.MX28 implements GPIO functions in block PINCTRL. It adds
the support in the same file used by other i.MX SoCs, and uses
cpu_is_mx28() to distinguish the PINCTRL from GPIO used by other
i.MX SoCs.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/gpio.c | 186 +++++++++++++++++++++++++++++++++++++--------
1 files changed, 153 insertions(+), 33 deletions(-)
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 9c3e362..f0d94af 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -30,6 +30,17 @@
static struct mxc_gpio_port *mxc_gpio_ports;
static int gpio_table_size;
+/* PINCTRL */
+#define GPIO_PORT_ID(p) (((void *)p - (void *)mxc_gpio_ports) / sizeof(p))
+#define GPIO_DOUT(p) (0x0700 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_DIN(p) (0x0900 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_DOE(p) (0x0b00 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_PIN2IRQ(p) (0x1000 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_IRQEN(p) (0x1100 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_LEV(p) (0x1200 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_POL(p) (0x1300 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_IRQSTAT(p) (0x1400 + GPIO_PORT_ID(p) * 0x10)
+
#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
#define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00)
@@ -40,17 +51,25 @@ static int gpio_table_size;
#define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14)
#define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
-#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
-#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1)
-#define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2)
-#define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3)
+#define GPIO_INT_LOW_LEV \
+ (cpu_is_mx28() ? 0x1 : (cpu_is_mx1_mx2() ? 0x3 : 0x0))
+#define GPIO_INT_HIGH_LEV \
+ (cpu_is_mx28() ? 0x3 : (cpu_is_mx1_mx2() ? 0x2 : 0x1))
+#define GPIO_INT_RISE_EDGE \
+ (cpu_is_mx1_mx2() ? 0x0 : 0x2)
+#define GPIO_INT_FALL_EDGE \
+ (cpu_is_mx28() ? 0x0 : (cpu_is_mx1_mx2() ? 0x1 : 0x3))
#define GPIO_INT_NONE 0x4
/* Note: This driver assumes 32 GPIOs are handled in one register */
static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
{
- __raw_writel(1 << index, port->base + GPIO_ISR);
+ if (cpu_is_mx28())
+ __raw_writel(1 << index,
+ port->base + GPIO_IRQSTAT(port) + CLR_ADDR);
+ else
+ __raw_writel(1 << index, port->base + GPIO_ISR);
}
static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
@@ -58,9 +77,23 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
{
u32 l;
- l = __raw_readl(port->base + GPIO_IMR);
- l = (l & (~(1 << index))) | (!!enable << index);
- __raw_writel(l, port->base + GPIO_IMR);
+ if (cpu_is_mx28()) {
+ if (enable == 0) {
+ __raw_writel(1 << index,
+ port->base + GPIO_PIN2IRQ(port) + CLR_ADDR);
+ __raw_writel(1 << index,
+ port->base + GPIO_IRQEN(port) + CLR_ADDR);
+ } else {
+ __raw_writel(1 << index,
+ port->base + GPIO_PIN2IRQ(port) + SET_ADDR);
+ __raw_writel(1 << index,
+ port->base + GPIO_IRQEN(port) + SET_ADDR);
+ }
+ } else {
+ l = __raw_readl(port->base + GPIO_IMR);
+ l = (l & (~(1 << index))) | (!!enable << index);
+ __raw_writel(l, port->base + GPIO_IMR);
+ }
}
static void gpio_ack_irq(u32 irq)
@@ -120,10 +153,28 @@ static int gpio_set_irq_type(u32 irq, u32 type)
return -EINVAL;
}
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = __raw_readl(reg) & ~(0x3 << (bit << 1));
- __raw_writel(val | (edge << (bit << 1)), reg);
+ if (cpu_is_mx28()) {
+ /* set level or edge */
+ if (edge & 0x1)
+ __raw_writel(1 << (gpio & 31),
+ port->base + GPIO_LEV(port) + SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + GPIO_LEV(port) + CLR_ADDR);
+ /* set polarity */
+ if ((edge >> 1) & 0x1)
+ __raw_writel(1 << (gpio & 31),
+ port->base + GPIO_POL(port) + SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + GPIO_POL(port) + CLR_ADDR);
+ } else {
+ reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
+ bit = gpio & 0xf;
+ val = __raw_readl(reg) & ~(0x3 << (bit << 1));
+ __raw_writel(val | (edge << (bit << 1)), reg);
+ }
+
_clear_gpio_irqstatus(port, gpio & 0x1f);
return 0;
@@ -135,23 +186,36 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
u32 bit, val;
int edge;
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = __raw_readl(reg);
- edge = (val >> (bit << 1)) & 3;
- val &= ~(0x3 << (bit << 1));
- if (edge == GPIO_INT_HIGH_LEV) {
- edge = GPIO_INT_LOW_LEV;
- pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
- } else if (edge == GPIO_INT_LOW_LEV) {
- edge = GPIO_INT_HIGH_LEV;
- pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+ if (cpu_is_mx28()) {
+ edge = 1 << (gpio & 31);
+ val = __raw_readl(port->base + GPIO_LEV(port));
+ if (val & edge) {
+ /* level is invalid for this function */
+ pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+ gpio, edge);
+ return;
+ }
+ __raw_writel(1 << (gpio & 31),
+ port->base + GPIO_POL(port) + TOG_ADDR);
} else {
- pr_err("mxc: invalid configuration for GPIO %d: %x\n",
- gpio, edge);
- return;
+ reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
+ bit = gpio & 0xf;
+ val = __raw_readl(reg);
+ edge = (val >> (bit << 1)) & 3;
+ val &= ~(0x3 << (bit << 1));
+ if (edge == GPIO_INT_HIGH_LEV) {
+ edge = GPIO_INT_LOW_LEV;
+ pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
+ } else if (edge == GPIO_INT_LOW_LEV) {
+ edge = GPIO_INT_HIGH_LEV;
+ pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+ } else {
+ pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+ gpio, edge);
+ return;
+ }
+ __raw_writel(val | (edge << (bit << 1)), reg);
}
- __raw_writel(val | (edge << (bit << 1)), reg);
}
/* handle 32 interrupts in one status register */
@@ -183,6 +247,29 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
mxc_gpio_irq_handler(port, irq_stat);
}
+/* MX28 has one interrupt *per* gpio port */
+static void mx28_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ irq_stat = __raw_readl(port->base + GPIO_IRQSTAT(port)) &
+ __raw_readl(port->base + GPIO_IRQEN(port)) &
+ __raw_readl(port->base + GPIO_PIN2IRQ(port));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+
+ if (port->both_edges & (1 << irqoffset))
+ mxc_flip_edge(port, irqoffset);
+
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
/* MX2 has one interrupt *for all* gpio ports */
static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
@@ -247,14 +334,20 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
container_of(chip, struct mxc_gpio_port, chip);
u32 l;
unsigned long flags;
+ void __iomem *reg;
+
+ if (cpu_is_mx28())
+ reg = port->base + GPIO_DOE(port);
+ else
+ reg = port->base + GPIO_GDIR;
spin_lock_irqsave(&port->lock, flags);
- l = __raw_readl(port->base + GPIO_GDIR);
+ l = __raw_readl(reg);
if (dir)
l |= 1 << offset;
else
l &= ~(1 << offset);
- __raw_writel(l, port->base + GPIO_GDIR);
+ __raw_writel(l, reg);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -262,9 +355,14 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
struct mxc_gpio_port *port =
container_of(chip, struct mxc_gpio_port, chip);
- void __iomem *reg = port->base + GPIO_DR;
u32 l;
unsigned long flags;
+ void __iomem *reg;
+
+ if (cpu_is_mx28())
+ reg = port->base + GPIO_DOUT(port);
+ else
+ reg = port->base + GPIO_DR;
spin_lock_irqsave(&port->lock, flags);
l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
@@ -276,8 +374,14 @@ static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
{
struct mxc_gpio_port *port =
container_of(chip, struct mxc_gpio_port, chip);
+ void __iomem *reg;
+
+ if (cpu_is_mx28())
+ reg = port->base + GPIO_DIN(port);
+ else
+ reg = port->base + GPIO_PSR;
- return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
+ return (__raw_readl(reg) >> offset) & 1;
}
static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -306,8 +410,19 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
for (i = 0; i < cnt; i++) {
/* disable the interrupt and clear the status */
- __raw_writel(0, port[i].base + GPIO_IMR);
- __raw_writel(~0, port[i].base + GPIO_ISR);
+ if (cpu_is_mx28()) {
+ __raw_writel(0, port[i].base +
+ GPIO_PIN2IRQ(&port[i]));
+ __raw_writel(0, port[i].base +
+ GPIO_IRQEN(&port[i]));
+ __raw_writel(~0, port[i].base +
+ GPIO_IRQSTAT(&port[i]) +
+ CLR_ADDR);
+ } else {
+ __raw_writel(0, port[i].base + GPIO_IMR);
+ __raw_writel(~0, port[i].base + GPIO_ISR);
+ }
+
for (j = port[i].virtual_irq_start;
j < port[i].virtual_irq_start + 32; j++) {
set_irq_chip(j, &gpio_irq_chip);
@@ -338,6 +453,11 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
mx3_gpio_irq_handler);
set_irq_data(port[i].irq_high, &port[i]);
}
+ } else if (cpu_is_mx28()) {
+ /* setup one handler for each entry */
+ set_irq_chained_handler(port[i].irq,
+ mx28_gpio_irq_handler);
+ set_irq_data(port[i].irq, &port[i]);
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 06/11] ARM: imx: Add IOMUX support for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (4 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:46 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
` (5 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
Soc i.MX28 supports IOMUX function in block PINCTRL. Comparing
to the naming of iomux-v1 and iomux-v3, it uses iomux-pinctrl,
since PINCTRL is a totally different IP block from IOMUX and it's
not reasonable to name it iomux-v2 or iomux-v4, which is used to
distinguish the different revision of same IP block.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/include/mach/iomux-mx28.h | 50 +++++++++++++
arch/arm/plat-mxc/include/mach/iomux-pinctrl.h | 91 +++++++++++++++++++++++
arch/arm/plat-mxc/iomux-pinctrl.c | 94 ++++++++++++++++++++++++
3 files changed, 235 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx28.h
create mode 100644 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
create mode 100644 arch/arm/plat-mxc/iomux-pinctrl.c
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx28.h b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..8c68bd6
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009-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 __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux-pinctrl.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux-pinctrl.h
+ *
+ * BANK PIN MUX VOL MA PULL
+ */
+/* DUART */
+#define MX28_PAD_PWM0__DUART_RX IOMUX_PAD(3, 16, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX IOMUX_PAD(3, 17, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC IOMUX_PAD(4, 0, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+#define MX28_PAD_ENET_CLK__ENET_CLK IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15 IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
new file mode 100644
index 0000000..c2fdb33
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ * 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 __MACH_IOMUX_PINCTRL_H__
+#define __MACH_IOMUX_PINCTRL_H__
+
+typedef struct deprecated_pad_desc {
+ unsigned bank:3;
+ unsigned pin:5;
+ unsigned muxsel:2;
+ unsigned ma:3;
+ unsigned vol:2;
+ unsigned pull:1;
+} iomux_pinctrl_cfg_t;
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull) \
+ { \
+ .bank = _bank, \
+ .pin = _pin, \
+ .muxsel = _muxsel, \
+ .vol = _vol, \
+ .ma = _ma, \
+ .pull = _pull, \
+ }
+
+#define PAD_MUXSEL_0 0
+#define PAD_MUXSEL_1 1
+#define PAD_MUXSEL_2 2
+#define PAD_MUXSEL_GPIO 3
+
+#define PAD_1V8 0
+#define PAD_3V3 1
+#define PAD_VOL_NONE 2
+
+#define PAD_4MA 0
+#define PAD_8MA 1
+#define PAD_12MA 2
+#define PAD_16MA 3
+#define PAD_MA_NONE 4
+
+#define PAD_NOPULL 0
+#define PAD_PULL 1
+
+#define MX51_NUM_GPIO_PORT 4
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad);
+
+/*
+ * setups mutliple pads
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base);
+
+#endif /* __MACH_IOMUX_PINCTRL_H__*/
diff --git a/arch/arm/plat-mxc/iomux-pinctrl.c b/arch/arm/plat-mxc/iomux-pinctrl.c
new file mode 100644
index 0000000..5f5b5ac
--- /dev/null
+++ b/arch/arm/plat-mxc/iomux-pinctrl.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * 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 <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/iomux-pinctrl.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad)
+{
+ u32 reg, ofs, bp, bm;
+
+ /* MUXSEL */
+ ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
+ bp = pad->pin % 16 * 2;
+ bm = 0x3 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->muxsel << bp;
+ __raw_writel(reg, base + ofs);
+
+ /* DRIVE */
+ if (pad->ma != PAD_MA_NONE && pad->vol != PAD_VOL_NONE)
+ {
+ ofs = 0x300 + pad->bank * 0x40 + pad->pin / 8 * 0x10;
+ bp = pad->pin % 8 * 4;
+ bm = 0x7 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->ma << bp | pad->vol << (bp + 2);
+ __raw_writel(reg, base + ofs);
+ }
+
+ /* PULL */
+ ofs = 0x600 + pad->bank * 0x10;
+ bp = pad->pin;
+ bm = 0x1 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->pull << bp;
+ __raw_writel(reg, base + ofs);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_pad);
+
+int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count)
+{
+ iomux_pinctrl_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxc_iomux_pinctrl_setup_pad(p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_multiple_pads);
+
+void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base)
+{
+ base = iomux_pinctrl_base;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 07/11] ARM: imx: Add support of uncompress print for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (5 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:47 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
` (4 subsequent siblings)
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
SoC i.MX28 uses DUART IP block as the debug serial. It adds the
support in the same file used by other i.MX SoC UART, and uses
variable is_duart to distinguish.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/plat-mxc/include/mach/uncompress.h | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index 9dd9c20..adb617f 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -1,8 +1,9 @@
/*
- * arch/arm/plat-mxc/include/mach/uncompress.h
+ * rch/arm/plat-mxc/include/mach/uncompress.h
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) Shane Nay (shane at minirl.com)
+ * Copyright 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
@@ -22,14 +23,16 @@
#include <asm/mach-types.h>
static unsigned long uart_base;
+static unsigned short is_duart = 0;
#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
-#define USR2 0x98
-#define USR2_TXFE (1<<14)
-#define TXR 0x40
-#define UCR1 0x80
-#define UCR1_UARTEN 1
+#define USR2 (is_duart ? 0x18 : 0x98)
+#define USR2_TXFE (is_duart ? 1<<7 : 1<<14)
+#define USR2_BUSY (1 << 3)
+#define TXR (is_duart ? 0x00 : 0x40)
+#define UCR1 (is_duart ? 0x30 : 0x80)
+#define UCR1_UARTEN 1
/*
* The following code assumes the serial port has already been
@@ -59,6 +62,7 @@ static inline void flush(void)
#define MX1_UART1_BASE_ADDR 0x00206000
#define MX25_UART1_BASE_ADDR 0x43f90000
+#define MX28_DUART_BASE_ADDR 0x80074000
#define MX2X_UART1_BASE_ADDR 0x1000a000
#define MX3X_UART1_BASE_ADDR 0x43F90000
#define MX3X_UART2_BASE_ADDR 0x43F94000
@@ -83,6 +87,10 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
case MACH_TYPE_MXT_TD60:
uart_base = MX2X_UART1_BASE_ADDR;
break;
+ case MACH_TYPE_MX28EVK:
+ uart_base = MX28_DUART_BASE_ADDR;
+ is_duart = 1;
+ break;
case MACH_TYPE_MX31LITE:
case MACH_TYPE_ARMADILLO5X0:
case MACH_TYPE_MX31MOBOARD:
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 08/11] ARM: imx: Add clock support for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (6 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
` (3 subsequent siblings)
11 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-imx/clock-imx28.c | 733 +++++++++++++++++++++++++++++++++
arch/arm/mach-imx/regs-clkctrl-mx28.h | 662 +++++++++++++++++++++++++++++
2 files changed, 1395 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-imx/clock-imx28.c
create mode 100644 arch/arm/mach-imx/regs-clkctrl-mx28.h
diff --git a/arch/arm/mach-imx/clock-imx28.c b/arch/arm/mach-imx/clock-imx28.c
new file mode 100644
index 0000000..104f95e
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx28.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2009-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.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ }
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+ return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+ .get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+ return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g) \
+static int name##_enable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ udelay(10); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ \
+ return 0; \
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g) \
+static void name##_disable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name) \
+ static struct clk name = { \
+ .get_rate = name##_get_rate, \
+ .enable = name##_enable, \
+ .disable = name##_disable, \
+ .parent = &ref_xtal_clk, \
+ }
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ unsigned long parent_rate; \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
+ div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
+ parent_rate = clk_get_rate(clk->parent); \
+ \
+ return parent_rate * 18 / div; \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
+ .get_rate = name##_get_rate, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = &pll0_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+ /* ref_xtal_clk is implemented as the only parent */
+ return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+ return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ if (clk->parent == &ref_xtal_clk) \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
+ BP_CLKCTRL_##rs##_DIV_XTAL; \
+ else \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
+ BP_CLKCTRL_##rs##_DIV_##rs; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ if (clk == &saif0_clk || clk == &saif1_clk) \
+ return (clk_get_rate(clk->parent) >> 16 * div); \
+ else \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+_CLK_GET_RATE1(fec_clk, ENET)
+
+#define _CLK_GET_RATE_STUB(name) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ return clk_get_rate(clk->parent); \
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV 0
+#define BP_CLKCTRL_CPU_DIV 0
+#define BM_CLKCTRL_CPU_BUSY 0
+
+#define _CLK_SET_RATE(name, dr, fr, fs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, bm_busy, div_max, d, f, div, frac; \
+ unsigned long diff, parent_rate, calc_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ bm_busy = BM_CLKCTRL_##dr##_BUSY; \
+ \
+ if (clk->parent == &ref_xtal_clk) { \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
+ BP_CLKCTRL_CPU_DIV_XTAL; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
+ } \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ } else { \
+ div = frac = 1; \
+ diff = parent_rate; \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
+ BP_CLKCTRL_CPU_DIV_CPU; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
+ } \
+ for (d = 1; d <= div_max; d++) { \
+ f = parent_rate * 18 / d / rate; \
+ if ((parent_rate * 18 / d) % rate) \
+ f++; \
+ if (f < 18 || f > 35) \
+ continue; \
+ \
+ calc_rate = parent_rate * 18 / f / d; \
+ if (calc_rate > rate) \
+ continue; \
+ \
+ if (rate - calc_rate < diff) { \
+ frac = f; \
+ div = d; \
+ diff = rate - calc_rate; \
+ } \
+ \
+ if (diff == 0) \
+ break; \
+ } \
+ \
+ if (diff == parent_rate) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
+ reg |= frac; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ } \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ if (clk == &cpu_clk) { \
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
+ } else { \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg | (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & bm_busy)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div_max, div; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg | (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+_CLK_SET_RATE1(fec_clk, ENET)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u16 div; \
+ u32 reg; \
+ u64 lrate; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ if (rate > parent_rate) \
+ return -EINVAL; \
+ \
+ lrate = (u64)rate << 16; \
+ do_div(lrate, parent_rate); \
+ div = (u16)lrate; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ reg &= ~BM_CLKCTRL_##rs##_DIV; \
+ reg |= div << BP_CLKCTRL_##rs##_DIV; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ return -EINVAL; \
+}
+
+_CLK_SET_RATE_STUB(emi_clk)
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) { \
+ __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
+ HW_CLKCTRL_CLKSEQ_TOG); \
+ clk->parent = parent; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) \
+ return -EINVAL; \
+ else \
+ return 0; \
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+ .get_rate = cpu_clk_get_rate,
+ .set_rate = cpu_clk_set_rate,
+ .set_parent = cpu_clk_set_parent,
+ .parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+ .get_rate = hbus_clk_get_rate,
+ .parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+ .get_rate = xbus_clk_get_rate,
+ .set_rate = xbus_clk_set_rate,
+ .parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+ .get_rate = lradc_clk_get_rate,
+ .parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 16,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_##es, \
+ .get_rate = name##_get_rate, \
+ .set_rate = name##_set_rate, \
+ .set_parent = name##_set_parent, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = p, \
+ }
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+/* fec 1588 clock */
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &pll0_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("imx-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+
+ _REGISTER_CLOCK("hclk", NULL, hbus_clk)
+ _REGISTER_CLOCK("xclk", NULL, xbus_clk)
+ _REGISTER_CLOCK("can.0", NULL, can0_clk)
+ _REGISTER_CLOCK("can.1", NULL, can1_clk)
+ _REGISTER_CLOCK("usb.0", NULL, usb0_clk)
+ _REGISTER_CLOCK("usb.1", NULL, usb1_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("pwm", NULL, pwm_clk)
+ _REGISTER_CLOCK("lradc", NULL, lradc_clk)
+ _REGISTER_CLOCK("spdif", NULL, spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+ u32 reg;
+ int i;
+
+ /* Fix up parent per register setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+ cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+ &ref_xtal_clk : &ref_cpu_clk;
+ emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+ &ref_xtal_clk : &ref_emi_clk;
+ ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+ &ref_xtal_clk : &ref_pix_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_gpmi_clk;
+ saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+ &ref_xtal_clk : &pll0_clk;
+ saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+ &ref_xtal_clk : &pll0_clk;
+
+ /* Use int div over frac when both are available */
+ __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+ reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+ reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+ reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+ reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+ reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+ reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+ reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+ /* SAIF has to use frac div for functional operation */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+ reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+ reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+ /*
+ * Set safe hbus clock divider. A divider of 3 ensure that
+ * the Vddd voltage required for the cpu clock is sufficiently
+ * high for the hbus clock.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+ reg &= BM_CLKCTRL_HBUS_DIV;
+ reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Gate off cpu clock in WFI for power saving */
+ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+ /* Extra fec clock setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+ reg &= ~BM_CLKCTRL_ENET_SLEEP;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+ reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+ return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxc_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+ MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/regs-clkctrl-mx28.h b/arch/arm/mach-imx/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..e2d84a8
--- /dev/null
+++ b/arch/arm/mach-imx/regs-clkctrl-mx28.h
@@ -0,0 +1,662 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008-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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___CLKCTRL_IMX28_H
+#define __ARCH_ARM___CLKCTRL_IMX28_H
+
+#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1 0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6 0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1 0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3 0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2 0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1 0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU (0x00000050)
+#define HW_CLKCTRL_CPU_SET (0x00000054)
+#define HW_CLKCTRL_CPU_CLR (0x00000058)
+#define HW_CLKCTRL_CPU_TOG (0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5 30
+#define BM_CLKCTRL_CPU_RSRVD5 0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+ (((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4 0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3 13
+#define BM_CLKCTRL_CPU_RSRVD3 0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v) \
+ (((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2 0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1 6
+#define BM_CLKCTRL_CPU_RSRVD1 0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS (0x00000060)
+#define HW_CLKCTRL_HBUS_SET (0x00000064)
+#define HW_CLKCTRL_HBUS_CLR (0x00000068)
+#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2 0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1 6
+#define BM_CLKCTRL_HBUS_RSRVD1 0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS (0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 12
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL (0x00000080)
+#define HW_CLKCTRL_XTAL_SET (0x00000084)
+#define HW_CLKCTRL_XTAL_CLR (0x00000088)
+#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2 27
+#define BM_CLKCTRL_XTAL_RSRVD2 0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v) \
+ (((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1 2
+#define BM_CLKCTRL_XTAL_RSRVD1 0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v) \
+ (((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0 (0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE 31
+#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP0_BUSY 0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1 10
+#define BM_CLKCTRL_SSP0_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP0_DIV 0
+#define BM_CLKCTRL_SSP0_DIV 0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1 (0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE 31
+#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP1_BUSY 0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1 10
+#define BM_CLKCTRL_SSP1_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP1_DIV 0
+#define BM_CLKCTRL_SSP1_DIV 0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2 (0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE 31
+#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP2_BUSY 0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1 10
+#define BM_CLKCTRL_SSP2_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP2_DIV 0
+#define BM_CLKCTRL_SSP2_DIV 0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3 (0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE 31
+#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP3_BUSY 0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1 10
+#define BM_CLKCTRL_SSP3_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP3_DIV 0
+#define BM_CLKCTRL_SSP3_DIV 0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI (0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE 31
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2 0x40000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1 11
+#define BM_CLKCTRL_GPMI_RSRVD1 0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF (0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE 31
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD 0
+#define BM_CLKCTRL_SPDIF_RSRVD 0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI (0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE 31
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3 18
+#define BM_CLKCTRL_EMI_RSRVD3 0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v) \
+ (((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2 12
+#define BM_CLKCTRL_EMI_RSRVD2 0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v) \
+ (((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1 6
+#define BM_CLKCTRL_EMI_RSRVD1 0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v) \
+ (((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0 (0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE 31
+#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1 17
+#define BM_CLKCTRL_SAIF0_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF0_DIV 0
+#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1 (0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE 31
+#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1 17
+#define BM_CLKCTRL_SAIF1_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF1_DIV 0
+#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1 14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1 0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v) \
+ (((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV 0
+#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM (0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 8
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET (0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP 0x80000000
+#define BP_CLKCTRL_ENET_DISABLE 30
+#define BM_CLKCTRL_ENET_DISABLE 0x40000000
+#define BM_CLKCTRL_ENET_STATUS 0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1 0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME 21
+#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY 0x08000000
+#define BP_CLKCTRL_ENET_DIV 21
+#define BM_CLKCTRL_ENET_DIV 0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL 19
+#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v) \
+ (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0 0
+#define BM_CLKCTRL_ENET_RSRVD0 0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v) \
+ (((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC (0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2 0x80000000
+#define BM_CLKCTRL_HSADC_RESETB 0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV 28
+#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v) \
+ (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1 0
+#define BM_CLKCTRL_HSADC_RSRVD1 0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN (0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2 0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1 0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1 0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0 (0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC 24
+#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC 16
+#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC 8
+#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC 0
+#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2 24
+#define BM_CLKCTRL_FRAC1_RSRVD2 0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC 0
+#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ (0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0 19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+ (((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2 0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
+
+#define HW_CLKCTRL_RESET (0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD 6
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD 0
+#define BM_CLKCTRL_STATUS_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION (0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+#endif /* __ARCH_ARM___CLKCTRL_IMX28_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 09/11] ARM: imx: Add memory map support for i.MX28
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (7 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
` (2 subsequent siblings)
11 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-imx/mm-imx28.c | 50 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 50 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-imx/mm-imx28.c
diff --git a/arch/arm/mach-imx/mm-imx28.c b/arch/arm/mach-imx/mm-imx28.c
new file mode 100644
index 0000000..358f2d2
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx28.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008-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
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-pinctrl.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ imx_map_entry(MX28, OCRAM, MT_DEVICE),
+ imx_map_entry(MX28, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx28_map_io(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX28);
+ mxc_iomux_pinctrl_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+ mxc_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+int imx28_register_gpios(void);
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+ imx28_register_gpios();
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (8 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 16:54 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
It adds machine mx28evk with initial duart and fec
device registration.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-imx/devices-imx28.h | 20 ++++
arch/arm/mach-imx/devices.c | 27 ++++++-
arch/arm/mach-imx/mach-mx28evk.c | 109 +++++++++++++++++++++++
arch/arm/plat-mxc/devices/platform-duart.c | 42 +++++++++
arch/arm/plat-mxc/devices/platform-fec.c | 5 +
arch/arm/plat-mxc/include/mach/common.h | 5 +
arch/arm/plat-mxc/include/mach/devices-common.h | 11 +++
7 files changed, 218 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-imx/devices-imx28.h
create mode 100644 arch/arm/mach-imx/mach-mx28evk.c
create mode 100644 arch/arm/plat-mxc/devices/platform-duart.c
diff --git a/arch/arm/mach-imx/devices-imx28.h b/arch/arm/mach-imx/devices-imx28.h
new file mode 100644
index 0000000..f35c910
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx28.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_duart_data imx28_duart_data __initconst;
+#define imx28_add_duart() \
+ imx_add_duart(&imx28_duart_data)
+
+extern const struct imx_fec_data imx28_fec_data __initconst;
+#define imx28_add_fec(pdata) \
+ imx_add_fec(&imx28_fec_data, pdata)
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
index e69e46e..946db32 100644
--- a/arch/arm/mach-imx/devices.c
+++ b/arch/arm/mach-imx/devices.c
@@ -9,7 +9,7 @@
* licensed "as is" without any warranty of any kind, whether express
* or implied.
*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel at pengutronix.de
* Copyright 2008 Sascha Hauer, kernel at pengutronix.de
* Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
@@ -551,3 +551,28 @@ struct platform_device imx_kpp_device = {
};
#endif
+
+#ifdef CONFIG_ARCH_MX28
+/* gpio */
+#define DEFINE_MXC_PINCTRL_GPIO_PORT(n) \
+ { \
+ .chip.label = "gpio-" #n, \
+ .irq = MX28_INT_GPIO##n, \
+ .base = MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR), \
+ .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
+ }
+
+static struct mxc_gpio_port imx28_gpio_ports[] = {
+ DEFINE_MXC_PINCTRL_GPIO_PORT(0),
+ DEFINE_MXC_PINCTRL_GPIO_PORT(1),
+ DEFINE_MXC_PINCTRL_GPIO_PORT(2),
+ DEFINE_MXC_PINCTRL_GPIO_PORT(3),
+ DEFINE_MXC_PINCTRL_GPIO_PORT(4),
+};
+
+int __init imx28_register_gpios(void)
+{
+ return mxc_gpio_init(imx28_gpio_ports,
+ ARRAY_SIZE(imx28_gpio_ports));
+}
+#endif
diff --git a/arch/arm/mach-imx/mach-mx28evk.c b/arch/arm/mach-imx/mach-mx28evk.c
new file mode 100644
index 0000000..d5dd940
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx28evk.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-imx28.h"
+#include "devices.h"
+
+#define MX28EVK_FEC_PHY_POWER (2*32 + 15) /* GPIO_2_15 */
+#define MX28EVK_FEC_PHY_RESET (4*32 + 13) /* GPIO_4_13 */
+
+static iomux_pinctrl_cfg_t mx28evk_pads[] = {
+ /* DUART */
+ MX28_PAD_PWM0__DUART_RX,
+ MX28_PAD_PWM1__DUART_TX,
+
+ /* FEC */
+ MX28_PAD_ENET0_MDC__ENET0_MDC,
+ MX28_PAD_ENET0_MDIO__ENET0_MDIO,
+ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+ MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+ MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
+ MX28_PAD_ENET0_TXD0__ENET0_TXD0,
+ MX28_PAD_ENET0_TXD1__ENET0_TXD1,
+ MX28_PAD_ENET_CLK__ENET_CLK,
+ /* PHY power line */
+ MX28_PAD_SSP1_DATA3__GPIO_2_15,
+ /* PHY reset line */
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
+};
+
+/* FEC */
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static inline void mx28evk_fec_reset(void)
+{
+ int ret;
+
+ /* Power up FEC PHY */
+ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+ if (ret) {
+ pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+
+ /* Reset FEC PHY */
+ ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+ mdelay(1);
+ gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static void __init mx28evk_init(void)
+{
+ mxc_iomux_pinctrl_setup_multiple_pads(mx28evk_pads,
+ ARRAY_SIZE(mx28evk_pads));
+ imx28_add_duart();
+
+ mx28evk_fec_reset();
+ imx28_add_fec(&mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+ mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+ .init = mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX28_PHYS_OFFSET + 0x100,
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
diff --git a/arch/arm/plat-mxc/devices/platform-duart.c b/arch/arm/plat-mxc/devices/platform-duart.c
new file mode 100644
index 0000000..2dbf199
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-duart.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_duart_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _DUART_BASE_ADDR, \
+ .irq = soc ## _INT_DUART, \
+ }
+
+#ifdef CONFIG_ARCH_MX28
+const struct imx_duart_data imx28_duart_data __initconst =
+ imx_duart_data_entry_single(MX28);
+#endif
+
+struct platform_device *__init imx_add_duart(
+ const struct imx_duart_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-duart", 0, res, ARRAY_SIZE(res),
+ NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
index 11d087f..bd5a84b 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -26,6 +26,11 @@ const struct imx_fec_data imx27_fec_data __initconst =
imx_fec_data_entry_single(MX27);
#endif /* ifdef CONFIG_SOC_IMX27 */
+#ifdef CONFIG_ARCH_MX28
+const struct imx_fec_data imx28_fec_data __initconst =
+ imx_fec_data_entry_single(MX28);
+#endif
+
#ifdef CONFIG_ARCH_MX35
const struct imx_fec_data imx35_fec_data __initconst =
imx_fec_data_entry_single(MX35);
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 05676fb..6a5dea7 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -18,16 +18,19 @@ extern void mx1_map_io(void);
extern void mx21_map_io(void);
extern void mx25_map_io(void);
extern void mx27_map_io(void);
+extern void mx28_map_io(void);
extern void mx31_map_io(void);
extern void mx35_map_io(void);
extern void mx51_map_io(void);
extern void mxc91231_map_io(void);
extern void mxc_init_irq(void __iomem *);
extern void tzic_init_irq(void __iomem *);
+extern void icoll_init_irq(void __iomem *);
extern void mx1_init_irq(void);
extern void mx21_init_irq(void);
extern void mx25_init_irq(void);
extern void mx27_init_irq(void);
+extern void mx28_init_irq(void);
extern void mx31_init_irq(void);
extern void mx35_init_irq(void);
extern void mx51_init_irq(void);
@@ -38,6 +41,7 @@ extern int mx1_clocks_init(unsigned long fref);
extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
extern int mx25_clocks_init(void);
extern int mx27_clocks_init(unsigned long fref);
+extern int mx28_clocks_init(void);
extern int mx31_clocks_init(unsigned long fref);
extern int mx35_clocks_init(void);
extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
@@ -51,4 +55,5 @@ extern void mxc91231_power_off(void);
extern void mxc91231_arch_reset(int, const char *);
extern void mxc91231_prepare_idle(void);
extern void mx51_efikamx_reset(void);
+extern int mxc_reset_block(void __iomem *);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8c6896f..501329d 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -2,6 +2,8 @@
* Copyright (C) 2009-2010 Pengutronix
* Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
*
+ * Copyright 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 version 2 as published by the
* Free Software Foundation.
@@ -82,6 +84,15 @@ struct platform_device *__init imx_add_imx_uart_1irq(
const struct imx_imx_uart_1irq_data *data,
const struct imxuart_platform_data *pdata);
+struct imx_duart_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_duart(
+ const struct imx_duart_data *data);
+
#include <mach/mxc_nand.h>
struct imx_mxc_nand_data {
/*
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (9 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
2010-11-15 17:01 ` Uwe Kleine-König
2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-imx/Kconfig | 20 ++++++++++++++++++++
arch/arm/mach-imx/Makefile | 4 ++++
arch/arm/mach-imx/Makefile.boot | 4 ++++
arch/arm/plat-mxc/Kconfig | 12 ++++++++++++
arch/arm/plat-mxc/Makefile | 4 +++-
arch/arm/plat-mxc/devices/Kconfig | 3 +++
arch/arm/plat-mxc/devices/Makefile | 1 +
7 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d6e998f..8accd5c 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -199,3 +199,23 @@ config MACH_MXT_TD60
includes specific configurations for the module and its peripherals.
endif
+
+if ARCH_MX28
+
+config SOC_IMX28
+ select CPU_ARM926T
+ select ARCH_MXC_IOMUX_PINCTRL
+ select MXC_ICOLL
+ bool
+
+comment "MX28 platforms:"
+
+config MACH_MX28EVK
+ bool "MX28 EVK platform"
+ select IMX_HAVE_PLATFORM_DUART
+ help
+ Include support for MX28 EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
+
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 5582692..3b12218 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
+obj-$(CONFIG_ARCH_MX28) += clock-imx28.o mm-imx28.o
+
# Support for CMOS sensor interface
obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
@@ -32,3 +34,5 @@ obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
+
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 7988a85..fd451d0 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -9,3 +9,7 @@ initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
+
+zreladdr-$(CONFIG_ARCH_MX28) := 0x40008000
+params_phys-$(CONFIG_ARCH_MX28) := 0x40000100
+initrd_phys-$(CONFIG_ARCH_MX28) := 0x40800000
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 680aeba..fd7ec19 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -25,6 +25,12 @@ config ARCH_MX25
help
This enables support for systems based on the Freescale i.MX25 family
+config ARCH_MX28
+ bool "MX28-based"
+ select SOC_IMX28
+ help
+ This enables support for systems based on the Freescale i.MX28 family
+
config ARCH_MX3
bool "MX3-based"
select CPU_V6
@@ -68,6 +74,9 @@ config MXC_TZIC
config MXC_AVIC
bool
+config MXC_ICOLL
+ bool
+
config MXC_PWM
tristate "Enable PWM driver"
select HAVE_PWM
@@ -109,6 +118,9 @@ config IMX_HAVE_IOMUX_V1
config ARCH_MXC_IOMUX_V3
bool
+config ARCH_MXC_IOMUX_PINCTRL
+ bool
+
config ARCH_MXC_AUDMUX_V1
bool
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 0e12591..e194468 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -5,12 +5,14 @@
# Common support
obj-y := clock.o gpio.o time.o devices.o cpu.o system.o
-# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
obj-$(CONFIG_MXC_TZIC) += tzic.o
obj-$(CONFIG_MXC_AVIC) += avic.o
+obj-$(CONFIG_MXC_ICOLL) += icoll.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+obj-$(CONFIG_ARCH_MXC_IOMUX_PINCTRL) += iomux-pinctrl.o
+
obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 9aa6f3e..e8860d9 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -1,3 +1,6 @@
+config IMX_HAVE_PLATFORM_DUART
+ bool
+
config IMX_HAVE_PLATFORM_ESDHC
bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 45aefeb..11e2fcf 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_IMX_HAVE_PLATFORM_DUART) += platform-duart.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
@ 2010-11-15 16:25 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:25 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:25PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/include/mach/hardware.h | 9 +-
> arch/arm/plat-mxc/include/mach/irqs.h | 11 +-
> arch/arm/plat-mxc/include/mach/memory.h | 5 +-
> arch/arm/plat-mxc/include/mach/mx28.h | 232 +++++++++++++++++++++++++++++
> arch/arm/plat-mxc/include/mach/mxc.h | 14 ++
> 5 files changed, 264 insertions(+), 7 deletions(-)
> create mode 100644 arch/arm/plat-mxc/include/mach/mx28.h
>
> diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> index 2f59b63..499b14c 100644
> --- a/arch/arm/plat-mxc/include/mach/hardware.h
> +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> *
> * This program is free software; you can redistribute it and/or
> @@ -63,6 +63,9 @@
> * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
> * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
> * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000
> + * mx28:
> + * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
> + * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
> * mx31:
> * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
> * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
> @@ -127,6 +130,10 @@
> # include <mach/mx25.h>
> #endif
>
> +#ifdef CONFIG_ARCH_MX28
> +# include <mach/mx28.h>
> +#endif
> +
> #ifdef CONFIG_ARCH_MXC91231
> # include <mach/mxc91231.h>
> #endif
> diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> index 86781f7..2f810c5 100644
> --- a/arch/arm/plat-mxc/include/mach/irqs.h
> +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> */
>
> /*
> @@ -12,12 +12,13 @@
> #define __ASM_ARCH_MXC_IRQS_H__
>
> /*
> - * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> + * SoCs with AVIC interrupt controller have 64 IRQs,
> + * those with TZIC and ICOLL have 128.
> */
> -#ifdef CONFIG_MXC_TZIC
> -#define MXC_INTERNAL_IRQS 128
> -#else
> +#ifdef CONFIG_MXC_AVIC
> #define MXC_INTERNAL_IRQS 64
> +#else
> +#define MXC_INTERNAL_IRQS 128
> #endif
I like the more explicit approach that was used before. When using
#elif it doesn't look that ugly.
> #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
> diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> index 564ec9d..af090e3 100644
> --- a/arch/arm/plat-mxc/include/mach/memory.h
> +++ b/arch/arm/plat-mxc/include/mach/memory.h
> @@ -1,5 +1,5 @@
> /*
> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
INAL but I wonder if your change to the file is worth 3 years of
copyright assignment. *I* don't care much though. The same applies to
some other files touched by this patch.
> */
>
> /*
> @@ -15,6 +15,7 @@
> #define MX21_PHYS_OFFSET UL(0xc0000000)
> #define MX25_PHYS_OFFSET UL(0x80000000)
> #define MX27_PHYS_OFFSET UL(0xa0000000)
> +#define MX28_PHYS_OFFSET UL(0x40000000)
> #define MX3x_PHYS_OFFSET UL(0x80000000)
> #define MX51_PHYS_OFFSET UL(0x90000000)
> #define MXC91231_PHYS_OFFSET UL(0x90000000)
> @@ -28,6 +29,8 @@
> # define PHYS_OFFSET MX25_PHYS_OFFSET
> # elif defined CONFIG_MACH_MX27
> # define PHYS_OFFSET MX27_PHYS_OFFSET
> +# elif defined CONFIG_ARCH_MX28
> +# define PHYS_OFFSET MX28_PHYS_OFFSET
> # elif defined CONFIG_ARCH_MX3
> # define PHYS_OFFSET MX3x_PHYS_OFFSET
> # elif defined CONFIG_ARCH_MXC91231
> diff --git a/arch/arm/plat-mxc/include/mach/mx28.h b/arch/arm/plat-mxc/include/mach/mx28.h
> new file mode 100644
> index 0000000..6f73888
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/mx28.h
> @@ -0,0 +1,232 @@
> +/*
> + * Copyright (C) 2009-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 __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
Is this needed?
> +
> +#define SET_ADDR 0x4
> +#define CLR_ADDR 0x8
> +#define TOG_ADDR 0xc
Please don't pollute the namespace but use MX28 prefixes. Are these
used?
> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR 0x00000000
> +#define MX28_OCRAM_SIZE SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR 0x80000000
> +#define MX28_IO_SIZE SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR (MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR (MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR (MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_FEC_BASE_ADDR MX28_ENET_BASE_ADDR
> +
> +#define MX28_IO_P2V(x) IMX_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x) IOMEM(MX27_IO_P2V(x))
s/27/28/ I suppose
> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT 0
> +#define MX28_INT_VDDD_BRNOUT 1
> +#define MX28_INT_VDDIO_BRNOUT 2
> +#define MX28_INT_VDDA_BRNOUT 3
> +#define MX28_INT_VDD5V_DROOP 4
> +#define MX28_INT_DCDC4P2_BRNOUT 5
> +#define MX28_INT_VDD5V 6
> +#define MX28_INT_RESV7 7
> +#define MX28_INT_CAN0 8
> +#define MX28_INT_CAN1 9
> +#define MX28_INT_LRADC_TOUCH 10
> +#define MX28_INT_RESV11 11
> +#define MX28_INT_RESV12 12
> +#define MX28_INT_HSADC 13
> +#define MX28_INT_IRADC_THRESH0 14
> +#define MX28_INT_IRADC_THRESH1 15
> +#define MX28_INT_LRADC_CH0 16
> +#define MX28_INT_LRADC_CH1 17
> +#define MX28_INT_LRADC_CH2 18
> +#define MX28_INT_LRADC_CH3 19
> +#define MX28_INT_LRADC_CH4 20
> +#define MX28_INT_LRADC_CH5 21
> +#define MX28_INT_LRADC_CH6 22
> +#define MX28_INT_LRADC_CH7 23
> +#define MX28_INT_LRADC_BUTTON0 24
> +#define MX28_INT_LRADC_BUTTON1 25
> +#define MX28_INT_RESV26 26
> +#define MX28_INT_PERFMON 27
> +#define MX28_INT_RTC_1MSEC 28
> +#define MX28_INT_RTC_ALARM 29
> +#define MX28_INT_RESV30 30
> +#define MX28_INT_COMMS 31
> +#define MX28_INT_EMI_ERR 32
> +#define MX28_INT_RESV33 33
> +#define MX28_INT_RESV34 34
> +#define MX28_INT_RESV35 35
> +#define MX28_INT_RESV36 36
> +#define MX28_INT_RESV37 37
> +#define MX28_INT_LCDIF 38
> +#define MX28_INT_PXP 39
> +#define MX28_INT_RESV40 40
> +#define MX28_INT_BCH 41
> +#define MX28_INT_GPMI 42
> +#define MX28_INT_RESV43 43
> +#define MX28_INT_RESV44 44
> +#define MX28_INT_SPDIF_ERROR 45
> +#define MX28_INT_RESV46 46
> +#define MX28_INT_DUART 47
> +#define MX28_INT_TIMER0 48
> +#define MX28_INT_TIMER1 49
> +#define MX28_INT_TIMER2 50
> +#define MX28_INT_TIMER3 51
> +#define MX28_INT_DCP_VMI 52
> +#define MX28_INT_DCP 53
> +#define MX28_INT_DCP_SECURE 54
> +#define MX28_INT_RESV55 55
> +#define MX28_INT_RESV56 56
> +#define MX28_INT_RESV57 57
> +#define MX28_INT_SAIF1 58
> +#define MX28_INT_SAIF0 59
> +#define MX28_INT_RESV60 60
> +#define MX28_INT_RESV61 61
> +#define MX28_INT_RESV62 62
> +#define MX28_INT_RESV63 63
> +#define MX28_INT_RESV64 64
> +#define MX28_INT_RESV65 65
> +#define MX28_INT_SPDIF_DMA 66
> +#define MX28_INT_RESV67 67
> +#define MX28_INT_I2C0_DMA 68
> +#define MX28_INT_I2C1_DMA 69
> +#define MX28_INT_AUART0_RX_DMA 70
> +#define MX28_INT_AUART0_TX_DMA 71
> +#define MX28_INT_AUART1_RX_DMA 72
> +#define MX28_INT_AUART1_TX_DMA 73
> +#define MX28_INT_AUART2_RX_DMA 74
> +#define MX28_INT_AUART2_TX_DMA 75
> +#define MX28_INT_AUART3_RX_DMA 76
> +#define MX28_INT_AUART3_TX_DMA 77
> +#define MX28_INT_AUART4_RX_DMA 78
> +#define MX28_INT_AUART4_TX_DMA 79
> +#define MX28_INT_SAIF0_DMA 80
> +#define MX28_INT_SAIF1_DMA 81
> +#define MX28_INT_SSP0_DMA 82
> +#define MX28_INT_SSP1_DMA 83
> +#define MX28_INT_SSP2_DMA 84
> +#define MX28_INT_SSP3_DMA 85
> +#define MX28_INT_LCDIF_DMA 86
> +#define MX28_INT_HSADC_DMA 87
> +#define MX28_INT_GPMI_DMA 88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP 89
> +#define MX28_INT_RESV90 90
> +#define MX28_INT_RESV91 91
> +#define MX28_INT_USB1 92
> +#define MX28_INT_USB0 93
> +#define MX28_INT_USB1_WAKEUP 94
> +#define MX28_INT_USB0_WAKEUP 95
> +#define MX28_INT_SSP0 96
> +#define MX28_INT_SSP1 97
> +#define MX28_INT_SSP2 98
> +#define MX28_INT_SSP3 99
> +#define MX28_INT_ENET_SWI 100
> +#define MX28_INT_ENET_MAC0 101
> +#define MX28_INT_ENET_MAC1 102
> +#define MX28_INT_ENET_MAC0_1588 103
> +#define MX28_INT_ENET_MAC1_1588 104
> +#define MX28_INT_RESV105 105
> +#define MX28_INT_RESV106 106
> +#define MX28_INT_RESV107 107
> +#define MX28_INT_RESV108 108
> +#define MX28_INT_RESV109 109
> +#define MX28_INT_I2C1_ERROR 110
> +#define MX28_INT_I2C0_ERROR 111
> +#define MX28_INT_AUART0 112
> +#define MX28_INT_AUART1 113
> +#define MX28_INT_AUART2 114
> +#define MX28_INT_AUART3 115
> +#define MX28_INT_AUART4 116
> +#define MX28_INT_RESV117 117
> +#define MX28_INT_RESV118 118
> +#define MX28_INT_RESV119 119
> +#define MX28_INT_RESV120 120
> +#define MX28_INT_RESV121 121
> +#define MX28_INT_RESV122 122
I'd just skip those RESV defines (assuming they mean "reserved").
> +#define MX28_INT_GPIO4 123
> +#define MX28_INT_GPIO3 124
> +#define MX28_INT_GPIO2 125
> +#define MX28_INT_GPIO1 126
> +#define MX28_INT_GPIO0 127
> +#define MX28_INT_FEC MX28_INT_ENET_MAC0
This looks strage. What is MX28_INT_ENET_MAC1 used for?
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> index 3432b78..563901f 100644
> --- a/arch/arm/plat-mxc/include/mach/mxc.h
> +++ b/arch/arm/plat-mxc/include/mach/mxc.h
> @@ -30,6 +30,7 @@
> #define MXC_CPU_MX21 21
> #define MXC_CPU_MX25 25
> #define MXC_CPU_MX27 27
> +#define MXC_CPU_MX28 28
> #define MXC_CPU_MX31 31
> #define MXC_CPU_MX35 35
> #define MXC_CPU_MX51 51
> @@ -87,6 +88,18 @@ extern unsigned int __mxc_cpu_type;
> # define cpu_is_mx27() (0)
> #endif
>
> +#ifdef CONFIG_ARCH_MX28
> +# ifdef mxc_cpu_type
> +# undef mxc_cpu_type
> +# define mxc_cpu_type __mxc_cpu_type
> +# else
> +# define mxc_cpu_type MXC_CPU_MX28
> +# endif
> +# define cpu_is_mx28() (mxc_cpu_type == MXC_CPU_MX28)
> +#else
> +# define cpu_is_mx28() (0)
> +#endif
> +
> #ifdef CONFIG_ARCH_MX31
> # ifdef mxc_cpu_type
> # undef mxc_cpu_type
> @@ -161,5 +174,6 @@ extern void __iomem *mxc_irq_base;
>
> #define MXC_IRQ_TYPE_AVIC 1
> #define MXC_IRQ_TYPE_TZIC 2
> +#define MXC_IRQ_TYPE_ICOLL 3
>
> #endif /* __ASM_ARCH_MXC_H__ */
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL
2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
@ 2010-11-15 16:33 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:33 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:26PM +0800, Shawn Guo wrote:
> MX28 uses Interrupt Collector (ICOLL) as the interrupt
> controller. So ICOLL becomes the third interrupt controller
> for MXC besides AVIC and TZIC.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/icoll.c | 79 ++++++++++++++++++++++++++
> arch/arm/plat-mxc/include/mach/entry-macro.S | 22 ++++++-
> 2 files changed, 97 insertions(+), 4 deletions(-)
> create mode 100644 arch/arm/plat-mxc/icoll.c
>
> diff --git a/arch/arm/plat-mxc/icoll.c b/arch/arm/plat-mxc/icoll.c
> new file mode 100644
> index 0000000..e9a9e42
> --- /dev/null
> +++ b/arch/arm/plat-mxc/icoll.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright (C) 2009-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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/irq.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define HW_ICOLL_VECTOR 0x0000
> +#define HW_ICOLL_LEVELACK 0x0010
> +#define HW_ICOLL_CTRL 0x0020
> +#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
> +#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
> +#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
> +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
> +
> +void __iomem *icoll_base;
> +
> +static void icoll_ack_irq(unsigned int irq)
> +{
> + __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> +
> + /* ACK current interrupt (level 0) */
> + __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
> + icoll_base + HW_ICOLL_LEVELACK);
> +}
> +
> +static void icoll_mask_irq(unsigned int irq)
> +{
> + __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> + icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
> +}
> +
> +static void icoll_unmask_irq(unsigned int irq)
> +{
> + __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> + icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
> +}
> +
> +static struct irq_chip mxc_icoll_chip = {
> + .ack = icoll_ack_irq,
> + .mask = icoll_mask_irq,
> + .unmask = icoll_unmask_irq,
> +};
> +
> +void __init icoll_init_irq(void __iomem *irqbase)
> +{
> + int i;
> +
> + icoll_base = irqbase;
> + mxc_irq_base = irqbase;
> + mxc_irq_controller_type = MXC_IRQ_TYPE_ICOLL;
> +
> + /* Reset icoll */
> + mxc_reset_block(irqbase + HW_ICOLL_CTRL);
mxc_reset_block is only defined in patch 3, so you must not use it in
patch 2.
> +
> + for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
> + set_irq_chip(i, &mxc_icoll_chip);
> + set_irq_handler(i, handle_level_irq);
> + set_irq_flags(i, IRQF_VALID);
> + }
> +}
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index a7dd008..a66e804 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -1,6 +1,6 @@
> /*
> * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> - * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> */
>
> /*
> @@ -73,25 +73,39 @@
> #endif
> .endm
>
> + .macro icoll_get_irqnr_and_base, irqnr, irqstat, base, tmp
> + ldr \irqnr, [\base, #0x70]
> + cmp \irqnr, #0x7F
> + moveqs \irqnr, #0
> + .endm
> +
> .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> -#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC
> +#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC && defined CONFIG_MXC_ICOLL
> ldr \tmp, =mxc_irq_controller_type
> ldr \tmp, [\tmp]
> cmp \tmp, #MXC_IRQ_TYPE_AVIC
> beq 3001f
> + cmp \tmp, #MXC_IRQ_TYPE_ICOLL
> + beq 3002f
>
> tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> - b 3002f
> + b 3003f
> 3001:
> avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> + b 3003f
> 3002:
> + icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> + b 3003f
> +3003:
>
> #elif defined CONFIG_MXC_TZIC
> tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> #elif defined CONFIG_MXC_AVIC
> avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#elif defined CONFIG_MXC_ICOLL
> + icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> #else
> -#error no tzic and no avic?
> +#error none of tzic, avic, icoll?
> #endif
> .endm
I wonder if it's sensible to integrate mx28 (and mx23) support into
mach-imx/plat-mxc. They seem to better fit into mach-stmp378x?!
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
@ 2010-11-15 16:36 ` Uwe Kleine-König
2010-11-17 11:17 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:36 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
> 1. The wdog reset is implemented in RTC block on MX28.
> 2. Implement the common reset routine for most blocks on MX28,
> so that the blocks can call it to get a software reset.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/system.c | 104 ++++++++++++++++++++++++++++++++++++++++++-
> 1 files changed, 101 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
> index c3972c5..257b426 100644
> --- a/arch/arm/plat-mxc/system.c
> +++ b/arch/arm/plat-mxc/system.c
> @@ -1,7 +1,7 @@
> /*
> * Copyright (C) 1999 ARM Limited
> * Copyright (C) 2000 Deep Blue Solutions Ltd
> - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> *
> @@ -36,6 +36,7 @@ static void __iomem *wdog_base;
> void arch_reset(char mode, const char *cmd)
> {
> unsigned int wcr_enable;
> + struct clk *clk;
>
> #ifdef CONFIG_ARCH_MXC91231
> if (cpu_is_mxc91231()) {
> @@ -52,9 +53,18 @@ void arch_reset(char mode, const char *cmd)
>
> if (cpu_is_mx1()) {
> wcr_enable = (1 << 0);
> - } else {
> - struct clk *clk;
> + } else if (cpu_is_mx28()) {
> + clk = clk_get_sys("rtc", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
>
> + /* set wdog count */
> + __raw_writel(1, wdog_base + 0x50);
> + /* wdog enbable bit */
s/enbable/enable/
> + wcr_enable = (1 << 4);
> + /* shift to SET address */
> + wdog_base += 0x4;
> + } else {
> clk = clk_get_sys("imx-wdt.0", NULL);
> if (!IS_ERR(clk))
> clk_enable(clk);
> @@ -80,3 +90,91 @@ void mxc_arch_reset_init(void __iomem *base)
> {
> wdog_base = base;
> }
> +
> +#ifdef CONFIG_ARCH_MX28
> +int mxc_reset_block(void __iomem *reg_addr)
> +{
> + u32 reg;
> + int timeout;
> +
> + /*
> + * The process of software reset of IP block is done
> + * in several steps:
> + *
> + * 1) clear SFTRST and wait it cleared;
> + * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
> + * 3) clear SFTRST and wait it cleared;
> + * 4) clear CLKGATE and wait it cleared.
> + */
> +
> + /* Clear SFTRST */
> + reg = __raw_readl(reg_addr);
> + reg &= ~(1 << 31);
> + __raw_writel(reg, reg_addr);
> + /* Wait SFTRST cleared */
> + timeout = 1000;
> + do {
> + mdelay(1);
> + if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> + break;
> + } while (--timeout > 0);
Does the mdelay make sence here?
> + if (timeout <= 0) {
> + pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
> + return -ETIMEDOUT;
> + }
> +
> + /* Clear CLKGATE */
> + reg = __raw_readl(reg_addr);
> + reg &= ~(1 << 30);
> + __raw_writel(reg, reg_addr);
> + /* Set SFTRST to reset the block */
> + reg = __raw_readl(reg_addr);
> + reg |= (1 << 31);
Can we have #defines here instead of constants?
> + __raw_writel(reg, reg_addr);
> + /* Poll CLKGATE set */
> + timeout = 1000;
> + do {
> + mdelay(1);
> + if (__raw_readl(reg_addr) & (1 << 30))
> + break;
> + } while (--timeout > 0);
> + if (timeout <= 0) {
> + pr_err("%s(%p): poll CLKGATE timeout\n", __func__, reg_addr);
> + return -ETIMEDOUT;
> + }
> +
> + /* Clear SFTRST */
> + reg = __raw_readl(reg_addr);
> + reg &= ~(1 << 31);
> + __raw_writel(reg, reg_addr);
> + /* Wait SFTRST cleared */
> + timeout = 1000;
> + do {
> + mdelay(1);
> + if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> + break;
> + } while (--timeout > 0);
> + if (timeout <= 0) {
> + pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
> + return -ETIMEDOUT;
> + }
> +
> + /* Clear CLKGATE */
> + reg = __raw_readl(reg_addr);
> + reg &= ~(1 << 30);
> + __raw_writel(reg, reg_addr);
> + /* Wait CLKGATE cleared */
> + timeout = 1000;
> + do {
> + mdelay(1);
> + if ((__raw_readl(reg_addr) & (1 << 30)) == 0)
> + break;
> + } while (--timeout > 0);
> + if (timeout <= 0) {
> + pr_err("%s(%p): clear CLKGATE timeout\n", __func__, reg_addr);
> + return -ETIMEDOUT;
> + }
> +
> + return 0;
> +}
> +#endif
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 04/11] ARM: imx: Add timer support for i.MX28
2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
@ 2010-11-15 16:40 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:40 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:28PM +0800, Shawn Guo wrote:
> SoC i.MX28 implements the timer in block TIMROT. It adds the
> support in the same file with GPT, and uses timer_is_timrot()
> to distinguish the IP block.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/time.c | 120 ++++++++++++++++++++++++++++++++++++++--------
> 1 files changed, 100 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
> index f9a1b05..3e1f09d 100644
> --- a/arch/arm/plat-mxc/time.c
> +++ b/arch/arm/plat-mxc/time.c
> @@ -5,6 +5,7 @@
> * Copyright (C) 2002 Shane Nay (shane at minirl.com)
> * Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
> * Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
> + * 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
> @@ -63,8 +64,22 @@
> #define V2_TCN 0x24
> #define V2_TCMP 0x10
>
> -#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
> -#define timer_is_v2() (!timer_is_v1())
> +/* TIMROT */
> +#define HW_TIMROT_ROTCTRL 0x00
> +#define HW_TIMROT_TIMCTRL0 0x20
> +#define HW_TIMROT_TIMCTRL0_SET 0x24
> +#define HW_TIMROT_TIMCTRL0_CLR 0x28
> +#define HW_TIMROT_RUNNING_COUNT0 0x30
> +#define HW_TIMROT_MATCH_COUNT0 0x50
> +#define BM_TIMROT_TIMCTRL0_IRQ_EN 0x00004000
> +#define BM_TIMROT_TIMCTRL0_IRQ 0x00008000
> +#define BM_TIMROT_TIMCTRL0_MATCH_MODE 0x00000800
> +#define BP_TIMROT_TIMCTRL0_SELECT 0
> +#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
> +
> +#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
> +#define timer_is_v2() (!timer_is_v1())
> +#define timer_is_timrot() (cpu_is_mx28())
Did you notice that timer_is_v2() evaluates to true on mx28?
> static struct clock_event_device clockevent_mxc;
> static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> @@ -105,6 +120,24 @@ static void gpt_irq_acknowledge(void)
> __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
> }
>
> +static inline void timrot_irq_disable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRL0_CLR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRL0_SET);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRL0_IRQ,
> + timer_base + HW_TIMROT_TIMCTRL0_CLR);
> +}
> +
> static cycle_t mx1_2_get_cycles(struct clocksource *cs)
> {
> return __raw_readl(timer_base + MX1_2_TCN);
> @@ -115,6 +148,11 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
> return __raw_readl(timer_base + V2_TCN);
> }
>
> +static cycle_t timrot_get_cycles(struct clocksource *cs)
> +{
> + return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNT0);
> +}
> +
> static struct clocksource clocksource_mxc = {
> .name = "mxc_timer1",
> .rating = 200,
> @@ -128,8 +166,12 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
> {
> unsigned int c = clk_get_rate(timer_clk);
>
> - if (timer_is_v2())
> + if (timer_is_timrot()) {
> + clocksource_mxc.read = timrot_get_cycles;
> + clocksource_mxc.shift = 10;
> + } else if (timer_is_v2()) {
> clocksource_mxc.read = v2_get_cycles;
> + }
>
> clocksource_mxc.mult = clocksource_hz2mult(c,
> clocksource_mxc.shift);
> @@ -166,6 +208,18 @@ static int v2_set_next_event(unsigned long evt,
> -ETIME : 0;
> }
>
> +static int timrot_set_next_event(unsigned long evt,
> + struct clock_event_device *dev)
> +{
> + unsigned long match;
> +
> + match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNT0) - evt;
> + __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNT0);
> +
> + return (int)(match - __raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNT0)) > 0 ? -ETIME : 0;
> +}
> +
> #ifdef DEBUG
> static const char *clock_event_mode_label[] = {
> [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> @@ -186,12 +240,19 @@ static void mxc_set_mode(enum clock_event_mode mode,
> */
> local_irq_save(flags);
>
> - /* Disable interrupt in GPT module */
> - gpt_irq_disable();
> + /* Disable interrupt in timer module */
> + if (timer_is_timrot())
> + timrot_irq_disable();
> + else
> + gpt_irq_disable();
can we have timrot_set_mode() please. Having several cpu_is_... in hot
paths isn't nice.
> if (mode != clockevent_mode) {
> /* Set event time into far-far future */
> - if (timer_is_v2())
> + if (timer_is_timrot())
> + __raw_writel(__raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNT0) + 3,
> + timer_base + HW_TIMROT_MATCH_COUNT0);
> + else if (timer_is_v2())
> __raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
> timer_base + V2_TCMP);
> else
> @@ -199,7 +260,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
> timer_base + MX1_2_TCMP);
>
> /* Clear pending interrupt */
> - gpt_irq_acknowledge();
> + if (timer_is_timrot())
> + timrot_irq_acknowledge();
> + else
> + gpt_irq_acknowledge();
> }
>
> #ifdef DEBUG
> @@ -225,7 +289,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
> * mode switching
> */
> local_irq_save(flags);
> - gpt_irq_enable();
> + if (timer_is_timrot())
> + timrot_irq_enable();
> + else
> + gpt_irq_enable();
> local_irq_restore(flags);
> break;
> case CLOCK_EVT_MODE_SHUTDOWN:
> @@ -249,7 +316,10 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
> else
> tstat = __raw_readl(timer_base + MX1_2_TSTAT);
>
> - gpt_irq_acknowledge();
> + if (timer_is_timrot())
> + timrot_irq_acknowledge();
> + else
> + gpt_irq_acknowledge();
>
> evt->event_handler(evt);
>
> @@ -275,7 +345,9 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
> {
> unsigned int c = clk_get_rate(timer_clk);
>
> - if (timer_is_v2())
> + if (timer_is_timrot())
> + clockevent_mxc.set_next_event = timrot_set_next_event;
> + else if (timer_is_v2())
> clockevent_mxc.set_next_event = v2_set_next_event;
>
> clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
> @@ -303,16 +375,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
> /*
> * Initialise to a known state (all timers off, and timing reset)
> */
> -
> - __raw_writel(0, timer_base + MXC_TCTL);
> - __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> -
> - if (timer_is_v2())
> - tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
> - else
> - tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
> -
> - __raw_writel(tctl_val, timer_base + MXC_TCTL);
> + if (timer_is_timrot()) {
> + mxc_reset_block(base + HW_TIMROT_ROTCTRL);
> + __raw_writel(
> + BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRL0_IRQ_EN |
> + BM_TIMROT_TIMCTRL0_MATCH_MODE,
> + timer_base + HW_TIMROT_TIMCTRL0); /* timer0*/
> + } else {
> + __raw_writel(0, timer_base + MXC_TCTL);
> + __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> + if (timer_is_v2())
> + tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR |
> + V2_TCTL_WAITEN | MXC_TCTL_TEN;
> + else
> + tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 |
> + MXC_TCTL_TEN;
> + __raw_writel(tctl_val, timer_base + MXC_TCTL);
> + }
>
> /* init and register the timer to the framework */
> mxc_clocksource_init(timer_clk);
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 05/11] ARM: imx: Add GPIO support for i.MX28
2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
@ 2010-11-15 16:43 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:43 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:29PM +0800, Shawn Guo wrote:
> SoC i.MX28 implements GPIO functions in block PINCTRL. It adds
> the support in the same file used by other i.MX SoCs, and uses
> cpu_is_mx28() to distinguish the PINCTRL from GPIO used by other
> i.MX SoCs.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/gpio.c | 186 +++++++++++++++++++++++++++++++++++++--------
> 1 files changed, 153 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
> index 9c3e362..f0d94af 100644
> --- a/arch/arm/plat-mxc/gpio.c
> +++ b/arch/arm/plat-mxc/gpio.c
> @@ -30,6 +30,17 @@
> static struct mxc_gpio_port *mxc_gpio_ports;
> static int gpio_table_size;
>
> +/* PINCTRL */
> +#define GPIO_PORT_ID(p) (((void *)p - (void *)mxc_gpio_ports) / sizeof(p))
> +#define GPIO_DOUT(p) (0x0700 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_DIN(p) (0x0900 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_DOE(p) (0x0b00 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_PIN2IRQ(p) (0x1000 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_IRQEN(p) (0x1100 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_LEV(p) (0x1200 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_POL(p) (0x1300 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_IRQSTAT(p) (0x1400 + GPIO_PORT_ID(p) * 0x10)
> +
> #define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
>
> #define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00)
> @@ -40,17 +51,25 @@ static int gpio_table_size;
> #define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14)
> #define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
>
> -#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
> -#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1)
> -#define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2)
> -#define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3)
> +#define GPIO_INT_LOW_LEV \
> + (cpu_is_mx28() ? 0x1 : (cpu_is_mx1_mx2() ? 0x3 : 0x0))
I'm more and more conviced that it doesn't make sense to fold mx28 into
the existing mxc code.
> +#define GPIO_INT_HIGH_LEV \
> + (cpu_is_mx28() ? 0x3 : (cpu_is_mx1_mx2() ? 0x2 : 0x1))
> +#define GPIO_INT_RISE_EDGE \
> + (cpu_is_mx1_mx2() ? 0x0 : 0x2)
> +#define GPIO_INT_FALL_EDGE \
> + (cpu_is_mx28() ? 0x0 : (cpu_is_mx1_mx2() ? 0x1 : 0x3))
> #define GPIO_INT_NONE 0x4
>
> /* Note: This driver assumes 32 GPIOs are handled in one register */
>
> static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
> {
> - __raw_writel(1 << index, port->base + GPIO_ISR);
> + if (cpu_is_mx28())
> + __raw_writel(1 << index,
> + port->base + GPIO_IRQSTAT(port) + CLR_ADDR);
> + else
> + __raw_writel(1 << index, port->base + GPIO_ISR);
> }
>
> static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
> @@ -58,9 +77,23 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
> {
> u32 l;
>
> - l = __raw_readl(port->base + GPIO_IMR);
> - l = (l & (~(1 << index))) | (!!enable << index);
> - __raw_writel(l, port->base + GPIO_IMR);
> + if (cpu_is_mx28()) {
> + if (enable == 0) {
> + __raw_writel(1 << index,
> + port->base + GPIO_PIN2IRQ(port) + CLR_ADDR);
> + __raw_writel(1 << index,
> + port->base + GPIO_IRQEN(port) + CLR_ADDR);
> + } else {
> + __raw_writel(1 << index,
> + port->base + GPIO_PIN2IRQ(port) + SET_ADDR);
> + __raw_writel(1 << index,
> + port->base + GPIO_IRQEN(port) + SET_ADDR);
> + }
> + } else {
> + l = __raw_readl(port->base + GPIO_IMR);
> + l = (l & (~(1 << index))) | (!!enable << index);
> + __raw_writel(l, port->base + GPIO_IMR);
> + }
> }
>
> static void gpio_ack_irq(u32 irq)
> @@ -120,10 +153,28 @@ static int gpio_set_irq_type(u32 irq, u32 type)
> return -EINVAL;
> }
>
> - reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> - bit = gpio & 0xf;
> - val = __raw_readl(reg) & ~(0x3 << (bit << 1));
> - __raw_writel(val | (edge << (bit << 1)), reg);
> + if (cpu_is_mx28()) {
> + /* set level or edge */
> + if (edge & 0x1)
> + __raw_writel(1 << (gpio & 31),
> + port->base + GPIO_LEV(port) + SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + GPIO_LEV(port) + CLR_ADDR);
> + /* set polarity */
> + if ((edge >> 1) & 0x1)
> + __raw_writel(1 << (gpio & 31),
> + port->base + GPIO_POL(port) + SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + GPIO_POL(port) + CLR_ADDR);
> + } else {
> + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
> + bit = gpio & 0xf;
> + val = __raw_readl(reg) & ~(0x3 << (bit << 1));
> + __raw_writel(val | (edge << (bit << 1)), reg);
> + }
> +
> _clear_gpio_irqstatus(port, gpio & 0x1f);
>
> return 0;
> @@ -135,23 +186,36 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
> u32 bit, val;
> int edge;
>
> - reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> - bit = gpio & 0xf;
> - val = __raw_readl(reg);
> - edge = (val >> (bit << 1)) & 3;
> - val &= ~(0x3 << (bit << 1));
> - if (edge == GPIO_INT_HIGH_LEV) {
> - edge = GPIO_INT_LOW_LEV;
> - pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
> - } else if (edge == GPIO_INT_LOW_LEV) {
> - edge = GPIO_INT_HIGH_LEV;
> - pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
> + if (cpu_is_mx28()) {
> + edge = 1 << (gpio & 31);
> + val = __raw_readl(port->base + GPIO_LEV(port));
> + if (val & edge) {
> + /* level is invalid for this function */
> + pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> + gpio, edge);
> + return;
> + }
> + __raw_writel(1 << (gpio & 31),
> + port->base + GPIO_POL(port) + TOG_ADDR);
> } else {
> - pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> - gpio, edge);
> - return;
> + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
> + bit = gpio & 0xf;
> + val = __raw_readl(reg);
> + edge = (val >> (bit << 1)) & 3;
> + val &= ~(0x3 << (bit << 1));
> + if (edge == GPIO_INT_HIGH_LEV) {
> + edge = GPIO_INT_LOW_LEV;
> + pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
> + } else if (edge == GPIO_INT_LOW_LEV) {
> + edge = GPIO_INT_HIGH_LEV;
> + pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
> + } else {
> + pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> + gpio, edge);
> + return;
> + }
> + __raw_writel(val | (edge << (bit << 1)), reg);
> }
> - __raw_writel(val | (edge << (bit << 1)), reg);
> }
>
> /* handle 32 interrupts in one status register */
> @@ -183,6 +247,29 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> mxc_gpio_irq_handler(port, irq_stat);
> }
>
> +/* MX28 has one interrupt *per* gpio port */
> +static void mx28_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> + u32 irq_stat;
> + struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
> + u32 gpio_irq_no_base = port->virtual_irq_start;
> +
> + irq_stat = __raw_readl(port->base + GPIO_IRQSTAT(port)) &
> + __raw_readl(port->base + GPIO_IRQEN(port)) &
> + __raw_readl(port->base + GPIO_PIN2IRQ(port));
> +
> + while (irq_stat != 0) {
> + int irqoffset = fls(irq_stat) - 1;
> +
> + if (port->both_edges & (1 << irqoffset))
> + mxc_flip_edge(port, irqoffset);
> +
> + generic_handle_irq(gpio_irq_no_base + irqoffset);
> +
> + irq_stat &= ~(1 << irqoffset);
> + }
> +}
> +
> /* MX2 has one interrupt *for all* gpio ports */
> static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> {
> @@ -247,14 +334,20 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
> container_of(chip, struct mxc_gpio_port, chip);
> u32 l;
> unsigned long flags;
> + void __iomem *reg;
> +
> + if (cpu_is_mx28())
> + reg = port->base + GPIO_DOE(port);
> + else
> + reg = port->base + GPIO_GDIR;
>
> spin_lock_irqsave(&port->lock, flags);
> - l = __raw_readl(port->base + GPIO_GDIR);
> + l = __raw_readl(reg);
> if (dir)
> l |= 1 << offset;
> else
> l &= ~(1 << offset);
> - __raw_writel(l, port->base + GPIO_GDIR);
> + __raw_writel(l, reg);
> spin_unlock_irqrestore(&port->lock, flags);
> }
>
> @@ -262,9 +355,14 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> {
> struct mxc_gpio_port *port =
> container_of(chip, struct mxc_gpio_port, chip);
> - void __iomem *reg = port->base + GPIO_DR;
> u32 l;
> unsigned long flags;
> + void __iomem *reg;
> +
> + if (cpu_is_mx28())
> + reg = port->base + GPIO_DOUT(port);
> + else
> + reg = port->base + GPIO_DR;
Here again, you clutter several hot paths with if(cpu_is_...()) tests.
gpiolib is generic enough not to need this.
>
> spin_lock_irqsave(&port->lock, flags);
> l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> @@ -276,8 +374,14 @@ static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
> {
> struct mxc_gpio_port *port =
> container_of(chip, struct mxc_gpio_port, chip);
> + void __iomem *reg;
> +
> + if (cpu_is_mx28())
> + reg = port->base + GPIO_DIN(port);
> + else
> + reg = port->base + GPIO_PSR;
>
> - return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
> + return (__raw_readl(reg) >> offset) & 1;
> }
>
> static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> @@ -306,8 +410,19 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
>
> for (i = 0; i < cnt; i++) {
> /* disable the interrupt and clear the status */
> - __raw_writel(0, port[i].base + GPIO_IMR);
> - __raw_writel(~0, port[i].base + GPIO_ISR);
> + if (cpu_is_mx28()) {
> + __raw_writel(0, port[i].base +
> + GPIO_PIN2IRQ(&port[i]));
> + __raw_writel(0, port[i].base +
> + GPIO_IRQEN(&port[i]));
> + __raw_writel(~0, port[i].base +
> + GPIO_IRQSTAT(&port[i]) +
> + CLR_ADDR);
> + } else {
> + __raw_writel(0, port[i].base + GPIO_IMR);
> + __raw_writel(~0, port[i].base + GPIO_ISR);
> + }
> +
> for (j = port[i].virtual_irq_start;
> j < port[i].virtual_irq_start + 32; j++) {
> set_irq_chip(j, &gpio_irq_chip);
> @@ -338,6 +453,11 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
> mx3_gpio_irq_handler);
> set_irq_data(port[i].irq_high, &port[i]);
> }
> + } else if (cpu_is_mx28()) {
> + /* setup one handler for each entry */
> + set_irq_chained_handler(port[i].irq,
> + mx28_gpio_irq_handler);
> + set_irq_data(port[i].irq, &port[i]);
> }
> }
>
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 06/11] ARM: imx: Add IOMUX support for i.MX28
2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
@ 2010-11-15 16:46 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:46 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:30PM +0800, Shawn Guo wrote:
> Soc i.MX28 supports IOMUX function in block PINCTRL. Comparing
> to the naming of iomux-v1 and iomux-v3, it uses iomux-pinctrl,
> since PINCTRL is a totally different IP block from IOMUX and it's
> not reasonable to name it iomux-v2 or iomux-v4, which is used to
iomux v2 is already taken (by mx31) it just doesn't have this name (yet)
in the code.
> distinguish the different revision of same IP block.
Sounds more like something complet
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/include/mach/iomux-mx28.h | 50 +++++++++++++
> arch/arm/plat-mxc/include/mach/iomux-pinctrl.h | 91 +++++++++++++++++++++++
> arch/arm/plat-mxc/iomux-pinctrl.c | 94 ++++++++++++++++++++++++
> 3 files changed, 235 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx28.h
> create mode 100644 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
> create mode 100644 arch/arm/plat-mxc/iomux-pinctrl.c
>
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx28.h b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..8c68bd6
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (C) 2009-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 __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux-pinctrl.h>
> +
> +/*
> + * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux-pinctrl.h
> + *
> + * BANK PIN MUX VOL MA PULL
> + */
> +/* DUART */
> +#define MX28_PAD_PWM0__DUART_RX IOMUX_PAD(3, 16, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +#define MX28_PAD_PWM1__DUART_TX IOMUX_PAD(3, 17, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +
> +/* FEC */
> +#define MX28_PAD_ENET0_MDC__ENET0_MDC IOMUX_PAD(4, 0, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +#define MX28_PAD_ENET_CLK__ENET_CLK IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULL)
> +
> +/* GPIO */
> +#define MX28_PAD_SSP1_DATA3__GPIO_2_15 IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX28_H__ */
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
> new file mode 100644
> index 0000000..c2fdb33
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
> @@ -0,0 +1,91 @@
> +/*
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + * <armlinux@phytec.de>
> + * 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 __MACH_IOMUX_PINCTRL_H__
> +#define __MACH_IOMUX_PINCTRL_H__
> +
> +typedef struct deprecated_pad_desc {
> + unsigned bank:3;
> + unsigned pin:5;
> + unsigned muxsel:2;
> + unsigned ma:3;
> + unsigned vol:2;
> + unsigned pull:1;
> +} iomux_pinctrl_cfg_t;
Oh, you start with things that are already now deprecated?
> +
> +#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull) \
> + { \
> + .bank = _bank, \
> + .pin = _pin, \
> + .muxsel = _muxsel, \
> + .vol = _vol, \
> + .ma = _ma, \
> + .pull = _pull, \
> + }
> +
> +#define PAD_MUXSEL_0 0
> +#define PAD_MUXSEL_1 1
> +#define PAD_MUXSEL_2 2
> +#define PAD_MUXSEL_GPIO 3
> +
> +#define PAD_1V8 0
> +#define PAD_3V3 1
> +#define PAD_VOL_NONE 2
> +
> +#define PAD_4MA 0
> +#define PAD_8MA 1
> +#define PAD_12MA 2
> +#define PAD_16MA 3
> +#define PAD_MA_NONE 4
> +
> +#define PAD_NOPULL 0
> +#define PAD_PULL 1
> +
> +#define MX51_NUM_GPIO_PORT 4
> +
> +#define GPIO_PIN_MASK 0x1f
> +
> +#define GPIO_PORT_SHIFT 5
> +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
> +
> +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
> +
> +/*
> + * setups a single pad in the iomuxer
> + */
> +int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad);
> +
> +/*
> + * setups mutliple pads
s/mutliple/multiple/
> + * convenient way to call the above function with tables
> + */
> +int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count);
> +
> +/*
> + * Initialise the iomux controller
> + */
> +void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base);
> +
> +#endif /* __MACH_IOMUX_PINCTRL_H__*/
> diff --git a/arch/arm/plat-mxc/iomux-pinctrl.c b/arch/arm/plat-mxc/iomux-pinctrl.c
> new file mode 100644
> index 0000000..5f5b5ac
> --- /dev/null
> +++ b/arch/arm/plat-mxc/iomux-pinctrl.c
> @@ -0,0 +1,94 @@
> +/*
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + * <armlinux@phytec.de>
> + *
> + * 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 <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/string.h>
> +#include <linux/gpio.h>
> +#include <asm/mach/map.h>
> +#include <mach/hardware.h>
> +#include <mach/iomux-pinctrl.h>
> +
> +static void __iomem *base;
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad)
> +{
> + u32 reg, ofs, bp, bm;
> +
> + /* MUXSEL */
> + ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
> + bp = pad->pin % 16 * 2;
> + bm = 0x3 << bp;
> + reg = __raw_readl(base + ofs);
> + reg &= ~bm;
> + reg |= pad->muxsel << bp;
> + __raw_writel(reg, base + ofs);
> +
> + /* DRIVE */
> + if (pad->ma != PAD_MA_NONE && pad->vol != PAD_VOL_NONE)
> + {
> + ofs = 0x300 + pad->bank * 0x40 + pad->pin / 8 * 0x10;
> + bp = pad->pin % 8 * 4;
> + bm = 0x7 << bp;
> + reg = __raw_readl(base + ofs);
> + reg &= ~bm;
> + reg |= pad->ma << bp | pad->vol << (bp + 2);
> + __raw_writel(reg, base + ofs);
> + }
> +
> + /* PULL */
> + ofs = 0x600 + pad->bank * 0x10;
> + bp = pad->pin;
> + bm = 0x1 << bp;
> + reg = __raw_readl(base + ofs);
> + reg &= ~bm;
> + reg |= pad->pull << bp;
> + __raw_writel(reg, base + ofs);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_pad);
> +
> +int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count)
> +{
> + iomux_pinctrl_cfg_t *p = pad_list;
> + int i;
> + int ret;
> +
> + for (i = 0; i < count; i++) {
> + ret = mxc_iomux_pinctrl_setup_pad(p);
> + if (ret)
> + return ret;
> + p++;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_multiple_pads);
> +
> +void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base)
> +{
> + base = iomux_pinctrl_base;
> +}
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 07/11] ARM: imx: Add support of uncompress print for i.MX28
2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
@ 2010-11-15 16:47 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:47 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:31PM +0800, Shawn Guo wrote:
> SoC i.MX28 uses DUART IP block as the debug serial. It adds the
> support in the same file used by other i.MX SoC UART, and uses
> variable is_duart to distinguish.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/plat-mxc/include/mach/uncompress.h | 20 ++++++++++++++------
> 1 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
> index 9dd9c20..adb617f 100644
> --- a/arch/arm/plat-mxc/include/mach/uncompress.h
> +++ b/arch/arm/plat-mxc/include/mach/uncompress.h
> @@ -1,8 +1,9 @@
> /*
> - * arch/arm/plat-mxc/include/mach/uncompress.h
> + * rch/arm/plat-mxc/include/mach/uncompress.h
???
> *
> * Copyright (C) 1999 ARM Limited
> * Copyright (C) Shane Nay (shane at minirl.com)
> + * Copyright 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
> @@ -22,14 +23,16 @@
> #include <asm/mach-types.h>
>
> static unsigned long uart_base;
> +static unsigned short is_duart = 0;
don't initialize static variables to 0.
>
> #define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
>
> -#define USR2 0x98
> -#define USR2_TXFE (1<<14)
> -#define TXR 0x40
> -#define UCR1 0x80
> -#define UCR1_UARTEN 1
> +#define USR2 (is_duart ? 0x18 : 0x98)
> +#define USR2_TXFE (is_duart ? 1<<7 : 1<<14)
> +#define USR2_BUSY (1 << 3)
> +#define TXR (is_duart ? 0x00 : 0x40)
> +#define UCR1 (is_duart ? 0x30 : 0x80)
> +#define UCR1_UARTEN 1
>
> /*
> * The following code assumes the serial port has already been
> @@ -59,6 +62,7 @@ static inline void flush(void)
>
> #define MX1_UART1_BASE_ADDR 0x00206000
> #define MX25_UART1_BASE_ADDR 0x43f90000
> +#define MX28_DUART_BASE_ADDR 0x80074000
> #define MX2X_UART1_BASE_ADDR 0x1000a000
> #define MX3X_UART1_BASE_ADDR 0x43F90000
> #define MX3X_UART2_BASE_ADDR 0x43F94000
> @@ -83,6 +87,10 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
> case MACH_TYPE_MXT_TD60:
> uart_base = MX2X_UART1_BASE_ADDR;
> break;
> + case MACH_TYPE_MX28EVK:
> + uart_base = MX28_DUART_BASE_ADDR;
> + is_duart = 1;
> + break;
> case MACH_TYPE_MX31LITE:
> case MACH_TYPE_ARMADILLO5X0:
> case MACH_TYPE_MX31MOBOARD:
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk
2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
@ 2010-11-15 16:54 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:54 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:34PM +0800, Shawn Guo wrote:
> It adds machine mx28evk with initial duart and fec
> device registration.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-imx/devices-imx28.h | 20 ++++
> arch/arm/mach-imx/devices.c | 27 ++++++-
> arch/arm/mach-imx/mach-mx28evk.c | 109 +++++++++++++++++++++++
> arch/arm/plat-mxc/devices/platform-duart.c | 42 +++++++++
> arch/arm/plat-mxc/devices/platform-fec.c | 5 +
> arch/arm/plat-mxc/include/mach/common.h | 5 +
> arch/arm/plat-mxc/include/mach/devices-common.h | 11 +++
Can you split this up into (say):
- mx28: dynamically allocate duart devices
- mx28: dynamically allocate fec devices
- mx28: add gpio port definitions
- mx28: mx28evk support
> 7 files changed, 218 insertions(+), 1 deletions(-)
> create mode 100644 arch/arm/mach-imx/devices-imx28.h
> create mode 100644 arch/arm/mach-imx/mach-mx28evk.c
> create mode 100644 arch/arm/plat-mxc/devices/platform-duart.c
>
> diff --git a/arch/arm/mach-imx/devices-imx28.h b/arch/arm/mach-imx/devices-imx28.h
> new file mode 100644
> index 0000000..f35c910
> --- /dev/null
> +++ b/arch/arm/mach-imx/devices-imx28.h
> @@ -0,0 +1,20 @@
> +/*
> + * Copyright (C) 2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * Copyright 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 version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <mach/mx28.h>
> +#include <mach/devices-common.h>
> +
> +extern const struct imx_duart_data imx28_duart_data __initconst;
> +#define imx28_add_duart() \
> + imx_add_duart(&imx28_duart_data)
> +
> +extern const struct imx_fec_data imx28_fec_data __initconst;
> +#define imx28_add_fec(pdata) \
> + imx_add_fec(&imx28_fec_data, pdata)
> diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
> index e69e46e..946db32 100644
> --- a/arch/arm/mach-imx/devices.c
> +++ b/arch/arm/mach-imx/devices.c
> @@ -9,7 +9,7 @@
> * licensed "as is" without any warranty of any kind, whether express
> * or implied.
> *
> - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> * Copyright 2008 Sascha Hauer, kernel at pengutronix.de
> * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
> @@ -551,3 +551,28 @@ struct platform_device imx_kpp_device = {
> };
>
> #endif
> +
> +#ifdef CONFIG_ARCH_MX28
> +/* gpio */
> +#define DEFINE_MXC_PINCTRL_GPIO_PORT(n) \
> + { \
> + .chip.label = "gpio-" #n, \
> + .irq = MX28_INT_GPIO##n, \
> + .base = MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR), \
> + .virtual_irq_start = MXC_GPIO_IRQ_START + n * 32, \
> + }
> +
> +static struct mxc_gpio_port imx28_gpio_ports[] = {
> + DEFINE_MXC_PINCTRL_GPIO_PORT(0),
> + DEFINE_MXC_PINCTRL_GPIO_PORT(1),
> + DEFINE_MXC_PINCTRL_GPIO_PORT(2),
> + DEFINE_MXC_PINCTRL_GPIO_PORT(3),
> + DEFINE_MXC_PINCTRL_GPIO_PORT(4),
> +};
> +
> +int __init imx28_register_gpios(void)
> +{
> + return mxc_gpio_init(imx28_gpio_ports,
> + ARRAY_SIZE(imx28_gpio_ports));
> +}
> +#endif
In my tree I have moved this out of devices.c to plat-mxc/gpio.c.
> diff --git a/arch/arm/mach-imx/mach-mx28evk.c b/arch/arm/mach-imx/mach-mx28evk.c
> new file mode 100644
> index 0000000..d5dd940
> --- /dev/null
> +++ b/arch/arm/mach-imx/mach-mx28evk.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/irq.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx28.h>
> +
> +#include "devices-imx28.h"
> +#include "devices.h"
> +
> +#define MX28EVK_FEC_PHY_POWER (2*32 + 15) /* GPIO_2_15 */
> +#define MX28EVK_FEC_PHY_RESET (4*32 + 13) /* GPIO_4_13 */
> +
> +static iomux_pinctrl_cfg_t mx28evk_pads[] = {
> + /* DUART */
> + MX28_PAD_PWM0__DUART_RX,
> + MX28_PAD_PWM1__DUART_TX,
> +
> + /* FEC */
> + MX28_PAD_ENET0_MDC__ENET0_MDC,
> + MX28_PAD_ENET0_MDIO__ENET0_MDIO,
> + MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
> + MX28_PAD_ENET0_RXD0__ENET0_RXD0,
> + MX28_PAD_ENET0_RXD1__ENET0_RXD1,
> + MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
> + MX28_PAD_ENET0_TXD0__ENET0_TXD0,
> + MX28_PAD_ENET0_TXD1__ENET0_TXD1,
> + MX28_PAD_ENET_CLK__ENET_CLK,
> + /* PHY power line */
> + MX28_PAD_SSP1_DATA3__GPIO_2_15,
> + /* PHY reset line */
> + MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
> +};
> +
> +/* FEC */
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> + .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static inline void mx28evk_fec_reset(void)
> +{
> + int ret;
> +
> + /* Power up FEC PHY */
> + ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
> + if (ret) {
> + pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
> + return;
> + }
> + gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
> +
> + /* Reset FEC PHY */
> + ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
> + if (ret) {
> + pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
> + return;
> + }
> + gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> + mdelay(1);
> + gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static void __init mx28evk_init(void)
> +{
> + mxc_iomux_pinctrl_setup_multiple_pads(mx28evk_pads,
> + ARRAY_SIZE(mx28evk_pads));
> + imx28_add_duart();
> +
> + mx28evk_fec_reset();
> + imx28_add_fec(&mx28_fec_pdata);
> +}
> +
> +static void __init mx28evk_timer_init(void)
> +{
> + mx28_clocks_init();
> +}
> +
> +static struct sys_timer mx28evk_timer = {
> + .init = mx28evk_timer_init,
> +};
> +
> +MACHINE_START(MX28EVK, "Freescale MX28 EVK")
> + /* Maintainer: Freescale Semiconductor, Inc. */
> + .boot_params = MX28_PHYS_OFFSET + 0x100,
> + .map_io = mx28_map_io,
> + .init_irq = mx28_init_irq,
> + .init_machine = mx28evk_init,
> + .timer = &mx28evk_timer,
> +MACHINE_END
> diff --git a/arch/arm/plat-mxc/devices/platform-duart.c b/arch/arm/plat-mxc/devices/platform-duart.c
> new file mode 100644
> index 0000000..2dbf199
> --- /dev/null
> +++ b/arch/arm/plat-mxc/devices/platform-duart.c
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright (C) 2009-2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * Copyright 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 version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +
> +#define imx_duart_data_entry_single(soc) \
> + { \
> + .iobase = soc ## _DUART_BASE_ADDR, \
> + .irq = soc ## _INT_DUART, \
> + }
> +
> +#ifdef CONFIG_ARCH_MX28
> +const struct imx_duart_data imx28_duart_data __initconst =
> + imx_duart_data_entry_single(MX28);
> +#endif
> +
> +struct platform_device *__init imx_add_duart(
> + const struct imx_duart_data *data)
> +{
> + struct resource res[] = {
> + {
> + .start = data->iobase,
> + .end = data->iobase + SZ_8K - 1,
> + .flags = IORESOURCE_MEM,
> + }, {
> + .start = data->irq,
> + .end = data->irq,
> + .flags = IORESOURCE_IRQ,
> + },
> + };
> +
> + return imx_add_platform_device("imx-duart", 0, res, ARRAY_SIZE(res),
> + NULL, 0);
> +}
> diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
> index 11d087f..bd5a84b 100644
> --- a/arch/arm/plat-mxc/devices/platform-fec.c
> +++ b/arch/arm/plat-mxc/devices/platform-fec.c
> @@ -26,6 +26,11 @@ const struct imx_fec_data imx27_fec_data __initconst =
> imx_fec_data_entry_single(MX27);
> #endif /* ifdef CONFIG_SOC_IMX27 */
>
> +#ifdef CONFIG_ARCH_MX28
I'd prefer CONFIG_SOC_MX28 to have uniform naming. (I already switched
MX25, MX31 and MX35 to CONFIG_SOC_MX... in my tree)
> +const struct imx_fec_data imx28_fec_data __initconst =
> + imx_fec_data_entry_single(MX28);
> +#endif
> +
> #ifdef CONFIG_ARCH_MX35
> const struct imx_fec_data imx35_fec_data __initconst =
> imx_fec_data_entry_single(MX35);
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 05676fb..6a5dea7 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -18,16 +18,19 @@ extern void mx1_map_io(void);
> extern void mx21_map_io(void);
> extern void mx25_map_io(void);
> extern void mx27_map_io(void);
> +extern void mx28_map_io(void);
> extern void mx31_map_io(void);
> extern void mx35_map_io(void);
> extern void mx51_map_io(void);
> extern void mxc91231_map_io(void);
> extern void mxc_init_irq(void __iomem *);
> extern void tzic_init_irq(void __iomem *);
> +extern void icoll_init_irq(void __iomem *);
> extern void mx1_init_irq(void);
> extern void mx21_init_irq(void);
> extern void mx25_init_irq(void);
> extern void mx27_init_irq(void);
> +extern void mx28_init_irq(void);
> extern void mx31_init_irq(void);
> extern void mx35_init_irq(void);
> extern void mx51_init_irq(void);
> @@ -38,6 +41,7 @@ extern int mx1_clocks_init(unsigned long fref);
> extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
> extern int mx25_clocks_init(void);
> extern int mx27_clocks_init(unsigned long fref);
> +extern int mx28_clocks_init(void);
> extern int mx31_clocks_init(unsigned long fref);
> extern int mx35_clocks_init(void);
> extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
> @@ -51,4 +55,5 @@ extern void mxc91231_power_off(void);
> extern void mxc91231_arch_reset(int, const char *);
> extern void mxc91231_prepare_idle(void);
> extern void mx51_efikamx_reset(void);
> +extern int mxc_reset_block(void __iomem *);
> #endif
> diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
> index 8c6896f..501329d 100644
> --- a/arch/arm/plat-mxc/include/mach/devices-common.h
> +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
> @@ -2,6 +2,8 @@
> * Copyright (C) 2009-2010 Pengutronix
> * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> *
> + * Copyright 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 version 2 as published by the
> * Free Software Foundation.
> @@ -82,6 +84,15 @@ struct platform_device *__init imx_add_imx_uart_1irq(
> const struct imx_imx_uart_1irq_data *data,
> const struct imxuart_platform_data *pdata);
>
> +struct imx_duart_data {
> + int id;
> + resource_size_t iobase;
> + resource_size_t iosize;
> + resource_size_t irq;
> +};
> +struct platform_device *__init imx_add_duart(
> + const struct imx_duart_data *data);
> +
Can you please keep the file sorted alphabetically?
> #include <mach/mxc_nand.h>
> struct imx_mxc_nand_data {
> /*
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile
2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
@ 2010-11-15 17:01 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 17:01 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 15, 2010 at 10:36:35PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-imx/Kconfig | 20 ++++++++++++++++++++
> arch/arm/mach-imx/Makefile | 4 ++++
> arch/arm/mach-imx/Makefile.boot | 4 ++++
> arch/arm/plat-mxc/Kconfig | 12 ++++++++++++
> arch/arm/plat-mxc/Makefile | 4 +++-
> arch/arm/plat-mxc/devices/Kconfig | 3 +++
> arch/arm/plat-mxc/devices/Makefile | 1 +
> 7 files changed, 47 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index d6e998f..8accd5c 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -199,3 +199,23 @@ config MACH_MXT_TD60
> includes specific configurations for the module and its peripherals.
>
> endif
> +
> +if ARCH_MX28
> +
> +config SOC_IMX28
> + select CPU_ARM926T
> + select ARCH_MXC_IOMUX_PINCTRL
> + select MXC_ICOLL
> + bool
> +
> +comment "MX28 platforms:"
> +
> +config MACH_MX28EVK
> + bool "MX28 EVK platform"
> + select IMX_HAVE_PLATFORM_DUART
> + help
> + Include support for MX28 EVK platform. This includes specific
> + configurations for the board and its peripherals.
> +
> +endif
> +
please remove the new line at EOF.
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index 5582692..3b12218 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -14,6 +14,8 @@ obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
> obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
> obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
>
> +obj-$(CONFIG_ARCH_MX28) += clock-imx28.o mm-imx28.o
> +
> # Support for CMOS sensor interface
> obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
>
> @@ -32,3 +34,5 @@ obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
> obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
> obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
> obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
> +
> +obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
> diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> index 7988a85..fd451d0 100644
> --- a/arch/arm/mach-imx/Makefile.boot
> +++ b/arch/arm/mach-imx/Makefile.boot
> @@ -9,3 +9,7 @@ initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
> zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
> params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
> initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
> +
> +zreladdr-$(CONFIG_ARCH_MX28) := 0x40008000
> +params_phys-$(CONFIG_ARCH_MX28) := 0x40000100
> +initrd_phys-$(CONFIG_ARCH_MX28) := 0x40800000
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index 680aeba..fd7ec19 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -25,6 +25,12 @@ config ARCH_MX25
> help
> This enables support for systems based on the Freescale i.MX25 family
>
> +config ARCH_MX28
> + bool "MX28-based"
> + select SOC_IMX28
Can you please let the machines select SOC_IMX28?
> + help
> + This enables support for systems based on the Freescale i.MX28 family
> +
> config ARCH_MX3
> bool "MX3-based"
> select CPU_V6
> @@ -68,6 +74,9 @@ config MXC_TZIC
> config MXC_AVIC
> bool
>
> +config MXC_ICOLL
> + bool
> +
> config MXC_PWM
> tristate "Enable PWM driver"
> select HAVE_PWM
> @@ -109,6 +118,9 @@ config IMX_HAVE_IOMUX_V1
> config ARCH_MXC_IOMUX_V3
> bool
>
> +config ARCH_MXC_IOMUX_PINCTRL
> + bool
> +
> config ARCH_MXC_AUDMUX_V1
> bool
>
> diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> index 0e12591..e194468 100644
> --- a/arch/arm/plat-mxc/Makefile
> +++ b/arch/arm/plat-mxc/Makefile
> @@ -5,12 +5,14 @@
> # Common support
> obj-y := clock.o gpio.o time.o devices.o cpu.o system.o
>
> -# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
> obj-$(CONFIG_MXC_TZIC) += tzic.o
> obj-$(CONFIG_MXC_AVIC) += avic.o
> +obj-$(CONFIG_MXC_ICOLL) += icoll.o
>
> obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
> obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> +obj-$(CONFIG_ARCH_MXC_IOMUX_PINCTRL) += iomux-pinctrl.o
> +
> obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
> obj-$(CONFIG_MXC_PWM) += pwm.o
> obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
> diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
> index 9aa6f3e..e8860d9 100644
> --- a/arch/arm/plat-mxc/devices/Kconfig
> +++ b/arch/arm/plat-mxc/devices/Kconfig
> @@ -1,3 +1,6 @@
> +config IMX_HAVE_PLATFORM_DUART
> + bool
> +
> config IMX_HAVE_PLATFORM_ESDHC
> bool
>
> diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
> index 45aefeb..11e2fcf 100644
> --- a/arch/arm/plat-mxc/devices/Makefile
> +++ b/arch/arm/plat-mxc/devices/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_IMX_HAVE_PLATFORM_DUART) += platform-duart.o
> obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
> obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
> obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
` (10 preceding siblings ...)
2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
@ 2010-11-16 10:15 ` Sascha Hauer
2010-11-16 12:42 ` Shawn Guo
11 siblings, 1 reply; 28+ messages in thread
From: Sascha Hauer @ 2010-11-16 10:15 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
> This patchset adds the initial support of i.MX28, and the target device
> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
Without further looking at the patch I agree with Uwe: The i.MX23/28
are totally different from the other i.MX SoCs and should not be
integrated in current i.MX support. And definitely it should not be
integrated by adding cpu_is_* into each and every function.
Now you have two choices: Add the code to plat-stmp3xxx (for the
interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
add a new mach-mxs like you did in the Freescale Kernel.
I'm not sure which choice of these two is best. It would be good to get
some other opinions from people who already had the situation that a
vendor got sold and we get the same old metal with new names.
BTW the imx-single-kernel branch is a branch to show where things might
or might not go. You should not base your work on this.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
@ 2010-11-16 12:42 ` Shawn Guo
2010-11-16 17:24 ` Uwe Kleine-König
0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-16 12:42 UTC (permalink / raw)
To: linux-arm-kernel
Hi Sascha,
Thanks for the comments. Please see my comments below.
On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Hello Shawn,
>
> On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
>> This patchset adds the initial support of i.MX28, and the target device
>> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
>> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
>
> Without further looking at the patch I agree with Uwe: The i.MX23/28
> are totally different from the other i.MX SoCs and should not be
> integrated in current i.MX support. And definitely it should not be
> integrated by adding cpu_is_* into each and every function.
>
cpu_is_* is not being added into each and every function. Uwe had this
comment on only two files, arch/arm/plat-mxc/gpio.c and
arch/arm/plat-mxc/time.c. As there are big percentage of
infrastructural common codes that are IP block independent, I though
it's good to use the same file. But since you are not in this
position, I would propose another option. Like what I'm doing with
iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
based time implementation.
The philosophy behind this is we treat arch/arm/plat-mxc as the
Freescale IP block pool. The driver in this folder is IP block
oriented other than SoC oriented. And SoC is actually a collection of
IP blocks. MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
AVIC/TZIC. Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
avic.c/tzic.c in. The only thing we need to deal with is picking up
the file name to stand for the IP block.
> Now you have two choices: Add the code to plat-stmp3xxx (for the
> interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
> add a new mach-mxs like you did in the Freescale Kernel.
> I'm not sure which choice of these two is best. It would be good to get
> some other opinions from people who already had the situation that a
> vendor got sold and we get the same old metal with new names.
>
Yes, MX23/28 are based on former Sigmatel SoCs. The imx-single-kernel
demonstrates the possibility of single image for different SoCs from
same vendor. My patchset somehow adds the the possibility for SoCs
even from different vendors, even though I'm unsure if single image
for SoCs from different vendor is something ARM Kernel will possibly
go in the future?
The plat-stmp3xxx is not an option for me because of the Freescale
marketing concern. For the choice of what Freescale Kernel is doing,
there is no mach-mxs. Instead, there are arch/arm/plat-mxs,
arch/arm/mach-mx23 and arch/arm/mach-mx28. Going this way, MX23/28
will be totally separated from i.MX family, though their name tells
the relationship with i.MX family. Also, Freescale is merging the
Sigmatel IP pool into i.MX one and will only maintain the same pool.
In another words, Sigmatel IP block are getting consolidated with i.MX
ones. You can still say MX28 are former Sigmatel based, but it gets
i.MX IP blocks, FEC(ENET), FlexCAN integrated. If MX28 is not so
typical, MX50 can be the one. It primarily derives from MX51/MX53 and
will go into plat-mxc and mach-mx5 in common understanding, but it
gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
GPMI, DCP, APHB DMA, and so on. SoC is merging these two families
into one. It makes no sense for SW to keeps them separated.
Can you please think about the IP oriented way I mentioned above to
see if there is any problem that stops us going? Also do you want to
eventually include MX23/28 into imx-single-kernel image? If you do,
don't you think my proposal will make it a little bit easier?
> BTW the imx-single-kernel branch is a branch to show where things might
> or might not go. You should not base your work on this.
>
> Sascha
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 ? ?|
> Amtsgericht Hildesheim, HRA 2686 ? ? ? ? ? | Fax: ? +49-5121-206917-5555 |
>
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
2010-11-16 12:42 ` Shawn Guo
@ 2010-11-16 17:24 ` Uwe Kleine-König
2010-11-17 1:28 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-16 17:24 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Tue, Nov 16, 2010 at 08:42:29PM +0800, Shawn Guo wrote:
> On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > Hello Shawn,
> >
> > On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
> >> This patchset adds the initial support of i.MX28, and the target device
> >> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
> >> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
> >
> > Without further looking at the patch I agree with Uwe: The i.MX23/28
> > are totally different from the other i.MX SoCs and should not be
> > integrated in current i.MX support. And definitely it should not be
> > integrated by adding cpu_is_* into each and every function.
> >
> cpu_is_* is not being added into each and every function. Uwe had this
> comment on only two files, arch/arm/plat-mxc/gpio.c and
I consider the irq handling very ugly, but I didn't feel like repeating
the same argument gives much value. (And OK, the irq handling was ugly
already before, that's on my plate to evaluate.) I didn't recheck where
I thought the runtime checks were non-optimal, but seeing to much of
them makes me feel that this is the wrong approach. This is more a
subjective thing and for that it's independant if there are one, two or
five instances.
> arch/arm/plat-mxc/time.c. As there are big percentage of
> infrastructural common codes that are IP block independent, I though
> it's good to use the same file. But since you are not in this
> position, I would propose another option. Like what I'm doing with
> iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
> arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
> based time implementation.
>
> The philosophy behind this is we treat arch/arm/plat-mxc as the
> Freescale IP block pool. The driver in this folder is IP block
> oriented other than SoC oriented. And SoC is actually a collection of
> IP blocks. MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
> MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
> AVIC/TZIC. Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
> icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
> avic.c/tzic.c in. The only thing we need to deal with is picking up
> the file name to stand for the IP block.
For me (not having seen mx50) integrating mx28 into mach-imx seems
wrong. Currently they are completely orthogonal for the components that
matter for architecture support (i.e. timer, irq handling, clocks, pin
muxing, power management and to a slightly lesser degree gpio and memory
mapping).
> > Now you have two choices: Add the code to plat-stmp3xxx (for the
> > interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
> > add a new mach-mxs like you did in the Freescale Kernel.
> > I'm not sure which choice of these two is best. It would be good to get
> > some other opinions from people who already had the situation that a
> > vendor got sold and we get the same old metal with new names.
> >
> Yes, MX23/28 are based on former Sigmatel SoCs. The imx-single-kernel
> demonstrates the possibility of single image for different SoCs from
> same vendor. My patchset somehow adds the the possibility for SoCs
> even from different vendors, even though I'm unsure if single image
> for SoCs from different vendor is something ARM Kernel will possibly
> go in the future?
That's one of the goals of Linaro. I'd prefer to get an
"really-all-i.MX" image via this more global approach.
> The plat-stmp3xxx is not an option for me because of the Freescale
> marketing concern. For the choice of what Freescale Kernel is doing,
I prefer technical arguments here. Just because some guys in the
marketing department consider giving similar names to completely
different products *I* don't believe grouping them together in the
source code makes more sense. (It just reinforces my opinion about
marketing guys :-)
> there is no mach-mxs. Instead, there are arch/arm/plat-mxs,
> arch/arm/mach-mx23 and arch/arm/mach-mx28. Going this way, MX23/28
> will be totally separated from i.MX family, though their name tells
Adding mach-mx23, mach-mx28 and plat-mxs is (IMHO) too much. mx23 and
mx28 are similar enough to put both of the two into a single mach
directory. So seeing the naming choices Freescale did for their kernel
mach-mxs looks reasonable to me.
> the relationship with i.MX family. Also, Freescale is merging the
This wouldn't be worse than what we had before I merged mach-mx1 and
mach-mx2 into mach-imx for 2.6.36: mach-mx1, mach-mx2, mach-mx25,
mach-mx3 and mach-mx5.
> Sigmatel IP pool into i.MX one and will only maintain the same pool.
> In another words, Sigmatel IP block are getting consolidated with i.MX
> ones. You can still say MX28 are former Sigmatel based, but it gets
> i.MX IP blocks, FEC(ENET), FlexCAN integrated. If MX28 is not so
This is natural and OK. But these components are no reason to put mx28
into mach-imx. The respective drivers live in drivers/net and
drivers/net/can. So at best they can share the imx_add_device_du_jour
functions. Here I'd suggest to make these functions available for all
ARMs (or even all archs).
> typical, MX50 can be the one. It primarily derives from MX51/MX53 and
> will go into plat-mxc and mach-mx5 in common understanding, but it
Let's discuss that when you come up with mx50 patches :-)
> gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
> GPMI, DCP, APHB DMA, and so on. SoC is merging these two families
> into one. It makes no sense for SW to keeps them separated.
I don't want to separate things artificially that belong together, but I
don't want to put things together that are really seperate, too.
> Can you please think about the IP oriented way I mentioned above to
> see if there is any problem that stops us going? Also do you want to
> eventually include MX23/28 into imx-single-kernel image? If you do,
> don't you think my proposal will make it a little bit easier?
It might be easier, yes, but there are also some other criterias that
matter, like maintainability, efficiency of compiled code etc. And I
think when taking these into account using a different machine directory
is the right choice.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
2010-11-16 17:24 ` Uwe Kleine-König
@ 2010-11-17 1:28 ` Shawn Guo
2010-11-17 6:06 ` Uwe Kleine-König
0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-17 1:28 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/11/17 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Tue, Nov 16, 2010 at 08:42:29PM +0800, Shawn Guo wrote:
>> On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
>> > Hello Shawn,
>> >
>> > On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
>> >> This patchset adds the initial support of i.MX28, and the target device
>> >> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
>> >> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
>> >
>> > Without further looking at the patch I agree with Uwe: The i.MX23/28
>> > are totally different from the other i.MX SoCs and should not be
>> > integrated in current i.MX support. And definitely it should not be
>> > integrated by adding cpu_is_* into each and every function.
>> >
>> cpu_is_* is not being added into each and every function. Uwe had this
>> comment on only two files, arch/arm/plat-mxc/gpio.c and
> I consider the irq handling very ugly, but I didn't feel like repeating
> the same argument gives much value. ?(And OK, the irq handling was ugly
> already before, that's on my plate to evaluate.) ?I didn't recheck where
> I thought the runtime checks were non-optimal, but seeing to much of
> them makes me feel that this is the wrong approach. ?This is more a
> subjective thing and for that it's independant if there are one, two or
> five instances.
>
>> arch/arm/plat-mxc/time.c. As there are big percentage of
>> infrastructural common codes that are IP block independent, I though
>> it's good to use the same file. ?But since you are not in this
>> position, I would propose another option. Like what I'm doing with
>> iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
>> arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
>> based time implementation.
>>
>> The philosophy behind this is we treat arch/arm/plat-mxc as the
>> Freescale IP block pool. ?The driver in this folder is IP block
>> oriented other than SoC oriented. ?And SoC is actually a collection of
>> IP blocks. ?MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
>> MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
>> AVIC/TZIC. ?Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
>> icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
>> avic.c/tzic.c in. ?The only thing we need to deal with is picking up
>> the file name to stand for the IP block.
> For me (not having seen mx50) integrating mx28 into mach-imx seems
> wrong. ?Currently they are completely orthogonal for the components that
> matter for architecture support (i.e. timer, irq handling, clocks, pin
> muxing, power management and to a slightly lesser degree gpio and memory
> mapping).
>
>> > Now you have two choices: Add the code to plat-stmp3xxx (for the
>> > interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
>> > add a new mach-mxs like you did in the Freescale Kernel.
>> > I'm not sure which choice of these two is best. It would be good to get
>> > some other opinions from people who already had the situation that a
>> > vendor got sold and we get the same old metal with new names.
>> >
>> Yes, MX23/28 are based on former Sigmatel SoCs. ?The imx-single-kernel
>> demonstrates the possibility of single image for different SoCs from
>> same vendor. ?My patchset somehow adds the the possibility for SoCs
>> even from different vendors, even though I'm unsure if single image
>> for SoCs from different vendor is something ARM Kernel will possibly
>> go in the future?
> That's one of the goals of Linaro. ?I'd prefer to get an
> "really-all-i.MX" image via this more global approach.
>
>> The plat-stmp3xxx is not an option for me because of the Freescale
>> marketing concern. ?For the choice of what Freescale Kernel is doing,
> I prefer technical arguments here. ?Just because some guys in the
> marketing department consider giving similar names to completely
> different products *I* don't believe grouping them together in the
> source code makes more sense. ?(It just reinforces my opinion about
> marketing guys :-)
>
>> there is no mach-mxs. ?Instead, there are arch/arm/plat-mxs,
>> arch/arm/mach-mx23 and arch/arm/mach-mx28. ?Going this way, MX23/28
>> will be totally separated from i.MX family, though their name tells
> Adding mach-mx23, mach-mx28 and plat-mxs is (IMHO) too much. ?mx23 and
> mx28 are similar enough to put both of the two into a single mach
> directory. ?So seeing the naming choices Freescale did for their kernel
> mach-mxs looks reasonable to me.
>
>> the relationship with i.MX family. ?Also, Freescale is merging the
> This wouldn't be worse than what we had before I merged mach-mx1 and
> mach-mx2 into mach-imx for 2.6.36: mach-mx1, mach-mx2, mach-mx25,
> mach-mx3 and mach-mx5.
>
>> Sigmatel IP pool into i.MX one and will only maintain the same pool.
>> In another words, Sigmatel IP block are getting consolidated with i.MX
>> ones. You can still say MX28 are former Sigmatel based, but it gets
>> i.MX IP blocks, FEC(ENET), FlexCAN integrated. ?If MX28 is not so
> This is natural and OK. ?But these components are no reason to put mx28
> into mach-imx. ?The respective drivers live in drivers/net and
> drivers/net/can. ?So at best they can share the imx_add_device_du_jour
> functions. ?Here I'd suggest to make these functions available for all
> ARMs (or even all archs).
>
>> typical, MX50 can be the one. ?It primarily derives from MX51/MX53 and
>> will go into plat-mxc and mach-mx5 in common understanding, but it
> Let's discuss that when you come up with mx50 patches :-)
>
>> gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
>> GPMI, DCP, APHB DMA, and so on. ?SoC is merging these two families
>> into one. ?It makes no sense for SW to keeps them separated.
> I don't want to separate things artificially that belong together, but I
> don't want to put things together that are really seperate, too.
>
>> Can you please think about the IP oriented way I mentioned above to
>> see if there is any problem that stops us going? ?Also do you want to
>> eventually include MX23/28 into imx-single-kernel image? ?If you do,
>> don't you think my proposal will make it a little bit easier?
> It might be easier, yes, but there are also some other criterias that
> matter, like maintainability, efficiency of compiled code etc. ?And I
> think when taking these into account using a different machine directory
> is the right choice.
>
plat-stmp3xxx is not an option for me. Another reason is it has the
support for mach-stmp37xx. If I change anything in plat-stmp3xxx, I
can not even find a board to test mach-stmp37xx. For me
plat-stmp3xxx, mach-stmp37xx and mach-stmp378x seem out of
maintaining. I do not see they are moving.
So at the end of the day, mach-mxs + plat-mxs becomes the option that
could work for both of us, right? Correct me I misunderstood your
comments.
> Best regards
> Uwe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | Uwe Kleine-K?nig ? ? ? ? ? ?|
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
>
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
2010-11-17 1:28 ` Shawn Guo
@ 2010-11-17 6:06 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-17 6:06 UTC (permalink / raw)
To: linux-arm-kernel
Hi Shawn,
> plat-stmp3xxx is not an option for me. Another reason is it has the
> support for mach-stmp37xx. If I change anything in plat-stmp3xxx, I
> can not even find a board to test mach-stmp37xx. For me
> plat-stmp3xxx, mach-stmp37xx and mach-stmp378x seem out of
> maintaining. I do not see they are moving.
>
> So at the end of the day, mach-mxs + plat-mxs becomes the option that
> could work for both of us, right? Correct me I misunderstood your
> comments.
As long as you don't use more than mach directory there is no need to
populate plat-mxs. Everything can go into mach-mxs.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
2010-11-15 16:36 ` Uwe Kleine-König
@ 2010-11-17 11:17 ` Shawn Guo
2010-11-17 13:44 ` Uwe Kleine-König
0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-17 11:17 UTC (permalink / raw)
To: linux-arm-kernel
2010/11/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
>> +#ifdef CONFIG_ARCH_MX28
>> +int mxc_reset_block(void __iomem *reg_addr)
>> +{
>> + ? ? u32 reg;
>> + ? ? int timeout;
>> +
>> + ? ? /*
>> + ? ? ?* The process of software reset of IP block is done
>> + ? ? ?* in several steps:
>> + ? ? ?*
>> + ? ? ?* 1) clear SFTRST and wait it cleared;
>> + ? ? ?* 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
>> + ? ? ?* 3) clear SFTRST and wait it cleared;
>> + ? ? ?* 4) clear CLKGATE and wait it cleared.
>> + ? ? ?*/
>> +
>> + ? ? /* Clear SFTRST */
>> + ? ? reg = __raw_readl(reg_addr);
>> + ? ? reg &= ~(1 << 31);
>> + ? ? __raw_writel(reg, reg_addr);
>> + ? ? /* Wait SFTRST cleared */
>> + ? ? timeout = 1000;
>> + ? ? do {
>> + ? ? ? ? ? ? mdelay(1);
>> + ? ? ? ? ? ? if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
>> + ? ? ? ? ? ? ? ? ? ? break;
>> + ? ? } while (--timeout > 0);
> Does the mdelay make sence here?
>
i.MX28 Application Processor Reference Manual, Chapter 39.5.10
"Correct Way to Software Reset a Block".
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
2010-11-17 11:17 ` Shawn Guo
@ 2010-11-17 13:44 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-17 13:44 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Nov 17, 2010 at 07:17:39PM +0800, Shawn Guo wrote:
> 2010/11/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
> >> +#ifdef CONFIG_ARCH_MX28
> >> +int mxc_reset_block(void __iomem *reg_addr)
> >> +{
> >> + ? ? u32 reg;
> >> + ? ? int timeout;
> >> +
> >> + ? ? /*
> >> + ? ? ?* The process of software reset of IP block is done
> >> + ? ? ?* in several steps:
> >> + ? ? ?*
> >> + ? ? ?* 1) clear SFTRST and wait it cleared;
> >> + ? ? ?* 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
> >> + ? ? ?* 3) clear SFTRST and wait it cleared;
> >> + ? ? ?* 4) clear CLKGATE and wait it cleared.
> >> + ? ? ?*/
> >> +
> >> + ? ? /* Clear SFTRST */
> >> + ? ? reg = __raw_readl(reg_addr);
> >> + ? ? reg &= ~(1 << 31);
> >> + ? ? __raw_writel(reg, reg_addr);
> >> + ? ? /* Wait SFTRST cleared */
> >> + ? ? timeout = 1000;
> >> + ? ? do {
> >> + ? ? ? ? ? ? mdelay(1);
> >> + ? ? ? ? ? ? if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> >> + ? ? ? ? ? ? ? ? ? ? break;
> >> + ? ? } while (--timeout > 0);
> > Does the mdelay make sence here?
> >
> i.MX28 Application Processor Reference Manual, Chapter 39.5.10
> "Correct Way to Software Reset a Block".
Quoting the chapter you pointed out:
// Prepare for soft-reset by making sure that SFTRST is not currently
// asserted. Also clear CLKGATE so we can wait for its assertion below.
HW_GPMI_CTRL0_CLR(BM_GPMI_CTRL0_SFTRST);
// Wait at least a microsecond for SFTRST to deassert. In actuality, we
// need to wait 3 GPMI clocks, but this is much easier to implement.
musecs = hw_profile_GetMicroseconds();
while (HW_GPMI_CTRL0.B.SFTRST || (hw_profile_GetMicroseconds() - musecs <
DDI_NAND_HAL_GPMI_SOFT_RESET_LATENCY));
[...]
This talks about a microsecond, not a millisecond.
Expecting that most of the time not a whole millisecond is needed, I'd
do something like that:
val = __raw_readl(reset_addr);
val &= ~MX28_MODULERESET_SFTRST;
__raw_writel(val, reset_addr);
/*
* SFTRST needs 3 GPMI clocks to settle, the reference manual
* recommends to wait 1us.
*/
udelay(1);
timeout = 0x400;
while ((__raw_readl(reset_addr) & MX28_MODULERESET_SFTRST) && --timeout)
/* nothing /*;
if (!timeout)
goto error;
That is do a busy read and don't busy wait a millisecond between two
consecutive reads just twiddling thumbs.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2010-11-17 13:44 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
2010-11-15 16:25 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
2010-11-15 16:33 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
2010-11-15 16:36 ` Uwe Kleine-König
2010-11-17 11:17 ` Shawn Guo
2010-11-17 13:44 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
2010-11-15 16:40 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
2010-11-15 16:43 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
2010-11-15 16:46 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
2010-11-15 16:47 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
2010-11-15 16:54 ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
2010-11-15 17:01 ` Uwe Kleine-König
2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
2010-11-16 12:42 ` Shawn Guo
2010-11-16 17:24 ` Uwe Kleine-König
2010-11-17 1:28 ` Shawn Guo
2010-11-17 6:06 ` Uwe Kleine-König
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.